static int enqueue_next_best_state(diagnostic_problem problem, priority_queue opened, gotcha_node current, const_tv_term_list_list systems) { register unsigned int ix; current->depth += 1; ix = current->depth - 1; while (current->offsets[ix] < systems->arr[ix]->sz) { if (is_consistent(problem, current, systems)) { update_cardinality(problem, current); if (!priority_queue_push(opened, current)) { return 0; } increase_int_counter("pushed"); maximize_int_counter("max", priority_queue_size(opened)); return 1; } current->offsets[ix] += 1; increase_int_counter("inconsistent"); } gotcha_node_free(current); return 1; }
static int enqueue_sibling(diagnostic_problem problem, priority_queue opened, gotcha_node current, const_tv_term_list_list systems) { register unsigned int ix; gotcha_node sibling; if (current->depth == 0) { return 1; } ix = current->depth - 1; if (NULL == (sibling = gotcha_node_copy(current, systems->sz))) { return 0; } while (sibling->offsets[ix] < systems->arr[ix]->sz - 1) { sibling->offsets[ix] += 1; if (is_consistent(problem, sibling, systems)) { update_cardinality(problem, sibling); if (!priority_queue_push(opened, sibling)) { gotcha_node_free(sibling); return 0; } increase_int_counter("pushed"); maximize_int_counter("max", priority_queue_size(opened)); return 1; } increase_int_counter("inconsistent"); } gotcha_node_free(sibling); return 1; }
//Doesn't check/add to hash set //Used for the first level created by geng void _add_graph_to_level(graph_info *new_graph, level *my_level) { unsigned i = new_graph->m - my_level->min_m; priority_queue_push(my_level->queues[i], new_graph); if(priority_queue_num_elems(my_level->queues[i]) > my_level->p) { graph_info *g = priority_queue_pull(my_level->queues[i]); if(g->gcan) hash_set_remove(my_level->sets[i], g); graph_info_destroy(g); } }
END_TEST START_TEST(test_priority_queue_crud){ priority_queue_t* pq; int* v = callocx(N,sizeof(int)); priority_queue_initialize(&pq,int_constructor,int_destructor,int_comparator); int i; for(i=0;i<N;i++){ v[i] = rand(); priority_queue_push(pq,&v[i]); } qsort(v,N,sizeof(int),int_comparator); ck_assert(priority_queue_size(pq)==N); for(i=0; !priority_queue_empty(pq); i++){ ck_assert(*(int*) priority_queue_front(pq) == v[i]); priority_queue_pop(pq); } free(v); priority_queue_delete(&pq); }
int gotcha_diag(diagnostic_problem problem, const_tv_term alpha) { priority_queue opened; gotcha_node initial; dnf_tree consistent_input; tv_term_list_list systems; unsigned int old_diagnoses; int terminate = 0; int result = 1; diagnostic_problem_reset(problem); sort_int_list(alpha->neg); sort_int_list(alpha->pos); start_stopwatch("observation filtering time"); consistent_input = dnf_tree_filter(dnf_tree_copy(problem->u.tv_tdnf_sd.model), alpha); stop_stopwatch("observation filtering time"); systems = new_tv_term_list_list(); get_systems(consistent_input, systems); /* Start the timer. */ start_stopwatch("search time"); opened = priority_queue_new(cmp_nodes, (priority_queue_element_destroy_func_t)gotcha_node_free, (void *)systems->sz); initial = gotcha_node_new(systems->sz); priority_queue_push(opened, initial); increase_int_counter("pushed"); maximize_int_counter("max", 1); while (!terminate && !priority_queue_empty(opened)) { gotcha_node current = priority_queue_pop(opened); candidate_found(current->cardinality); if (is_terminate()) { gotcha_node_free(current); break; } if (current->depth != 0) { /* The root node has no siblings. */ if (!enqueue_sibling(problem, opened, current, systems)) { result = 0; gotcha_node_free(current); break; } } if (is_diagnosis(current, systems)) { tv_term diagnosis = build_term(current, systems); if (NULL == diagnosis) { result = 0; gotcha_node_free(current); break; } old_diagnoses = problem->diagnoses->sz; if (!add_diagnosis_from_tv_term(problem, diagnosis, &terminate, 1)) { result = 0; rfre_tv_term(diagnosis); gotcha_node_free(current); break; } if (cones != NULL && problem->diagnoses->sz - 1 == old_diagnoses) { assert(problem->diagnoses->sz > 0); /* @todo: Fix the termination here. */ expand_cone_exhaustive(cones, alpha, problem->diagnoses->arr[problem->diagnoses->sz - 1]); } rfre_tv_term(diagnosis); gotcha_node_free(current); } else { if (!enqueue_next_best_state(problem, opened, current, systems)) { result = 0; gotcha_node_free(current); break; } } } priority_queue_free(opened); fre_tv_term_list_list(systems); /* Stop the timer. */ stop_stopwatch("search time"); dnf_tree_free(consistent_input); return result; }