SolveGTSP.c
Go to the documentation of this file.
1 #include "LKH.h"
2 #include <unistd.h>
3 #include <sys/time.h>
4 #include <sys/resource.h>
5 
6 GainType SolveTSP(int Dimension, char *ParFileName,
7  char *TourFileName, int *Tour, GainType Optimum,
8  GainType Deduction);
9 
11 static void WriteFullTour(enum TourType Type, int Dimension,
12  char *TourFileName, int Id);
13 
14 /*
15  * The SolveGTSP function solves an E-GTSP instance. The resulting g-tour is
16  * returned in the parameter GTour, and its cost as the value of the
17  * function.
18  *
19  * The algorithm is as follows:
20  *. 1. Transform the E-GTSP instance into an asymmetric TSP instance.
21  * 2. Write the TSP instance to a problem file.
22  * 3. Write suitable parameter values to a parameter file.
23  * 4. Execute LKH given these two files (by calling solveTSP).
24  * 5. Extract the g-tour from the TSP solution tour by picking the
25  * first vertex from each cluster in the TSP tour.
26  */
27 
28 GainType SolveGTSP(int *GTour)
29 {
30  int i, j, Dist, Clusters = 0;
31  Cluster *Cl;
32  Node *From, *To;
33  FILE *ParFile, *ProblemFile;
34  char ParFileName[256], ProblemFileName[256], TourFileName[256],
35  NewInitialTourFileName[256] = { 0 },
36  NewInputTourFileName[256] = { 0 },
37  NewSubproblemTourFileName[256] = { 0 },
38  **NewMergeTourFileName,
39  Prefix[256];
40  GainType M, Cost;
41  int *Tour, *Used;
42 
43  assert(NewMergeTourFileName =
44  (char **) malloc(MergeTourFiles * sizeof(char *)));
45  for (i = 0; i < MergeTourFiles; i++)
46  assert(NewMergeTourFileName[i] = (char *) malloc(256));
47  for (Cl = FirstCluster; Cl; Cl = Cl->Next) {
48  Clusters++;
49  From = Cl->First;
50  do
51  From->V = Clusters;
52  while ((From = From->Next) != Cl->First);
53  }
54  assert(Clusters == GTSPSets);
55 
56  M = Clusters < 2 ? 0 : INT_MAX / 4 / Precision;
57 
58  sprintf(Prefix, "%s.pid%d", Name, getpid());
59 
60  /* Create the problem file */
61  sprintf(ProblemFileName, "TMP/%s.atsp", Prefix);
62  assert(ProblemFile = fopen(ProblemFileName, "w"));
63  fprintf(ProblemFile, "NAME : %s.gtsp\n", Prefix);
64  fprintf(ProblemFile, "TYPE : ATSP\n");
65  if (ProblemType != ATSP)
66  fprintf(ProblemFile, "DIMENSION : %d\n", Dimension);
67  else
68  fprintf(ProblemFile, "DIMENSION : %d\n", DimensionSaved);
69  fprintf(ProblemFile, "EDGE_WEIGHT_TYPE : EXPLICIT\n");
70  fprintf(ProblemFile, "EDGE_WEIGHT_FORMAT : FULL_MATRIX\n");
71  fprintf(ProblemFile, "EDGE_WEIGHT_SECTION\n");
72 
73  /* Transform the GTSP into an ATSP */
74  for (i = 1; i <= DimensionSaved; i++) {
75  From = &NodeSet[i];
76  for (j = 1; j <= DimensionSaved; j++) {
77  if (i == j)
78  fprintf(ProblemFile, "999999 ");
79  else {
80  To = &NodeSet[j];
81  Dist = To == From->Next ? (GainType) 0 :
82  To->V == From->V ? 2 * M :
83  (ProblemType != ATSP ? Distance(From->Next, To) :
84  From->Next->C[j]) + M;
85  fprintf(ProblemFile, "%d ", Dist);
86  while (Dist * Precision / Precision != Dist) {
87  printff("*** PRECISION (= %d) is too large. ",
88  Precision);
89  if ((Precision /= 10) < 1)
90  Precision = 1;
91  printff("Changed to %d.\n", Precision);
92  }
93  }
94  }
95  fprintf(ProblemFile, "\n");
96  }
97  fprintf(ProblemFile, "EOF\n");
98  fclose(ProblemFile);
99 
100  /* Create the parameter file */
101  sprintf(ParFileName, "TMP/%s.par", Prefix);
102  assert(ParFile = fopen(ParFileName, "w"));
103  fprintf(ParFile, "PROBLEM_FILE = TMP/%s.atsp\n", Prefix);
104  fprintf(ParFile, "ASCENT_CANDIDATES = %d\n", AscentCandidates);
105  fprintf(ParFile, "BACKBONE_TRIALS = %d\n", BackboneTrials);
106  if (Backtracking)
107  fprintf(ParFile, "BACKTRACKING = YES\n");
108  for (i = 0; i < CandidateFiles; i++)
109  fprintf(ParFile, "CANDIDATE_FILE = %s\n", CandidateFileName[i]);
110  fprintf(ParFile, "CANDIDATE_SET_TYPE = ALPHA\n");
111  if (Excess > 0)
112  fprintf(ParFile, "EXCESS = %g\n", Excess);
113  if (!Gain23Used)
114  fprintf(ParFile, "GAIN23 = NO\n");
115  if (!GainCriterionUsed)
116  fprintf(ParFile, "GAIN_CRITERION = NO\n");
117  fprintf(ParFile, "INITIAL_PERIOD = %d\n", InitialPeriod);
118  if (InitialTourAlgorithm != WALK)
119  fprintf(ParFile, "INITIAL_TOUR_ALGORITHM = %s\n",
121  NEAREST_NEIGHBOR ? "NEAREST-NEIGHBOR" :
122  InitialTourAlgorithm == GREEDY ? "GREEDY" : "");
123  fprintf(ParFile, "INITIAL_STEP_SIZE = %d\n", InitialStepSize);
124  if (InitialTourFileName) {
125  sprintf(NewInitialTourFileName, "TMP/%s.initial.tour", Prefix);
126  WriteFullTour(INITIAL, DimensionSaved, NewInitialTourFileName, 0);
127  fprintf(ParFile, "INITIAL_TOUR_FILE = %s\n",
128  NewInitialTourFileName);
129  }
130  fprintf(ParFile, "INITIAL_TOUR_FRACTION = %0.3f\n",
132  if (InputTourFileName) {
133  sprintf(NewInputTourFileName, "TMP/%s.input.tour", Prefix);
134  WriteFullTour(INPUT, DimensionSaved, NewInputTourFileName, 0);
135  fprintf(ParFile, "INPUT_TOUR_FILE = %s\n", NewInputTourFileName);
136  }
137  fprintf(ParFile, "KICK_TYPE = %d\n", KickType);
138  fprintf(ParFile, "MAX_BREADTH = %d\n", MaxBreadth);
139  fprintf(ParFile, "MAX_CANDIDATES = %d%s\n", MaxCandidates,
140  CandidateSetSymmetric ? " SYMMETRIC" : "");
141  fprintf(ParFile, "MAX_SWAPS = %d\n", MaxSwaps);
142  fprintf(ParFile, "MAX_TRIALS = %d\n", MaxTrials);
143  for (i = 0; i < MergeTourFiles; i++) {
144  sprintf(NewMergeTourFileName[i],
145  "TMP/%s.merge%d.tour", Prefix, i + 1);
146  WriteFullTour(MERGE, DimensionSaved, NewMergeTourFileName[i], i);
147  fprintf(ParFile, "MERGE_TOUR_FILE = %s\n",
148  NewMergeTourFileName[i]);
149  }
150  fprintf(ParFile, "MOVE_TYPE = %d\n", MoveType);
151  if (NonsequentialMoveType >= 4)
152  fprintf(ParFile, "NONSEQUENTIAL_MOVE_TYPE = %d\n",
154  if (Optimum != MINUS_INFINITY)
155  fprintf(ParFile, "OPTIMUM = " GainFormat "\n",
156  Optimum + Clusters * M);
157  fprintf(ParFile, "PATCHING_A = %d %s\n", PatchingA,
158  PatchingARestricted ? "RESTRICTED" :
159  PatchingAExtended ? "EXTENDED" : "");
160  fprintf(ParFile, "PATCHING_C = %d %s\n", PatchingC,
161  PatchingCRestricted ? "RESTRICTED" :
162  PatchingCExtended ? "EXTENDED" : "");
163  if (PiFileName)
164  fprintf(ParFile, "PI_FILE = %s\n", PiFileName);
165  fprintf(ParFile, "POPULATION_SIZE = %d\n", MaxPopulationSize);
166  fprintf(ParFile, "PRECISION = %d\n", Precision);
167  if (!RestrictedSearch)
168  fprintf(ParFile, "RESTRICTED_SEARCH = NO\n");
169  fprintf(ParFile, "RUNS = %d\n", Runs);
170  fprintf(ParFile, "SEED = %d\n", Seed);
171  if (!StopAtOptimum)
172  fprintf(ParFile, "STOP_AT_OPTIMUM = NO\n");
173  if (!Subgradient)
174  fprintf(ParFile, "SUBGRADIENT = NO\n");
175  if (SubproblemSize > 0)
176  fprintf(ParFile, "SUBPROBLEM_SIZE = %d\n", 2 * SubproblemSize);
178  sprintf(NewSubproblemTourFileName, "TMP/%s.subproblem.tour",
179  Prefix);
180  WriteFullTour(SUBPROBLEM, DimensionSaved, NewSubproblemTourFileName, 0);
181  fprintf(ParFile, "SUBPROBLEM_TOUR_FILE = %s\n",
182  NewSubproblemTourFileName);
183  }
184  fprintf(ParFile, "SUBSEQUENT_MOVE_TYPE = %d\n", SubsequentMoveType);
185  if (!SubsequentPatching)
186  fprintf(ParFile, "SUBSEQUENT_PATCHING = NO\n");
187  if (TimeLimit != DBL_MAX)
188  fprintf(ParFile, "TIME_LIMIT = %0.1f\n", TimeLimit);
189  sprintf(TourFileName, "TMP/%s.tour", Prefix);
190  fprintf(ParFile, "TOUR_FILE = %s\n", TourFileName);
191  fprintf(ParFile, "TRACE_LEVEL = %d\n",
192  TraceLevel == 0 ? 1 : TraceLevel);
193  fclose(ParFile);
194 
195  /* Solve the ATSP */
196  assert(Tour = (int *) malloc((DimensionSaved + 1) * sizeof(int)));
197  Cost =
198  SolveTSP(DimensionSaved, ParFileName, TourFileName,
199  Tour, Optimum, Clusters * M);
200  unlink(ParFileName);
201  unlink(ProblemFileName);
202  unlink(NewInitialTourFileName);
203  unlink(NewInputTourFileName);
204  for (i = 0; i < MergeTourFiles; i++)
205  unlink(NewMergeTourFileName[i]);
206  unlink(NewSubproblemTourFileName);
207 
208  /* Extract the g-tour and check it */
209  for (i = 1; i <= DimensionSaved; i++)
210  NodeSet[Tour[i - 1]].Suc = &NodeSet[Tour[i]];
211  free(Tour);
212  From = FirstNode;
213  i = From->V;
214  do
215  FirstNode = From = From->Suc;
216  while (From->V == i);
217  assert(Used = (int *) calloc(Clusters + 1, sizeof(int)));
218  i = 0;
219  do {
220  GTour[++i] = From->Id;
221  j = From->V;
222  if (Used[j])
223  eprintf("Illegal g-tour: cluster entered more than once");
224  Used[j] = 1;
225  while (From->V == j)
226  From = From->Suc;
227  } while (From != FirstNode);
228  free(Used);
229  if (i != Clusters)
230  eprintf("Illegal g-tour: unvisited cluster(s)");
231  GTour[0] = GTour[Clusters];
232  return Cost;
233 }
234 
235 static void WriteFullTour(enum TourType Type, int Dimension,
236  char *TourFileName, int Id)
237 {
238  int *Tour, i = 0;
239  Node *N, *From, *To;
240 
241  assert(Tour = (int *) malloc((Dimension + 1) * sizeof(int)));
242  From = FirstNode;
243  while (Type == INITIAL ? !From->InitialSuc :
244  Type == INPUT ? !From->InputSuc :
245  Type == MERGE ? !From->MergeSuc[Id] :
246  Type == SUBPROBLEM ? !From->SubproblemSuc : 0)
247  From = From->Suc;
248  N = From;
249  do {
250  To = N;
251  do
252  Tour[++i] = N->Id;
253  while ((N = N->Next) != To);
254  N = Type == INITIAL ? N->InitialSuc :
255  Type == INPUT ? N->InputSuc :
256  Type == MERGE ? N->MergeSuc[Id] :
257  Type == SUBPROBLEM ? N->SubproblemSuc : From;
258  } while (N != From);
259  assert(i == Dimension);
260  Tour[0] = Tour[Dimension];
261  WriteTour(TourFileName, Tour, -1);
262  free(Tour);
263 }
char * ProblemFileName
Definition: LKH.h:284
int Dimension
Definition: LKH.h:190
int Gain23Used
Definition: LKH.h:206
int NonsequentialMoveType
Definition: LKH.h:237
double InitialTourFraction
Definition: LKH.h:212
int MaxSwaps
Definition: LKH.h:227
GainType SolveTSP(int Dimension, char *ParFileName, char *TourFileName, int *Tour, GainType Optimum, GainType Deduction)
Definition: SolveTSP.c:18
int SubsequentMoveType
Definition: LKH.h:265
Definition: LKH.h:53
char * SubproblemTourFileName
Definition: LKH.h:284
int CandidateSetSymmetric
Definition: LKH.h:290
int Precision
Definition: LKH.h:249
int SubproblemSize
Definition: LKH.h:264
int GTSPSets
Definition: LKH.h:209
TourType
Definition: SolveGTSP.c:10
int GainCriterionUsed
Definition: LKH.h:207
void printff(char *fmt,...)
Definition: printff.c:10
Definition: LKH.h:68
int MaxCandidates
Definition: LKH.h:224
int Id
Definition: LKH.h:69
Definition: LKH.h:162
int KickType
Definition: LKH.h:217
CostFunction Distance
Definition: LKH.h:304
#define MINUS_INFINITY
Definition: GainType.h:21
int PatchingAExtended
Definition: LKH.h:290
GainType Optimum
Definition: LKH.h:241
int MaxBreadth
Definition: LKH.h:221
Node * NodeSet
Definition: LKH.h:235
int MaxTrials
Definition: LKH.h:230
int MergeTourFiles
Definition: LKH.h:231
Definition: LKH.h:41
double Excess
Definition: LKH.h:192
int PatchingA
Definition: LKH.h:245
Node * InputSuc
Definition: LKH.h:108
int RestrictedSearch
Definition: LKH.h:253
Cluster * Next
Definition: LKH.h:164
int DimensionSaved
Definition: LKH.h:191
Node * Suc
Definition: LKH.h:89
Node ** MergeSuc
Definition: LKH.h:114
Node * FirstNode
Definition: LKH.h:201
Node * InitialSuc
Definition: LKH.h:109
int TraceLevel
Definition: LKH.h:274
void eprintf(const char *fmt,...)
Definition: eprintf.c:8
int * C
Definition: LKH.h:88
char * PiFileName
Definition: LKH.h:284
int Subgradient
Definition: LKH.h:262
int MaxPopulationSize
Definition: LKH.h:229
int PatchingC
Definition: LKH.h:247
int V
Definition: LKH.h:75
unsigned Seed
Definition: LKH.h:259
int Runs
Definition: LKH.h:258
char * TourFileName
Definition: LKH.h:284
static void WriteFullTour(enum TourType Type, int Dimension, char *TourFileName, int Id)
Definition: SolveGTSP.c:235
int StopAtOptimum
Definition: LKH.h:260
GainType SolveGTSP(int *GTour)
Definition: SolveGTSP.c:28
Node * Next
Definition: LKH.h:96
int InitialTourAlgorithm
Definition: LKH.h:290
char * Name
Definition: LKH.h:288
char * Type
Definition: LKH.h:288
Cluster * FirstCluster
Definition: LKH.h:200
int ProblemType
Definition: LKH.h:290
double TimeLimit
Definition: LKH.h:273
int AscentCandidates
Definition: LKH.h:174
Definition: LKH.h:52
int PatchingARestricted
Definition: LKH.h:290
int InitialStepSize
Definition: LKH.h:211
int Backtracking
Definition: LKH.h:177
int PatchingCRestricted
Definition: LKH.h:290
void WriteTour(char *FileName, int *Tour, GainType Cost)
Definition: WriteTour.c:16
FILE * ProblemFile
Definition: LKH.h:302
int M
Definition: LKH.h:218
int SubsequentPatching
Definition: LKH.h:269
#define GainFormat
Definition: GainType.h:22
int CandidateFiles
Definition: LKH.h:188
char * InitialTourFileName
Definition: LKH.h:284
char * InputTourFileName
Definition: LKH.h:284
char ** CandidateFileName
Definition: LKH.h:284
int MoveType
Definition: LKH.h:232
int InitialPeriod
Definition: LKH.h:210
long long GainType
Definition: GainType.h:13
int BackboneTrials
Definition: LKH.h:176
int PatchingCExtended
Definition: LKH.h:290
Node * SubproblemSuc
Definition: LKH.h:111
Node * First
Definition: LKH.h:163


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