static void create_scc (ScanData *data) { int i; gboolean found = FALSE; gboolean found_bridge = FALSE; ColorData *color_data = NULL; for (i = dyn_array_ptr_size (&loop_stack) - 1; i >= 0; --i) { ScanData *other = dyn_array_ptr_get (&loop_stack, i); found_bridge |= other->is_bridge; if (found_bridge || other == data) break; } #if DUMP_GRAPH printf ("|SCC rooted in %s (%p) has bridge %d\n", safe_name_bridge (data->obj), data->obj, found_bridge); printf ("\tpoints-to-colors: "); for (i = 0; i < dyn_array_ptr_size (&color_merge_array); ++i) printf ("%p ", dyn_array_ptr_get (&color_merge_array, i)); printf ("\n"); printf ("loop stack: "); for (i = 0; i < dyn_array_ptr_size (&loop_stack); ++i) { ScanData *other = dyn_array_ptr_get (&loop_stack, i); printf ("(%d/%d)", other->index, other->low_index); } printf ("\n"); #endif if (found_bridge) { color_data = new_color (TRUE); ++num_colors_with_bridges; } else { color_data = reduce_color (); } while (dyn_array_ptr_size (&loop_stack) > 0) { ScanData *other = dyn_array_ptr_pop (&loop_stack); #if DUMP_GRAPH printf ("\tmember %s (%p) index %d low-index %d color %p state %d\n", safe_name_bridge (other->obj), other->obj, other->index, other->low_index, other->color, other->state); #endif other->color = color_data; switch (other->state) { case FINISHED_ON_STACK: other->state = FINISHED_OFF_STACK; break; case FINISHED_OFF_STACK: break; default: g_error ("Invalid state when building SCC %d", other->state); } if (other->is_bridge) dyn_array_ptr_add (&color_data->bridges, other->obj); if (other == data) { found = TRUE; break; } } g_assert (found); for (i = 0; i < dyn_array_ptr_size (&color_merge_array); ++i) { ColorData *cd = dyn_array_ptr_get (&color_merge_array, i); g_assert (cd->visited); cd->visited = FALSE; } dyn_array_ptr_set_size (&color_merge_array, 0); found_bridge = FALSE; }
Graph* tabu_search(Graph* graph, int tabu_len, int candidates_len, int max_iter, int* colors){ Graph* best = initial_solution(graph); int best_cost = cost(best); int new_best_cost = best_cost - 1; Graph* s = reduce_color(best, new_best_cost); int conflict_c; char** conflict_vt = conflict_vertices(s, &conflict_c); int tabu_pos = 0; tabu_t** tabu_list = (tabu_t**) malloc(sizeof(tabu_t*) * candidates_len * graph->iterator_size); int iter = 0; while (iter < max_iter){ Graph** candidates = (Graph**) malloc(sizeof(Graph*) * candidates_len); if (conflict_c > 0){ for (int i = 0; i < candidates_len; i++){ candidates[i] = generate_candidates(s, conflict_vt, conflict_c, tabu_list, &tabu_pos, new_best_cost); } int conflict_cand_c; Graph* best_candidate = get_best_candidate(candidates, candidates_len, conflict_vt, conflict_c, &conflict_cand_c); if (conflict_c > conflict_cand_c){ free_graph(s); free(conflict_vt); s = best_candidate; conflict_vt = conflict_vertices(s, &conflict_c); } else if (best_candidate != NULL) free_graph(best_candidate); } if (conflict_c == 0){ best_cost = new_best_cost; free_graph(best); best = s; new_best_cost = best_cost - 1; s = reduce_color(best, new_best_cost); free(conflict_vt); conflict_vt = conflict_vertices(s, &conflict_c); } if (tabu_pos > tabu_len) update_tabu_list(tabu_list, &tabu_pos, tabu_len); free(candidates); iter++; } free(conflict_vt); free(tabu_list); if (colors != NULL) *colors = best_cost; return best; }