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); }
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); }
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); }