Example #1
0
void sweep(int parent, heur_prob *p)
{
  printf("\nIn sweep....\n\n");
  int mytid, info, r_bufid;
  int i;
  int vertnum;
  sweep_data *data;
  float depotx, depoty;
  float tempx, tempy;
  double t=0;

  mytid = pvm_mytid();

  (void) used_time(&t);

  printf("mytid in sweep.c= %i", pvm_mytid());
  /*-----------------------------------------------------------------------*\
  |                     Receive the VRP data                                |
  \*-----------------------------------------------------------------------*/

  PVM_FUNC(r_bufid, pvm_recv(-1, SWEEP_TRIALS));
  PVM_FUNC(info, pvm_upkint(&(p->par.sweep_trials), 1, 1));
  printf("\nCheckpoint 1\n");
  /*-----------------------------------------------------------------------*/

  vertnum = p->vertnum;
  p->cur_tour = (best_tours *)calloc(1, sizeof(best_tours));
  p->cur_tour->tour = (_node *)calloc(vertnum, sizeof(_node));
  printf("\nCheckpoint 2\n");
  data = (sweep_data *)calloc(vertnum-1, sizeof(sweep_data));
  if (p->dist.coordx && p->dist.coordy){
     depotx = p->dist.coordx[0];
     depoty = p->dist.coordy[0];
     printf("\nCheckpoint 3\n");
     /*calculate angles for sorting*/
     for (i=0; i<vertnum-1; i++){
       tempx = p->dist.coordx[i+1] - depotx;
       tempy = p->dist.coordy[i+1] - depoty;
       data[i].angle = (float) atan2(tempy, tempx);
       if (data[i].angle < 0) data[i].angle += 2*M_PI;
       data[i].cust=i+1;
     }
     printf("\nCheckpoint 4\n");
     quicksort(data, vertnum-1);
     printf("\nCheckpoint 5\n");
     make_tour(p, data, p->cur_tour);
     printf("\nCheckpoint 6\n");
  /*-----------------------------------------------------------------------*\
  |               Transmit the tour back to the parent                      |
  \*-----------------------------------------------------------------------*/

     send_tour(p->cur_tour->tour, p->cur_tour->cost, p->cur_tour->numroutes,
	       SWEEP, used_time(&t), parent, vertnum, 0, NULL);
     printf("\nCheckpoint 7\n");
  }
  if (data) free((char *) data);
  printf("\nCheckpoint 8\n");    
  free_heur_prob(p);
  
}
Example #2
0
void nearest_ins(int parent, heur_prob *p)
{
  printf("\nIn nearest_ins....\n\n");
  int numroutes, cur_route, nearnode, *starter;
  int mytid, info, r_bufid;
  int *intour;
  int last, cost;
  neighbor *nbtree;
  _node *tour;
  route_data *route_info;
  int start;
  best_tours *tours;
  double t=0;

  mytid = pvm_mytid();

  (void) used_time(&t);

  tours = p->cur_tour = (best_tours *) calloc (1, sizeof(best_tours));
	
  /*-----------------------------------------------------------------------*\
  |                     Receive the VRP data                                |
  \*-----------------------------------------------------------------------*/

  PVM_FUNC(r_bufid, pvm_recv(-1, ROUTE_NINS_VRP_DATA));

  PVM_FUNC(info, pvm_upkbyte((char *)tours, sizeof(best_tours), 1));
  tour = p->cur_tour->tour = (_node *) calloc (p->vertnum, sizeof(_node));
  PVM_FUNC(info, pvm_upkbyte((char *)tour, (p->vertnum)*sizeof(_node), 1));
  numroutes = p->cur_tour->numroutes;
  starter = (int *) calloc (numroutes, sizeof(int));
  route_info = p->cur_tour->route_info
             = (route_data *) calloc (numroutes+1, sizeof(route_data));
	
  PVM_FUNC(r_bufid, pvm_recv(-1, ROUTE_NINS_START_RULE));
  PVM_FUNC(info, pvm_upkint(&start, 1, 1));/*receive the start
							   rule*/

  if (start != FAR_INS) srand(start); /*if the start rule is random, then*\
	                              \*initialize the random number gen.*/
  starters(p, starter, route_info, start);/*generate the route starters for*\
                                          \*all the clusters.              */
  /*-----------------------------------------------------------------------*\
  |                     Allocate arrays                                     |
  \*-----------------------------------------------------------------------*/

  nbtree   = (neighbor *) malloc (p->vertnum * sizeof(neighbor));
  intour   = (int *)      calloc (p->vertnum, sizeof(int));
	
  /*-----------------------------------------------------------------------*\
  |               Find the nearest insertion tour from 'starters'           |
  \*-----------------------------------------------------------------------*/

  for (cur_route=1; cur_route<=numroutes; cur_route++){
    /*---------------------------------------------------------------------*\
    | The first part of this loop adds the starter and the nearest node to  |
    | it into the route to initialize it. Then a function is called         |
    | which inserts the rest of the nodes into the route in nearest         |
    | insert order.                                                         |
    \*---------------------------------------------------------------------*/
    if (route_info[cur_route].numcust <= 1) continue;
    cost = 0;
    last = 0;
    intour[0] = 0;
    intour[starter[cur_route-1]] = IN_TOUR;
    ni_insert_edges(p, starter[cur_route-1], nbtree, intour, &last, tour, cur_route);
    nearnode = closest(nbtree, intour, &last);
    intour[nearnode] = IN_TOUR;
    ni_insert_edges(p, nearnode, nbtree, intour, &last, tour, cur_route);
    tour[starter[cur_route-1]].next = nearnode;
    tour[nearnode].next = starter[cur_route-1];
    if (starter[cur_route - 1] == 0)
      route_info[cur_route].first = route_info[cur_route].last = nearnode;
    if (nearnode == 0)
      route_info[cur_route].first = route_info[cur_route].last
	                          = starter[cur_route-1];      

    cost = 2 * ICOST(&p->dist, starter[cur_route-1], nearnode);
    cost = nearest_ins_from_to(p, tour, cost, 2, route_info[cur_route].numcust+1,
			       starter[cur_route-1],
			       nbtree, intour, &last, route_info, cur_route);
    route_info[cur_route].cost = cost;
  }

  tour[0].next = route_info[1].first;

  /*-------------------------------------------------------------------------*\
  | This loop points the last node of each route to the first node of the next|
  | route. At the end of this procedure, the last node of each route is       |
  | pointing at the depot, which is not what we want.                         |
  \*-------------------------------------------------------------------------*/
  for (cur_route = 1; cur_route< numroutes; cur_route++)
    tour[route_info[cur_route].last].next = route_info[cur_route+1].first;

  cost = compute_tour_cost(&p->dist, tour);
	
  /*-----------------------------------------------------------------------*\
  |               Transmit the tour back to the parent                      |
  \*-----------------------------------------------------------------------*/
  
  send_tour(tour, cost, numroutes, tours->algorithm, used_time(&t), parent,
	    p->vertnum, 1, route_info);
	
  if ( nbtree ) free ((char *) nbtree);
  if ( intour ) free ((char *) intour);
  if ( starter) free ((char *) starter);

  free_heur_prob(p);
	
}
Example #3
0
void tsp_fini(int parent, heur_prob *p)
{
  printf("\nIn tsp_fini....\n\n");
   int mytid, info, r_bufid;
   int starter, farnode, v0, v1, cur_start;
   _node *tsp_tour, *tour, *opt_tour;
   int maxdist;
   int *intour;
   int last, cost;
   int i, j;
   neighbor *nbtree;
   int trials, interval;
   int farside, vertnum;
   best_tours *opt_tours, *tours;
   double t=0;

   mytid = pvm_mytid();

   (void) used_time(&t);
		
   /*-----------------------------------------------------------------------*\
   |                     Receive the VRP data                                |
   \*-----------------------------------------------------------------------*/



   PVM_FUNC(r_bufid, pvm_recv(-1, TSP_FINI_TRIALS));
   PVM_FUNC(info, pvm_upkint(&trials, 1, 1));

   PVM_FUNC(r_bufid, pvm_recv(parent, TSP_FINI_RATIO));
   PVM_FUNC(info, pvm_upkint(&farside, 1, 1));
	
   /*-----------------------------------------------------------------------*\
   |                     Receive the starting point                          |
   \*-----------------------------------------------------------------------*/
   PVM_FUNC(r_bufid, pvm_recv(-1, TSP_START_POINT));
   PVM_FUNC(info, pvm_upkint(&starter, 1, 1));
   vertnum = p->vertnum;
	
   if (starter == vertnum)
      for (starter=v0=1, maxdist=ICOST(&p->dist, 0,1); v0<vertnum-1; v0++)
	 for (v1=v0+1; v1<vertnum; v1++)
	    if (maxdist < ICOST(&p->dist, v0, v1)){
	       maxdist = ICOST(&p->dist, v0, v1);
	       starter = v0;
	    }
	
   /*-----------------------------------------------------------------------*\
   |                     Allocate arrays                                     |
   \*-----------------------------------------------------------------------*/
   tsp_tour   = (_node *)  malloc (vertnum * sizeof(_node));
   nbtree     = (neighbor *) malloc (vertnum * sizeof(neighbor));
   intour     = (int *)      calloc (vertnum, sizeof(int));
   tours      = p->cur_tour = (best_tours *) calloc (1, sizeof(best_tours));
   tour       = p->cur_tour->tour = (_node *) calloc (vertnum, sizeof(_node));
   opt_tours = (best_tours *) malloc (sizeof(best_tours));
   opt_tour  = (_node *) malloc (vertnum*sizeof(_node));

  /*------------------------------------------------------------------------*\
  | This heuristic is a so-called route-first, cluster-second heuristic.     |
  | We first construct a TSP route by farnear insert and then partition it   |
  | into feasible routes by finding a shortest cycle of a graph with edge    |
  | costs bewtween nodes being defined to be the cost of a route from one    |
  | endpoint of the edge to the other.                                       |
  \*------------------------------------------------------------------------*/
	
   /*-----------------------------------------------------------------------*\
   |   Find the first 'farside node with farthest insertion from 'starter'   |
   \*-----------------------------------------------------------------------*/
   last = 0;
   intour[0] = IN_TOUR;
   intour[starter] = IN_TOUR;
   tsp_fi_insert_edges(p, starter, nbtree, intour, &last);
   farnode = tsp_farthest(nbtree, intour, &last);
   intour[farnode] = IN_TOUR;
   tsp_fi_insert_edges(p, farnode, nbtree, intour, &last);
   tsp_tour[starter].next = farnode;
   tsp_tour[farnode].next = starter;
	
   cost = 2 * ICOST(&p->dist, starter, farnode);
   farside = MAX(farside, 2);
   cost = tsp_farthest_ins_from_to(p, tsp_tour, cost, 
			       2, farside, starter, nbtree, intour, &last);
	
   /*------------------------------------------------------------------------*\
   |  Order the elements in nbtree (and fix the intour values) so after that  |
   |  nbtree is suitable to continue with nearest insertion.                  |
   \*------------------------------------------------------------------------*/

   qsort((char *)(nbtree+1), last, sizeof(neighbor), compar);
   for (i=1; i<=last; i++)
      intour[nbtree[i].nbor] = i;
	
   /*-----------------------------------------------------------------------*\
   |               Continue with nearest insertion                           |
   \*-----------------------------------------------------------------------*/
   cost = tsp_nearest_ins_from_to(p, tsp_tour, cost, 
			      farside, vertnum-1, starter, nbtree, intour, 
			      &last);

  /*------------------------------------------------------------------------*\
  | We must arbitrarily choose a node to be the first node on the first      |
  | route in order to start the partitioning algorithm. The trials variable  |
  | tells us how many starting points to try. Its value is contained in      |
  | p->par.tsp.numstarts.                                                    |
  \*------------------------------------------------------------------------*/

   if (trials > vertnum-1) trials = vertnum-1;
   interval = (vertnum-1)/trials;
   opt_tours->cost = MAXINT;

  /*------------------------------------------------------------------------*\
  | Try various partitionings and take the solution that has the least cost  |
  \*------------------------------------------------------------------------*/

   for (i=0, cur_start = starter; i<trials; i++){
     make_routes(p, tsp_tour, cur_start, tours);
     if (tours->cost < opt_tours->cost){
       (void) memcpy ((char *)opt_tours, (char *)tours, sizeof(best_tours));
       (void) memcpy ((char *)opt_tour, (char *)tour, vertnum*sizeof(_node));
     }
     for (j=0; j<interval; j++)
       cur_start = tsp_tour[cur_start].next;
   }
     
	
   /*-----------------------------------------------------------------------*\
   |              Transmit the tour back to the parent                       |
   \*-----------------------------------------------------------------------*/

   send_tour(opt_tour, opt_tours->cost, opt_tours->numroutes, TSP_FINI,
	     used_time(&t), parent, vertnum, 0, NULL);
	
   if ( nbtree ) free ((char *) nbtree);
   if ( intour ) free ((char *) intour);
   if ( opt_tours ) free ((char *) opt_tours);
   if ( opt_tour ) free ((char *) opt_tour);
   if ( tsp_tour ) free ((char *) tsp_tour);
     
   free_heur_prob(p);
	
}