PostOptimize.c
Go to the documentation of this file.
1 #include "LKH.h"
2 #include <unistd.h>
3 
4 GainType SolveTSP(int Dimension, char *ParFileName,
5  char *TourFileName, int *Tour, GainType Optimum,
6  GainType Displacement);
7 
8 static GainType KOptimize(int *GTour);
9 static GainType ClusterOptimize(int *GTour);
10 
11 /*
12  * The PostOptimize function performs post optimization on a given g-tour
13  * by two means: (1) Using LKH for local optimization on an instance with
14  * the vertices of the g-tour. (2) Performing so-called cluster optimization.
15  * This heuristic attempts to find a g-tour that visits the clusters in the
16  * same order as the current g-tour, but is cheaper than this
17  *
18  * Local optimization and cluster optimization are performed as long as it is
19  * possible to improve the current best g-tour.
20  *
21  * Parameters
22  * GTour: The input g-tour
23  * Cost: The cost of GTour
24  *
25  * The resulting g-tour is returned in the parameter GTour, and its cost
26  * as the value of the function.
27  */
28 
29 GainType PostOptimize(int *GTour, GainType Cost)
30 {
31  int *BestGTour, i, Clusters = GTSPSets, FirstTime = 1;
32 
33  if (StopAtOptimum && Cost == Optimum)
34  return Cost;
35  assert(BestGTour = (int *) malloc((Clusters + 1) * sizeof(int)));
36  memcpy(BestGTour, GTour, (Clusters + 1) * sizeof(int));
37  BestCost = Cost;
38  if (TraceLevel > 0)
39  printff("Post-optimization [Cost = " GainFormat "]\n", Cost);
40 
41  while (1) {
42  /* Perform K-opt optimization */
43  if (Clusters >= 4)
44  Cost = KOptimize(GTour);
45  if (Cost < BestCost) {
46  for (i = 1; i <= Clusters; i++)
47  GTour[i] = BestGTour[GTour[i]];
48  GTour[0] = GTour[Clusters];
49  memcpy(BestGTour, GTour, (Clusters + 1) * sizeof(int));
50  BestCost = Cost;
51  if (TraceLevel > 0)
52  printff(" K-opt = " GainFormat "\n",
53  Cost);
54  } else {
55  memcpy(GTour, BestGTour, (Clusters + 1) * sizeof(int));
56  if (!FirstTime)
57  break;
58  }
59  if (StopAtOptimum && BestCost == Optimum)
60  break;
61  /* Perform cluster optimization */
62  Cost = ClusterOptimize(GTour);
63  if (Cost >= BestCost)
64  break;
65  memcpy(BestGTour, GTour, (Clusters + 1) * sizeof(int));
66  BestCost = Cost;
67  FirstTime = 0;
68  if (TraceLevel > 0)
69  printff(" C-opt = " GainFormat "\n", Cost);
70  if (StopAtOptimum && BestCost == Optimum)
71  break;
72  }
73  memcpy(GTour, BestGTour, (Clusters + 1) * sizeof(int));
74  free(BestGTour);
75  return BestCost;
76 }
77 
78 /*
79  * The KOptimize function attempts to improve a given g-tour, GTour, using LKH.
80  * The return value is the cost of the resulting g-tour.
81  */
82 
83 static GainType KOptimize(int *GTour)
84 {
85  int i, j, Clusters = GTSPSets;
86  Node *N;
87  FILE *ParFile, *ProblemFile;
88  char ParFileName[256], ProblemFileName[256], TourFileName[256],
89  Prefix[256];
90  GainType Cost;
91 
92  /* Create the problem file */
93  sprintf(Prefix, "%s.pid%d", Name, getpid());
94  sprintf(ProblemFileName, "TMP/%s.post.tsp", Prefix);
95  assert(ProblemFile = fopen(ProblemFileName, "w"));
96  fprintf(ProblemFile, "NAME : %s\n", Name);
97  fprintf(ProblemFile, "TYPE : %s\n", Type);
98  fprintf(ProblemFile, "DIMENSION : %d\n", Clusters);
99  fprintf(ProblemFile, "EDGE_WEIGHT_TYPE : %s\n", EdgeWeightType);
100  if (CoordType == NO_COORDS) {
101  fprintf(ProblemFile, "EDGE_WEIGHT_FORMAT : FULL_MATRIX\n");
102  fprintf(ProblemFile, "EDGE_WEIGHT_SECTION\n");
103  for (i = 1; i <= Clusters; i++) {
104  for (j = 1; j <= Clusters; j++)
105  fprintf(ProblemFile, "%d ", i == j ? 99999 :
106  ProblemType != ATSP ? Distance(&NodeSet[GTour[i]],
107  &NodeSet[GTour[j]])
108  : NodeSet[GTour[i]].C[GTour[j]]);
109  fprintf(ProblemFile, "\n");
110  }
111  } else {
112  fprintf(ProblemFile, "NODE_COORD_SECTION\n");
113  if (CoordType == TWOD_COORDS) {
114  for (i = 1; i <= Clusters; i++) {
115  N = &NodeSet[GTour[i]];
116  fprintf(ProblemFile, "%d %f %f\n", i, N->X, N->Y);
117  }
118  } else if (CoordType == THREED_COORDS) {
119  for (i = 1; i <= Clusters; i++) {
120  N = &NodeSet[GTour[i]];
121  fprintf(ProblemFile, "%d %f %f %f\n", i, N->X, N->Y, N->Z);
122  }
123  }
124  }
125  fprintf(ProblemFile, "EOF\n");
126  fclose(ProblemFile);
127 
128  /* Create the parameter file */
129  sprintf(ParFileName, "TMP/%s.post.par", Prefix);
130  assert(ParFile = fopen(ParFileName, "w"));
131  fprintf(ParFile, "PROBLEM_FILE = %s\n", ProblemFileName);
132  fprintf(ParFile, "MAX_TRIALS = %d\n", MaxTrials);
133  fprintf(ParFile, "OPTIMUM = " GainFormat "\n", BestCost);
134  fprintf(ParFile, "PRECISION = %d\n", Precision);
135  fprintf(ParFile, "RUNS = 1\n");
136  fprintf(ParFile, "SEED = %d\n", Seed);
137  if (!Subgradient)
138  fprintf(ParFile, "SUBGRADIENT = NO\n");
139  sprintf(TourFileName, "TMP/%s.post.tour", Prefix);
140  fprintf(ParFile, "TOUR_FILE = %s\n", TourFileName);
141  fclose(ParFile);
142 
143  /* Solve the problem */
144  Cost =
145  SolveTSP(Clusters, ParFileName, TourFileName, GTour, BestCost, 0);
146  unlink(ParFileName);
147  unlink(ProblemFileName);
148  return Cost;
149 }
150 
151 /*
152  * The ClusterOptimize function attempts to improve a given g-tour, GTour,
153  * using cluster optimization (shortest path in a layered network).
154  * See M. Fischetti et al.: A branch-and-cut algorithm for the symmetric
155  * generalized traveling salesman problem.
156  * Operations Research, 45:378-394, 1997.
157  *
158  * The return value is the cost of the resulting g-tour.
159  */
160 
161 static GainType ClusterOptimize(int *GTour)
162 {
163  int i, j = 1, d, MinSize, MinV, Clusters = GTSPSets;
164  Cluster *Cl;
165  Node **First, *From, *To;
166  GainType Cost = PLUS_INFINITY;
167 
168  MinSize = MinV = INT_MAX;
169  for (Cl = FirstCluster; Cl && MinSize != 1; Cl = Cl->Next) {
170  if (Cl->Size < MinSize) {
171  MinSize = Cl->Size;
172  MinV = Cl->First->V;
173  }
174  }
175  for (i = 1; i <= Clusters; i++) {
176  From = &NodeSet[GTour[i]];
177  if (From->V == MinV) {
178  j = i;
179  break;
180  }
181  }
182  assert(First = (Node **) malloc(Clusters * sizeof(Node *)));
183  for (i = 0; i < Clusters; i++) {
184  First[i] = &NodeSet[GTour[j]];
185  if (++j > Clusters)
186  j = 1;
187  }
188  FirstNode = First[0];
189  do {
190  FirstNode->Cost = 0;
191  FirstNode->Dad = 0;
192  To = First[1];
193  do {
194  To->Cost = ProblemType != ATSP ? Distance(FirstNode, To)
195  : FirstNode->C[To->Id];
196  To->Dad = FirstNode;
197  } while ((To = To->Next) != First[1]);
198  for (i = 2; i < Clusters; i++) {
199  To = First[i];
200  do {
201  To->Cost = INT_MAX;
202  From = First[i - 1];
203  do {
204  if ((d = From->Cost +
205  (ProblemType != ATSP ? Distance(From, To) :
206  From->C[To->Id])) < To->Cost) {
207  To->Dad = From;
208  To->Cost = d;
209  }
210  } while ((From = From->Next) != First[i - 1]);
211  } while ((To = To->Next) != First[i]);
212  }
213  From = First[Clusters - 1];
214  do {
215  if ((d = From->Cost +
216  (ProblemType != ATSP ? Distance(From, FirstNode) :
217  From->C[FirstNode->Id])) < Cost) {
218  Cost = d;
219  for (i = Clusters, To = From; To; To = To->Dad)
220  GTour[i--] = To->Id;
221  }
222  } while ((From = From->Next) != First[Clusters - 1]);
223  } while ((FirstNode = FirstNode->Next) != First[0]);
224  free(First);
225  GTour[0] = GTour[Clusters];
226  return Cost;
227 }
d
char * ProblemFileName
Definition: LKH.h:284
int Dimension
Definition: LKH.h:190
double Y
Definition: LKH.h:123
GainType PostOptimize(int *GTour, GainType Cost)
Definition: PostOptimize.c:29
int Precision
Definition: LKH.h:249
Definition: LKH.h:42
int GTSPSets
Definition: LKH.h:209
int CoordType
Definition: LKH.h:290
void printff(char *fmt,...)
Definition: printff.c:10
Definition: LKH.h:68
int Id
Definition: LKH.h:69
double X
Definition: LKH.h:123
Definition: LKH.h:162
CostFunction Distance
Definition: LKH.h:304
double Z
Definition: LKH.h:123
GainType Optimum
Definition: LKH.h:241
Node * NodeSet
Definition: LKH.h:235
int MaxTrials
Definition: LKH.h:230
Definition: LKH.h:41
static GainType KOptimize(int *GTour)
Definition: PostOptimize.c:83
Node * Dad
Definition: LKH.h:94
Cluster * Next
Definition: LKH.h:164
Node * FirstNode
Definition: LKH.h:201
static GainType ClusterOptimize(int *GTour)
Definition: PostOptimize.c:161
int TraceLevel
Definition: LKH.h:274
int * C
Definition: LKH.h:88
int Cost
Definition: LKH.h:78
int Subgradient
Definition: LKH.h:262
int V
Definition: LKH.h:75
CostFunction C
Definition: LKH.h:304
unsigned Seed
Definition: LKH.h:259
char * TourFileName
Definition: LKH.h:284
int StopAtOptimum
Definition: LKH.h:260
Node * Next
Definition: LKH.h:96
#define PLUS_INFINITY
Definition: GainType.h:20
char * Name
Definition: LKH.h:288
GainType SolveTSP(int Dimension, char *ParFileName, char *TourFileName, int *Tour, GainType Optimum, GainType Displacement)
Definition: SolveTSP.c:18
char * Type
Definition: LKH.h:288
int Size
Definition: LKH.h:165
Cluster * FirstCluster
Definition: LKH.h:200
int ProblemType
Definition: LKH.h:290
FILE * ProblemFile
Definition: LKH.h:302
#define GainFormat
Definition: GainType.h:22
char * EdgeWeightType
Definition: LKH.h:288
long long GainType
Definition: GainType.h:13
GainType BestCost
Definition: LKH.h:179
Node * First
Definition: LKH.h:163


glkh_solver
Author(s): Francisco Suarez-Ruiz
autogenerated on Mon Jun 10 2019 13:50:26