int tsp_cuts(network *n, int verbosity, char tsp_prob, int which_cuts, cut_data ***cuts, int *num_cuts, int *alloc_cuts) { edge *edges = n->edges; CCtsp_lpcut_in *tsp_cuts = NULL; int *tsp_edgelist = (int *) malloc(2*n->edgenum*ISIZE); double *tsp_x = (double *) malloc(n->edgenum*DSIZE); int i, cutnum = 0, cuts_added = 0, rval, seed; CCrandstate rstate; CCtsp_cutselect *sel; CCtsp_tighten_info *stats; stats = (CCtsp_tighten_info *) calloc(1, sizeof(CCtsp_tighten_info)); sel = (CCtsp_cutselect *) calloc(1, sizeof(CCtsp_cutselect)); if (tsp_prob){ sel->connect = 1; if (which_cuts & SUBTOUR){ sel->segments = 1; sel->exactsubtour = 1; } if (which_cuts & BLOSSOM){ sel->fastblossom = 1; sel->ghfastblossom = 1; sel->exactblossom = 0; } if (which_cuts & COMB){ sel->blockcombs = 1; sel->growcombs = 0; sel->prclique = 0; } }else{ if (which_cuts & BLOSSOM){ sel->fastblossom = 1; sel->ghfastblossom = 1; sel->exactblossom = 1; } } for (i = 0; i < n->edgenum; i++, edges++){ tsp_edgelist[i << 1] = edges->v0; tsp_edgelist[(i << 1) + 1] = edges->v1; tsp_x[i] = edges->weight; } if (sel->connect){ rval = CCtsp_connect_cuts(&tsp_cuts, &cutnum, n->vertnum, n->edgenum, tsp_edgelist, tsp_x); if (rval) { fprintf(stderr, "CCtsp_connect_cuts failed\n"); printf("CCtsp_connect_cuts failed\n"); rval = 1; } if (verbosity > 3) printf("Found %2d connect cuts\n", cutnum); if (!rval && cutnum > 0){ cuts_added += add_tsp_cuts(&tsp_cuts, &cutnum, n->vertnum, tsp_prob, cuts, num_cuts, alloc_cuts); if (cuts_added){ if (verbosity > 3) printf("%i connect cuts added\n", cuts_added); goto CLEANUP; } } } if (sel->segments){ rval = CCtsp_segment_cuts(&tsp_cuts, &cutnum, n->vertnum, n->edgenum, tsp_edgelist, tsp_x); if (rval) { fprintf(stderr, "CCtsp_segment_cuts failed\n"); printf("CCtsp_segment_cuts failed\n"); rval = 1; } if (verbosity > 3) printf("Found %2d segment cuts\n", cutnum); if (!rval && cutnum > 0){ cuts_added += add_tsp_cuts(&tsp_cuts, &cutnum, n->vertnum, tsp_prob, cuts, num_cuts, alloc_cuts); if (cuts_added){ if (verbosity > 3) printf("%i segment cuts added\n", cuts_added); goto CLEANUP; } } } if (sel->fastblossom){ rval = CCtsp_fastblossom(&tsp_cuts, &cutnum, n->vertnum, n->edgenum, tsp_edgelist, tsp_x); if (rval) { fprintf(stderr, "CCtsp_fastblossom failed\n"); printf("CCtsp_fastblossom failed\n"); rval = 1; } if (verbosity > 3) printf("Found %2d fastblossom cuts\n", cutnum); if (!rval && cutnum > 0){ cuts_added += add_tsp_cuts(&tsp_cuts, &cutnum, n->vertnum, tsp_prob, cuts, num_cuts, alloc_cuts); if (cuts_added){ if (verbosity > 3) printf("%i fastblossom cuts added\n", cuts_added); goto CLEANUP; } } } if (sel->ghfastblossom){ rval = CCtsp_ghfastblossom(&tsp_cuts, &cutnum, n->vertnum, n->edgenum, tsp_edgelist, tsp_x); if (rval) { fprintf(stderr, "CCtsp_ghfastblossom failed\n"); printf("CCtsp_ghfastblossom failed\n"); rval = 1; } if (verbosity > 3) printf("Found %2d ghfastblossom cuts\n", cutnum); if (!rval && cutnum > 0){ cuts_added += add_tsp_cuts(&tsp_cuts, &cutnum, n->vertnum, tsp_prob, cuts, num_cuts, alloc_cuts); if (cuts_added){ if (verbosity > 3) printf("%i ghfastblossom cuts added\n", cuts_added); goto CLEANUP; } } } if (sel->blockcombs){ rval = CCtsp_block_combs(&tsp_cuts, &cutnum, n->vertnum, n->edgenum, tsp_edgelist, tsp_x, TRUE); if (rval) { fprintf(stderr, "CCtsp_block_combs failed\n"); printf("CCtsp_block_combs failed\n"); rval = 1; } if (verbosity > 3) printf("Found %2d block combs\n", cutnum); if (!rval && cutnum > 0){ cuts_added += add_tsp_cuts(&tsp_cuts, &cutnum, n->vertnum, tsp_prob, cuts, num_cuts, alloc_cuts); if (cuts_added){ if (verbosity > 3) printf("%i block combs added\n", cuts_added); goto CLEANUP; } } } if (sel->growcombs){ rval = CCtsp_edge_comb_grower(&tsp_cuts, &cutnum, n->vertnum, n->edgenum, tsp_edgelist, tsp_x, stats); if (rval) { fprintf(stderr, "CCtsp_edge_comb_grower failed\n"); printf("CCtsp_edge_comb_grower failed\n"); rval = 1; } if (verbosity > 3) printf("Found %2d grown combs\n", cutnum); if (!rval && cutnum > 0){ cuts_added += add_tsp_cuts(&tsp_cuts, &cutnum, n->vertnum, tsp_prob, cuts, num_cuts, alloc_cuts); if (cuts_added){ if (verbosity > 3) printf("%i grown combs added\n", cuts_added); goto CLEANUP; } } } if (sel->prclique){ rval = CCtsp_pr_cliquetree(&tsp_cuts, &cutnum, n->vertnum, n->edgenum, tsp_edgelist, tsp_x, stats); if (rval) { fprintf(stderr, "CCtsp_pr_cliquetree failed\n"); printf("CCtsp_pr_cliquetree failed\n"); rval = 1; } if (verbosity > 3) printf("Found %2d PR cliquetrees\n", cutnum); if (!rval && cutnum > 0){ cuts_added += add_tsp_cuts(&tsp_cuts, &cutnum, n->vertnum, tsp_prob, cuts, num_cuts, alloc_cuts); if (cuts_added){ if (verbosity > 3) printf("%i PR cliquetrees added\n", cuts_added); goto CLEANUP; } } } if (sel->exactsubtour){ rval = CCtsp_exact_subtours(&tsp_cuts, &cutnum, n->vertnum, n->edgenum, tsp_edgelist, tsp_x); if (rval) { fprintf(stderr, "CCtsp_exact_subtours failed\n"); printf("CCtsp_exact_subtours failed\n"); rval = 1; } if (verbosity > 3) printf("Found %2d exact subtours\n", cutnum); if (!rval && cutnum > 0){ cuts_added += add_tsp_cuts(&tsp_cuts, &cutnum, n->vertnum, tsp_prob, cuts, num_cuts, alloc_cuts); if (cuts_added){ if (verbosity > 3) printf("%i exactsubtours added\n", cuts_added); goto CLEANUP; } } } if (sel->exactblossom){ seed = (int) CCutil_real_zeit (); CCutil_sprand(seed, &rstate); rval = CCtsp_exactblossom(&tsp_cuts, &cutnum, n->vertnum, n->edgenum, tsp_edgelist, tsp_x, &rstate); if (rval) { fprintf(stderr, "CCtsp_exactblossom failed\n"); printf("CCtsp_exactblossom failed\n"); rval = 1; } if (verbosity > 3) printf("Found %2d exactblossoms\n", cutnum); if (!rval && cutnum > 0){ cuts_added += add_tsp_cuts(&tsp_cuts, &cutnum, n->vertnum, tsp_prob, cuts, num_cuts, alloc_cuts); if (cuts_added){ if (verbosity > 3) printf("%i exact blossoms added\n", cuts_added); goto CLEANUP; } } } CLEANUP: FREE(stats); FREE(tsp_edgelist); FREE(tsp_x); return(cuts_added); }
int user_find_cuts(void *user, int varnum, int iter_num, int level, int index, double objval, int *indices, double *values, double ub, double etol, int *num_cuts, int *alloc_cuts, cut_data ***cuts) { vrp_cg_problem *vrp = (vrp_cg_problem *)user; int vertnum = vrp->vertnum; network *n; vertex *verts = NULL; int *compdemands = NULL, *compnodes = NULL, *compnodes_copy = NULL; int *compmembers = NULL, comp_num = 0; /*__BEGIN_EXPERIMENTAL_SECTION__*/ int *compdemands_copy = NULL; double *compcuts_copy = NULL, *compdensity = NULL, density; /*___END_EXPERIMENTAL_SECTION___*/ double node_cut, max_node_cut, *compcuts = NULL; int rcnt, cur_bins = 0, k; char **coef_list; int i, max_node; double cur_slack = 0.0; int capacity = vrp->capacity; int cut_size = (vertnum >> DELETE_POWER) + 1; cut_data *new_cut = NULL; elist *cur_edge = NULL; int which_connected_routine = vrp->par.which_connected_routine; int *ref = vrp->ref; double *cut_val = vrp->cut_val; char *in_set = vrp->in_set; char *cut_list = vrp->cut_list; elist *cur_edge1 = NULL, *cur_edge2 = NULL; /*__BEGIN_EXPERIMENTAL_SECTION__*/ #ifdef COMPILE_OUR_DECOMP edge *edge_pt; #endif /*___END_EXPERIMENTAL_SECTION___*/ int node1 = 0, node2 = 0; int *demand = vrp->demand; int *new_demand = vrp->new_demand; int total_demand = demand[0]; int num_routes = vrp->numroutes, num_trials; int triangle_cuts = 0; char *coef; if (iter_num == 1) SRANDOM(1); /*__BEGIN_EXPERIMENTAL_SECTION__*/ #if 0 CCutil_sprand(1, &rand_state); #endif /*___END_EXPERIMENTAL_SECTION___*/ /*__BEGIN_EXPERIMENTAL_SECTION__*/ #if 0 if (vrp->dg_id && vrp->par.verbosity > 3){ sprintf(name, "support graph"); display_support_graph(vrp->dg_id, (p->cur_sol.xindex == 0 && p->cur_sol.xiter_num == 1) ? TRUE: FALSE, name, varnum, xind, xval, etol, CTOI_WAIT_FOR_CLICK_AND_REPORT); } #endif /*___END_EXPERIMENTAL_SECTION___*/ /* This creates a fractional graph representing the LP solution */ n = createnet(indices, values, varnum, etol, vrp->edges, demand, vertnum); if (n->is_integral){ /* if the network is integral, check for connectivity */ check_connectivity(n, etol, capacity, num_routes, cuts, num_cuts, alloc_cuts); free_net(n); return(USER_SUCCESS); } #ifdef DO_TSP_CUTS if (vrp->par.which_tsp_cuts && vrp->par.tsp_prob){ tsp_cuts(n, vrp->par.verbosity, vrp->par.tsp_prob, vrp->par.which_tsp_cuts, cuts, num_cuts, alloc_cuts); free_net(n); return(USER_SUCCESS); } #endif /*__BEGIN_EXPERIMENTAL_SECTION__*/ if (!vrp->par.always_do_mincut){/*user_par.always_do_mincut indicates whether we should just always do the min_cut routine or whether we should also try this routine*/ /*___END_EXPERIMENTAL_SECTION___*/ /*UNCOMMENT FOR PRODUCTION CODE*/ #if 0 { #endif verts = n->verts; if (which_connected_routine == BOTH) which_connected_routine = CONNECTED; new_cut = (cut_data *) calloc(1, sizeof(cut_data)); new_cut->size = cut_size; compnodes_copy = (int *) malloc((vertnum + 1) * sizeof(int)); compmembers = (int *) malloc((vertnum + 1) * sizeof(int)); /*__BEGIN_EXPERIMENTAL_SECTION__*/ compdemands_copy = (int *) calloc(vertnum + 1, sizeof(int)); compcuts_copy = (double *) calloc(vertnum + 1, sizeof(double)); #ifdef COMPILE_OUR_DECOMP compdensity = vrp->par.do_our_decomp ? (double *) calloc(vertnum+1, sizeof(double)) : NULL; #endif /*___END_EXPERIMENTAL_SECTION___*/ do{ compnodes = (int *) calloc(vertnum + 1, sizeof(int)); compdemands = (int *) calloc(vertnum + 1, sizeof(int)); compcuts = (double *) calloc(vertnum + 1, sizeof(double)); /*------------------------------------------------------------------*\ * Get the connected components of the solution graph without the * depot and see if the number of components is more than one \*------------------------------------------------------------------*/ rcnt = (which_connected_routine == BICONNECTED ? biconnected(n, compnodes, compdemands, compcuts) : connected(n, compnodes, compdemands, compmembers, /*__BEGIN_EXPERIMENTAL_SECTION__*/ compcuts, compdensity)); /*___END_EXPERIMENTAL_SECTION___*/ /*UNCOMMENT FOR PRODUCTION CODE*/ #if 0 compcuts, NULL)); #endif /* copy the arrays as they will be needed later */ if (!which_connected_routine && /*__BEGIN_EXPERIMENTAL_SECTION__*/ (vrp->par.do_greedy || vrp->par.do_our_decomp)){ /*___END_EXPERIMENTAL_SECTION___*/ /*UNCOMMENT FOR PRODUCTION CODE*/ #if 0 vrp->par.do_greedy){ #endif compnodes_copy = (int *) memcpy((char *)compnodes_copy, (char*)compnodes, (vertnum+1)*sizeof(int)); /*__BEGIN_EXPERIMENTAL_SECTION__*/ compdemands_copy = (int *) memcpy((char *)compdemands_copy, (char *)compdemands, (vertnum+1)*ISIZE); compcuts_copy = (double *) memcpy((char *)compcuts_copy, (char *)compcuts, (vertnum+1)*DSIZE); /*___END_EXPERIMENTAL_SECTION___*/ n->compnodes = compnodes_copy; comp_num = rcnt; } if (rcnt > 1){ /*---------------------------------------------------------------*\ * If the number of components is more then one, then check each * component to see if it violates a capacity constraint \*---------------------------------------------------------------*/ coef_list = (char **) calloc(rcnt, sizeof(char *)); coef_list[0] = (char *) calloc(rcnt*cut_size, sizeof(char)); for(i = 1; i<rcnt; i++) coef_list[i] = coef_list[0]+i*cut_size; for(i = 1; i < vertnum; i++) (coef_list[(verts[i].comp)-1][i >> DELETE_POWER]) |= (1 << (i & DELETE_AND)); for (i = 0; i < rcnt; i++){ if (compnodes[i+1] < 2) continue; /*check ith component to see if it violates a constraint*/ if (vrp->par.which_connected_routine == BOTH && which_connected_routine == BICONNECTED && compcuts[i+1]==0) continue; if (compcuts[i+1] < 2*BINS(compdemands[i+1], capacity)-etol){ /*the constraint is violated so impose it*/ new_cut->coef = (char *) (coef_list[i]); new_cut->type = (compnodes[i+1] < vertnum/2 ? SUBTOUR_ELIM_SIDE:SUBTOUR_ELIM_ACROSS); new_cut->rhs = (new_cut->type == SUBTOUR_ELIM_SIDE ? RHS(compnodes[i+1],compdemands[i+1], capacity): 2*BINS(compdemands[i+1], capacity)); cg_send_cut(new_cut, num_cuts, alloc_cuts, cuts); } else{/*if the constraint is not violated, then try generating a violated constraint by deleting customers that don't change the number of trucks required by the customers in the component but decrease the value of the cut*/ cur_bins = BINS(compdemands[i+1], capacity);/*the current number of trucks required*/ /*current slack in the constraint*/ cur_slack = (compcuts[i+1] - 2*cur_bins); while (compnodes[i+1]){/*while there are still nodes in the component*/ for (max_node = 0, max_node_cut = 0, k = 1; k < vertnum; k++){ if (verts[k].comp == i+1){ if (BINS(compdemands[i+1]-verts[k].demand, capacity) == cur_bins){ /*if the number of trucks doesn't decrease upon deleting this customer*/ for (node_cut = 0, cur_edge = verts[k].first; cur_edge; cur_edge = cur_edge->next_edge){ node_cut += (cur_edge->other_end ? -cur_edge->data->weight : cur_edge->data->weight); } if (node_cut > max_node_cut){/*check whether the value of the cut decrease is the best seen so far*/ max_node = k; max_node_cut = node_cut; } } } } if (!max_node){ break; } /*delete the customer that exhibited the greatest decrease in cut value*/ compnodes[i+1]--; compdemands[i+1] -= verts[max_node].demand; compcuts[i+1] -= max_node_cut; cur_slack -= max_node_cut; verts[max_node].comp = 0; coef_list[i][max_node >> DELETE_POWER] ^= (1 << (max_node & DELETE_AND)); if (cur_slack < 0){/*if the cut is now violated, impose it*/ new_cut->coef = (char *) (coef_list[i]); new_cut->type = (compnodes[i+1] < vertnum/2 ? SUBTOUR_ELIM_SIDE:SUBTOUR_ELIM_ACROSS); new_cut->size = cut_size; new_cut->rhs = (new_cut->type == SUBTOUR_ELIM_SIDE ? RHS(compnodes[i+1], compdemands[i+1], capacity): 2*cur_bins); cg_send_cut(new_cut, num_cuts, alloc_cuts, cuts); break; } } } } FREE(coef_list[0]); FREE(coef_list); } which_connected_routine++; FREE(compnodes); FREE(compdemands); FREE(compcuts); }while((!(*num_cuts) && vrp->par.which_connected_routine == BOTH)
int main (int ac, char **av) { int k, ncount; double val, best; double startzeit; int tempcount, *templist; int *incycle = (int *) NULL, *outcycle = (int *) NULL; CCdatagroup dat; int rval = 0; CCrandstate rstate; int allow_dups; int use_gridsize; CCutil_printlabel (); CCutil_init_datagroup (&dat); rval = print_command (ac, av); CCcheck_rval (rval, "print_command failed"); seed = (int) CCutil_real_zeit (); if (parseargs (ac, av)) return 1; CCutil_sprand (seed, &rstate); printf ("Chained Lin-Kernighan with seed %d\n", seed); fflush (stdout); if ((!nnodes_want && !nodefile) || (tsplib_in && !nodefile)) { usage (av[0]); return 1; } startzeit = CCutil_zeit (); if (tsplib_in) { if (CCutil_gettsplib (nodefile, &ncount, &dat)) { fprintf (stderr, "could not read the TSPLIB file\n"); rval = 1; goto CLEANUP; } CCutil_dat_getnorm (&dat, &norm); } else { ncount = nnodes_want; if (gridsize < 0) { use_gridsize = -gridsize; allow_dups = 0; } else if (gridsize > 0) { use_gridsize = gridsize; allow_dups = 1; } else { use_gridsize = nnodes_want; allow_dups = 0; } if (CCutil_getdata (nodefile, binary_in, norm, &ncount, &dat, use_gridsize, allow_dups, &rstate)) { rval = 1; goto CLEANUP; } } if (in_repeater == -1) in_repeater = ncount; incycle = CC_SAFE_MALLOC (ncount, int); if (!incycle) { rval = 1; goto CLEANUP; } if (cycfname) { if (CCutil_getcycle (ncount, cycfname, incycle, binary_edges)) { fprintf (stderr, "CCutil_getcycle failed\n"); rval = 1; goto CLEANUP; } } else if (edgecycfname) { if (CCutil_getcycle_edgelist (ncount, edgecycfname, incycle, binary_edges)) { fprintf (stderr, "CCutil_getcycle_edgelist failed\n"); rval = 1; goto CLEANUP; } } if (goodfname) { int *templen = (int *) NULL; if (CCutil_getedgelist (ncount, goodfname, &tempcount, &templist, &templen, binary_edges)) { rval = 1; goto CLEANUP; } if (templen) CC_FREE (templen, int); printf ("Read good-edge file: %d edges\n", tempcount); fflush (stdout); } else if (edgegenfname) { CCedgegengroup plan; if (CCedgegen_read (edgegenfname, &plan)) { fprintf (stderr, "CCedgegen_read failed\n"); rval = 1; goto CLEANUP; } if (CCedgegen_edges (&plan, ncount, &dat, (double *) NULL, &tempcount, &templist, 0, &rstate)) { fprintf (stderr, "CCedgegen_edges failed\n"); rval = 1; goto CLEANUP; } } if ((norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) { CCkdtree localkt; double kzeit = CCutil_zeit (); if ((!goodfname && !edgegenfname) || (!cycfname && !edgecycfname)) { if (CCkdtree_build (&localkt, ncount, &dat, (double *) NULL, &rstate)) { fprintf (stderr, "CCkdtree_build failed\n"); rval = 1; goto CLEANUP; } printf ("Time to build kdtree: %.2f\n", CCutil_zeit () - kzeit); fflush (stdout); if (!goodfname && !edgegenfname) { kzeit = CCutil_zeit (); if (nearnum) { if (CCkdtree_k_nearest (&localkt, ncount, nearnum, &dat, (double *) NULL, 1, &tempcount, &templist, run_silently, &rstate)) { fprintf (stderr, "CCkdtree_k_nearest failed\n"); rval = 1; goto CLEANUP; } if (!run_silently) { printf ("Time to find %d-nearest: %.2f\n", nearnum, CCutil_zeit () - kzeit); fflush (stdout); } } else { if (CCkdtree_quadrant_k_nearest (&localkt, ncount, quadtry, &dat, (double *) NULL, 1, &tempcount, &templist, run_silently, &rstate)) { fprintf (stderr, "CCkdtree-quad nearest code failed\n"); rval = 1; goto CLEANUP; } if (!run_silently) { printf ("Time to find quad %d-nearest: %.2f\n", quadtry, CCutil_zeit () - kzeit); fflush (stdout); } } } if (!cycfname && !edgecycfname) { kzeit = CCutil_zeit (); if (tour_type == LK_GREEDY) { if (CCkdtree_greedy_tour (&localkt, ncount, &dat, incycle, &val, run_silently, &rstate)) { fprintf (stderr, "CCkdtree greedy-tour failed\n"); rval = 1; goto CLEANUP; } } else if (tour_type == LK_QBORUVKA) { if (CCkdtree_qboruvka_tour (&localkt, ncount, &dat, incycle, &val, &rstate)) { fprintf (stderr, "CCkdtree qboruvka-tour failed\n"); rval = 1; goto CLEANUP; } } else if (tour_type == LK_BORUVKA) { if (CCkdtree_boruvka_tour (&localkt, ncount, &dat, incycle, &val, &rstate)) { fprintf (stderr, "CCkdtree boruvka-tour failed\n"); rval = 1; goto CLEANUP; } } else if (tour_type == LK_RANDOM) { randcycle (ncount, incycle, &rstate); } else { if (CCkdtree_nearest_neighbor_tour (&localkt, ncount, CCutil_lprand (&rstate) % ncount, &dat, incycle, &val, &rstate)) { fprintf (stderr, "CCkdtree NN-tour failed\n"); rval = 1; goto CLEANUP; } } if (!run_silently) { printf ("Time to grow tour: %.2f\n", CCutil_zeit () - kzeit); fflush (stdout); } } CCkdtree_free (&localkt); } } else if ((norm & CC_NORM_BITS) == CC_X_NORM_TYPE) { double xzeit = CCutil_zeit (); if (!goodfname && !edgegenfname) { if (nearnum) { if (CCedgegen_x_k_nearest (ncount, nearnum, &dat, (double *) NULL, 1, &tempcount, &templist, run_silently)) { fprintf (stderr, "CCedgegen_x_k_nearest failed\n"); rval = 1; goto CLEANUP; } if (!run_silently) { printf ("Time to find %d-nearest: %.2f\n", nearnum, CCutil_zeit () - xzeit); fflush (stdout); } } else { if (CCedgegen_x_quadrant_k_nearest (ncount, quadtry, &dat, (double *) NULL, 1, &tempcount, &templist, run_silently)) { fprintf (stderr, "x-quad nearest code failed\n"); rval = 1; goto CLEANUP; } if (!run_silently) { printf ("Time to find quad %d-nearest: %.2f\n", quadtry, CCutil_zeit () - xzeit); fflush (stdout); } } } if (!cycfname && !edgecycfname) { xzeit = CCutil_zeit (); if (tour_type == LK_GREEDY) { if (CCedgegen_x_greedy_tour (ncount, &dat, incycle, &val, tempcount, templist, run_silently)) { fprintf (stderr, "CCedgegen_x_greedy_tour failed\n"); rval = 1; goto CLEANUP; } } else if (tour_type == LK_QBORUVKA) { if (CCedgegen_x_qboruvka_tour (ncount, &dat, incycle, &val, tempcount, templist, run_silently)) { fprintf (stderr, "CCedgegen_x_qboruvka_tour failed\n"); rval = 1; goto CLEANUP; } } else if (tour_type == LK_RANDOM) { randcycle (ncount, incycle, &rstate); } else { if (CCedgegen_x_nearest_neighbor_tour (ncount, CCutil_lprand (&rstate) % ncount, &dat, incycle, &val)) { fprintf (stderr, "CCedgegen_x_nearest_neighbor_tour failed\n"); rval = 1; goto CLEANUP; } } if (!run_silently) { printf ("Time to grow tour: %.2f\n", CCutil_zeit () - xzeit); fflush (stdout); } } } else { double jzeit = CCutil_zeit (); if (!goodfname && !edgegenfname) { if (!nearnum) nearnum = 4 * quadtry; if (CCedgegen_junk_k_nearest (ncount, nearnum, &dat, (double *) NULL, 1, &tempcount, &templist, run_silently)) { fprintf (stderr, "CCedgegen_junk_k_nearest failed\n"); rval = 1; goto CLEANUP; } if (!run_silently) { printf ("Time to find %d nearest: %.2f\n", nearnum, CCutil_zeit () - jzeit); fflush (stdout); } } if (!cycfname && !edgecycfname) { jzeit = CCutil_zeit(); if (tour_type == LK_GREEDY) { if (CCedgegen_junk_greedy_tour (ncount, &dat, incycle, &val, tempcount, templist, run_silently)) { fprintf (stderr, "CCedgegen_junk_greedy_tour failed\n"); rval = 1; goto CLEANUP; } } else if (tour_type == LK_QBORUVKA) { if (CCedgegen_junk_qboruvka_tour (ncount, &dat, incycle, &val, tempcount, templist, run_silently)) { fprintf (stderr, "CCedgegen_junk_qboruvka_tour failed\n"); rval = 1; goto CLEANUP; } } else if (tour_type == LK_RANDOM) { randcycle (ncount, incycle, &rstate); } else { if (CCedgegen_junk_nearest_neighbor_tour (ncount, CCutil_lprand (&rstate) % ncount, &dat, incycle, &val, run_silently)) { fprintf (stderr, "CCedgegen_junk_nearest_neighbor_tour failed\n"); rval = 1; goto CLEANUP; } } if (!run_silently) { printf ("Time to grow tour: %.2f\n", CCutil_zeit () - jzeit); fflush (stdout); } } } outcycle = CC_SAFE_MALLOC (ncount, int); if (!outcycle) { rval = 1; goto CLEANUP; } if (number_runs) { k = 0; best = BIGDOUBLE; do { printf ("\nStarting Run %d\n", k); if (CClinkern_tour (ncount, &dat, tempcount, templist, 100000000, in_repeater, incycle, outcycle, &val, run_silently, time_bound, length_bound, (char *) NULL, kick_type, &rstate)) { fprintf (stderr, "CClinkern_tour failed\n"); rval = 1; goto CLEANUP; } if (val < best) { best = val; if (saveit_final) { if (CCutil_writecycle_edgelist (ncount, saveit_final, outcycle, &dat, binary_edges)) { fprintf (stderr, "could not write the cycle\n"); rval = 1; goto CLEANUP; } } } } while (++k < number_runs); printf ("Overall Best Cycle: %.0f\n", val); fflush (stdout); } else { double lkzeit = CCutil_zeit (); int attempt = 1; do { if (CClinkern_tour (ncount, &dat, tempcount, templist, 10000000, in_repeater, incycle, outcycle, &val, run_silently, time_bound, length_bound, saveit_name, kick_type, &rstate)) { fprintf (stderr, "CClinkern_tour failed\n"); rval = 1; goto CLEANUP; } if (length_bound != -1 && val > length_bound) { printf ("Cycle of value %.0f - did not reach %.0f\n", val, length_bound); printf ("Try again. Number of attempts: %d\n", ++attempt); } } while (length_bound != -1 && val > length_bound); if (saveit_final) { if (CCutil_writecycle_edgelist (ncount, saveit_final, outcycle, &dat, binary_edges)) { fprintf (stderr, "could not write the cycle\n"); rval = 1; goto CLEANUP; } } if (run_silently) printf ("Lin-Kernighan Running Time: %.2f\n", CCutil_zeit () - lkzeit); printf ("Final Cycle: %.0f\n", val); fflush (stdout); } printf ("Total Running Time: %.2f\n", CCutil_zeit () - startzeit); fflush (stdout); CLEANUP: #ifndef BIG_PROBLEM CC_IFFREE (templist, int); #endif CC_IFFREE (incycle, int); CC_IFFREE (outcycle, int); CCutil_freedatagroup (&dat); return rval; }
int main (int ac, char **av) { double val, szeit; CCkdtree kt; CCdatagroup dat; double *wcoord = (double *) NULL; int ncount; int *ttour = (int *) NULL, *tour2 = (int *) NULL; int rval = 0; int ecount; int *elist = (int *) NULL; CCrandstate rstate; int use_gridsize, allow_dups; CCutil_init_datagroup (&dat); seed = (int) CCutil_real_zeit (); if (parseargs (ac, av)) return 1; CCutil_sprand (seed, &rstate); if ((!nnodes_want && !nodefile) || (tsplib_in && !nodefile)) { usage (av[0]); return 1; } if (tsplib_in) { if (CCutil_gettsplib (nodefile, &ncount, &dat)) { fprintf (stderr, "could not read the TSPLIB file\n"); rval = 1; goto CLEANUP; } CCutil_dat_getnorm (&dat, &norm); } else { ncount = nnodes_want; if (gridsize < 0) { use_gridsize = -gridsize; allow_dups = 0; } else if (gridsize > 0) { use_gridsize = gridsize; allow_dups = 1; } else { use_gridsize = nnodes_want; allow_dups = 0; } if (CCutil_getdata (nodefile, binary_in, norm, &ncount, &dat, use_gridsize, allow_dups, &rstate)) { rval = 1; goto CLEANUP; } } if ((norm & CC_NORM_BITS) != CC_KD_NORM_TYPE) { fprintf (stderr, "Cannot run CCkdtree with norm %d\n", norm); rval = 1; goto CLEANUP; } if (usenodeweights) { if (CCutil_getnodeweights (weightfile, ncount, random_weight_limit, &wcoord, &rstate)) { fprintf (stderr, "could not read the nodeweight file\n"); rval = 1; goto CLEANUP; } } if (find_nearest_tour || find_greedy_tour || find_twoopt_tour || find_fa_tour || find_qboruvka_tour || find_boruvka_tour || find_3opt_tour) { ttour = CC_SAFE_MALLOC (ncount, int); if (!ttour) { rval = 1; goto CLEANUP; } }
int main (int ac, char **av) { int ncount, rval = 0; int *tour = (int *) NULL; double val; CCdatagroup dat; CCrandstate rstate; CCutil_init_datagroup (&dat); seed = (int) CCutil_real_zeit (); rval = parseargs (ac, av); if (rval) return 1; if ((!edgefname && !tspfname) || (edgefname && tspfname)) { usage (av[0]); return 1; } CCutil_sprand (seed, &rstate); if (tspfname) { rval = CCutil_gettsplib (tspfname, &ncount, &dat); if (rval) { fprintf (stderr, "CCutil_gettsplib failed\n"); goto CLEANUP; } } else { rval = CCutil_getdata (edgefname, 0, CC_SPARSE, &ncount, &dat, 0, 0, &rstate); if (rval) { fprintf (stderr, "CCutil_getdata failed\n"); goto CLEANUP; } } tour = CC_SAFE_MALLOC (ncount, int); if (!tour) { fprintf (stderr, "out of memory in main\n"); rval = 1; goto CLEANUP; } if (eformat == 0) { if (simpletour) { rval = CCutil_getcycle (ncount, cycfname, tour, 0); if (rval) { fprintf (stderr, "CCutil_getcycle failed\n"); goto CLEANUP; } } else { rval = CCutil_getcycle_tsplib (ncount, cycfname, tour); CCcheck_rval (rval, "CCutil_getcycle_tsplib failed"); } } else { rval = CCutil_getcycle_edgelist (ncount, cycfname, tour, 0); if (rval) { fprintf (stderr, "CCutil_getcycle_edgelist failed\n"); goto CLEANUP; } } { int *chk = (int *) NULL; int i; chk = CC_SAFE_MALLOC (ncount, int); CCcheck_NULL (chk, "out of memory in main"); for (i = 0; i < ncount; i++) chk[i] = 0; for (i = 0; i < ncount; i++) { if (chk[tour[i]] == 1) { fprintf (stderr, "duplicate node in tour: %d, position %d\n", tour[i], i); rval = 1; goto CLEANUP; } chk[tour[i]] = 1; } CC_IFFREE (chk, int); } if (edgefname) { int istour; rval = CCutil_sparse_real_tour (ncount, &dat, tour, &istour); if (rval) { fprintf (stderr, "CCutil_sparse_real_tour failed\n"); goto CLEANUP; } if (istour == 0) { printf ("Tour is not contained in the sparse edge set\n"); fflush (stdout); goto CLEANUP; } } CCutil_cycle_len (ncount, &dat, tour, &val); printf ("Tour Length: %.0f\n", val); fflush (stdout); CLEANUP: CC_IFFREE (tour, int); CCutil_freedatagroup (&dat); return rval; }