Beispiel #1
0
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);
}
Beispiel #2
0
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)
Beispiel #3
0
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;
}
Beispiel #4
0
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;
        }
    }
Beispiel #5
0
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;
}