void PrintStatistics() { int _Runs = Runs, _TrialsMin = TrialsMin; double _TimeMin = TimeMin; GainType _Optimum = Optimum; printff("Successes/Runs = %d/%d \n", Successes, Runs); if (_Runs == 0) _Runs = 1; if (_TrialsMin > TrialsMax) _TrialsMin = 0; if (_TimeMin > TimeMax) _TimeMin = 0; if (CostMin <= CostMax && CostMin != PLUS_INFINITY) { printff ("Cost.min = " GainFormat ", Cost.avg = %0.2f, Cost.max = " GainFormat "\n", CostMin, (double) CostSum / _Runs, CostMax); if (_Optimum == MINUS_INFINITY) _Optimum = BestCost; if (_Optimum != 0) printff ("Gap.min = %0.4f%%, Gap.avg = %0.4f%%, Gap.max = %0.4f%%\n", 100.0 * (CostMin - _Optimum) / _Optimum, 100.0 * (CostSum / _Runs - _Optimum) / _Optimum, 100.0 * (CostMax - _Optimum) / _Optimum); } printff("Trials.min = %d, Trials.avg = %0.1f, Trials.max = %d\n", _TrialsMin, 1.0 * TrialSum / _Runs, TrialsMax); printff ("Time.min = %0.1f sec., Time.avg = %0.1f sec., Time.max = %0.1f sec.\n", fabs(_TimeMin), fabs(TimeSum) / _Runs, fabs(TimeMax)); }
void WriteCandidates() { FILE *CandidateFile; int i, Count; Candidate *NN; Node *N; if (CandidateFiles == 0 || !(CandidateFile = fopen(CandidateFileName[0], "w"))) return; if (TraceLevel >= 1) printff("Writing CANDIDATE_FILE: \"%s\" ... ", CandidateFileName[0]); fprintf(CandidateFile, "%d\n", Dimension); for (i = 1; i <= Dimension; i++) { N = &NodeSet[i]; fprintf(CandidateFile, "%d %d", N->Id, N->Dad ? N->Dad->Id : 0); Count = 0; for (NN = N->CandidateSet; NN && NN->To; NN++) Count++; fprintf(CandidateFile, " %d ", Count); for (NN = N->CandidateSet; NN && NN->To; NN++) fprintf(CandidateFile, "%d %d ", NN->To->Id, NN->Alpha); fprintf(CandidateFile, "\n"); } fprintf(CandidateFile, "-1\nEOF\n"); fclose(CandidateFile); if (TraceLevel >= 1) printff("done\n"); }
int ReadCandidates(int MaxCandidates) { FILE *CandidateFile = 0; Node *From, *To; int Dimension, i, j, f, Id, Alpha, Count; if (CandidateFiles == 0 || (CandidateFiles == 1 && !(CandidateFile = fopen(CandidateFileName[0], "r")))) return 0; Dimension = ProblemType != ATSP ? DimensionSaved : 2 * DimensionSaved; for (f = 0; f < CandidateFiles; f++) { if (CandidateFiles >= 2 && !(CandidateFile = fopen(CandidateFileName[f], "r"))) eprintf("Cannot open CANDIDATE_FILE: \"%s\"", CandidateFileName[f]); if (TraceLevel >= 1) printff("Reading CANDIDATE_FILE: \"%s\" ... ", CandidateFileName[f]); fscanint(CandidateFile, &i); if (i != Dimension) eprintf("CANDIDATE_FILE \"%s\" does not match problem", CandidateFileName[f]); for (i = 1; i <= Dimension; i++) { fscanint(CandidateFile, &Id); assert(Id >= 1 && Id <= Dimension); From = &NodeSet[Id]; fscanint(CandidateFile, &Id); assert(Id >= 0 && Id <= Dimension); if (Id > 0) From->Dad = &NodeSet[Id]; assert(From != From->Dad); fscanint(CandidateFile, &Count); assert(Count >= 0 && Count < Dimension); if (!From->CandidateSet) assert(From->CandidateSet = (Candidate *) calloc(Count + 1, sizeof(Candidate))); for (j = 0; j < Count; j++) { fscanint(CandidateFile, &Id); assert(Id >= 1 && Id <= Dimension); To = &NodeSet[Id]; fscanint(CandidateFile, &Alpha); AddCandidate(From, To, D(From, To), Alpha); } } fclose(CandidateFile); if (TraceLevel >= 1) printff("done\n"); } ResetCandidateSet(); if (MaxCandidates > 0) TrimCandidateSet(MaxCandidates); return 1; }
void PrintPopulation() { int i; printff("Population:\n"); for (i = 0; i < PopulationSize; i++) { printff("%3d: " GainFormat, i + 1, Fitness[i]); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Fitness[i] - Optimum) / Optimum); printff("\n"); } }
void LKH::LKHAlg::SolveSubproblemBorderProblems(int Subproblems, GainType * GlobalBestCost) { Node *N; GainType OldGlobalBestCost; int CurrentSubproblem; int *SubproblemSaved; double EntryTime = GetTime(); assert(SubproblemSaved = (int *) malloc((DimensionSaved + 1) * sizeof(int))); /* Compute upper bound for the original problem */ N = FirstNode; do { N->Suc = N->SubproblemSuc; N->Suc->Pred = N; if (N->Subproblem > Subproblems) N->Subproblem -= Subproblems; SubproblemSaved[N->Id] = N->Subproblem; N->FixedTo1Saved = N->FixedTo2Saved = 0; N->SubBestPred = N->SubBestSuc = 0; } while ((N = N->SubproblemSuc) != FirstNode); if (TraceLevel >= 1) printff("\n*** Solve subproblem border problems *** [" GainFormat "]\n", *GlobalBestCost); for (CurrentSubproblem = 1; CurrentSubproblem <= Subproblems; CurrentSubproblem++) { MarkBorderPoints(CurrentSubproblem,this); OldGlobalBestCost = *GlobalBestCost; SolveSubproblem(CurrentSubproblem, Subproblems, GlobalBestCost); if (SubproblemsCompressed && *GlobalBestCost == OldGlobalBestCost) SolveCompressedSubproblem(CurrentSubproblem, Subproblems, GlobalBestCost); N = FirstNode; do N->Subproblem = SubproblemSaved[N->Id]; while ((N = N->SubproblemSuc) != FirstNode); } free(SubproblemSaved); printff("\nCost = " GainFormat, *GlobalBestCost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (*GlobalBestCost - Optimum) / Optimum); printff(", Time = %0.2f sec. %s\n", fabs(GetTime() - EntryTime), *GlobalBestCost < Optimum ? "<" : *GlobalBestCost == Optimum ? "=" : ""); }
static void KarpPartition(int start, int end, int last_mid) { int i; if (end - start + 1 <= SubproblemSize) { if (last_mid <= start) start = last_mid; else end = last_mid; CurrentSubproblem++; for (i = start; i <= end; i++) KDTree[i]->Subproblem = CurrentSubproblem; OldGlobalBestCost = GlobalBestCost; SolveSubproblem(CurrentSubproblem, Subproblems, &GlobalBestCost); if (SubproblemsCompressed && GlobalBestCost == OldGlobalBestCost) { if (TraceLevel >= 1) printff("\nCompress subproblem %d:\n", CurrentSubproblem); RestrictedSearch = 0; SolveSubproblem(CurrentSubproblem, Subproblems, &GlobalBestCost); RestrictedSearch = RestrictedSearchSaved; } } else { int mid = (start + end) / 2; KarpPartition(start, mid - 1, mid); KarpPartition(mid + 1, end, mid); } }
void SolveCompressedSubproblem(int CurrentSubproblem, int Subproblems, GainType * GlobalBestCost) { int Level, Number, RestrictedSearchSaved = RestrictedSearch; GainType OldGlobalBestCost = *GlobalBestCost; Node *N; if ((Number = CurrentSubproblem % Subproblems) == 0) Number = Subproblems; RestrictedSearch = 0; for (Level = 1; Level <= MaxLevel && *GlobalBestCost == OldGlobalBestCost; Level++) { if (TraceLevel >= 1) printff("\nCompress subproblem %d (Level %d):", Number, Level); if (!SolveSubproblem(CurrentSubproblem, Subproblems, GlobalBestCost)) break; } RestrictedSearch = RestrictedSearchSaved; N = FirstNode; do N->Subproblem = abs(N->Subproblem); while ((N = N->Suc) != FirstNode); }
int main(){ int a, sum = 0; printff("enter a no .\n"); scanff("%d",&a); sum = 29 + a; printf("the sumation of this no to 29 is : %d\n",sum); }
void SolveKCenterSubproblems() { Node *N; GainType GlobalBestCost, OldGlobalBestCost; double EntryTime = GetTime(); int CurrentSubproblem, Subproblems; AllocateStructures(); ReadPenalties(); /* Compute upper bound for the original problem */ GlobalBestCost = 0; N = FirstNode; do { if (!Fixed(N, N->SubproblemSuc)) GlobalBestCost += Distance(N, N->SubproblemSuc); N->Subproblem = 0; } while ((N = N->SubproblemSuc) != FirstNode); if (TraceLevel >= 1) { if (TraceLevel >= 2) printff("\n"); printff("*** K-center partitioning *** [Cost = " GainFormat "]\n", GlobalBestCost); } Subproblems = (int) ceil((double) Dimension / SubproblemSize); KCenterClustering(Subproblems); for (CurrentSubproblem = 1; CurrentSubproblem <= Subproblems; CurrentSubproblem++) { OldGlobalBestCost = GlobalBestCost; SolveSubproblem(CurrentSubproblem, Subproblems, &GlobalBestCost); if (SubproblemsCompressed && GlobalBestCost == OldGlobalBestCost) SolveCompressedSubproblem(CurrentSubproblem, Subproblems, &GlobalBestCost); } printff("\nCost = " GainFormat, GlobalBestCost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (GlobalBestCost - Optimum) / Optimum); printff(", Time = %0.2f sec. %s\n", fabs(GetTime() - EntryTime), GlobalBestCost < Optimum ? "<" : GlobalBestCost == Optimum ? "=" : ""); if (SubproblemBorders && Subproblems > 1) SolveSubproblemBorderProblems(Subproblems, &GlobalBestCost); }
int ReadPenalties() { int i, Id; Node *Na, *Nb = 0; static int PenaltiesRead = 0; if(ReadPenaltiesStatic) { PenaltiesRead = 0; ReadPenaltiesStatic = 0; } if (PiFileName == 0) return 0; if (PenaltiesRead || strcmp(PiFileName, "0") == 0) return PenaltiesRead = 1; if (!(PiFile = fopen(PiFileName, "r"))) return 0; if (TraceLevel >= 1) printff("Reading PI_FILE: \"%s\" ... ", PiFileName); fscanint(PiFile, &i); if (i != Dimension) eprintf("PI_FILE \"%s\" does not match problem", PiFileName); fscanint(PiFile, &Id); assert(Id >= 1 && Id <= Dimension); FirstNode = Na = &NodeSet[Id]; fscanint(PiFile, &Na->Pi); for (i = 2; i <= Dimension; i++) { fscanint(PiFile, &Id); assert(Id >= 1 && Id <= Dimension); Nb = &NodeSet[Id]; fscanint(PiFile, &Nb->Pi); Nb->Pred = Na; Na->Suc = Nb; Na = Nb; } FirstNode->Pred = Nb; Nb->Suc = FirstNode; fclose(PiFile); if (TraceLevel >= 1) printff("done\n"); return PenaltiesRead = 1; }
void ApplyCrossover(int i, int j) { int *Pi, *Pj, k; Pi = Population[i]; Pj = Population[j]; for (k = 1; k <= Dimension; k++) { NodeSet[Pi[k - 1]].Suc = &NodeSet[Pi[k]]; NodeSet[Pj[k - 1]].Next = &NodeSet[Pj[k]]; } if (TraceLevel >= 1) printff("Crossover(%d,%d)\n", i + 1, j + 1); /* Apply the crossover operator */ Crossover(); }
static void Read_EDGE_DATA_SECTION() { Node *Ni, *Nj; int i, j; CheckSpecificationPart(); if (!EdgeDataFormat) eprintf("Missing EDGE_DATA_FORMAT specification"); if (!FirstNode) CreateNodes(); if (ProblemType == HPP) Dimension--; if (!fscanint(ProblemFile, &i)) i = -1; while (i != -1) { if (i <= 0 || i > (ProblemType != ATSP ? Dimension : Dimension / 2)) eprintf("(EDGE_DATA_SECTION) Node number out of range: %d", i); fscanint(ProblemFile, &j); if (j == -1 && !strcmp(EdgeDataFormat, "EDGE_LIST")) eprintf("(EDGE_DATA_SECTION) Node number out of range: %d", -1); while (j != -1) { printff("i = %d, j = %d\n", i, j); if (j <= 0 || j > (ProblemType != ATSP ? Dimension : Dimension / 2)) eprintf("(EDGE_DATA_SECTION) Node number out of range: %d", j); if (i == j) eprintf("(EDGE_DATA_SECTION) Illegal edge: %d to %d", i, j); if (ProblemType == ATSP) { i += Dimension / 2; j += Dimension / 2; } Ni = &NodeSet[i]; Nj = &NodeSet[j]; AddCandidate(Ni, Nj, 0, 1); if (ProblemType != ATSP) AddCandidate(Nj, Ni, 0, 1); if (!strcmp(EdgeDataFormat, "EDGE_LIST") || !fscanint(ProblemFile, &j)) j = -1; } if (!fscanint(ProblemFile, &i)) i = -1; } if (ProblemType == HPP) Dimension++; Distance = Distance_1; }
int SolveSubproblem(int CurrentSubproblem, int Subproblems, GainType * GlobalBestCost) { Node *FirstNodeSaved = FirstNode, *N, *Next, *Last = 0; GainType OptimumSaved = Optimum, Cost, Improvement, GlobalCost; double LastTime, Time, ExcessSaved = Excess; int NewDimension = 0, OldDimension = 0, Number, i, InitialTourEdges = 0, AscentCandidatesSaved = AscentCandidates, InitialPeriodSaved = InitialPeriod, MaxTrialsSaved = MaxTrials; BestCost = PLUS_INFINITY; FirstNode = 0; N = FirstNodeSaved; do { if (N->Subproblem == CurrentSubproblem) { if (SubproblemsCompressed && (((N->SubproblemPred == N->SubBestPred || FixedOrCommon(N, N->SubproblemPred) || (N->SubBestPred && (N->FixedTo1Saved == N->SubBestPred || N->FixedTo2Saved == N->SubBestPred))) && (N->SubproblemSuc == N->SubBestSuc || FixedOrCommon(N, N->SubproblemSuc) || (N->SubBestSuc && (N->FixedTo1Saved == N->SubBestSuc || N->FixedTo2Saved == N->SubBestSuc)))) || ((N->SubproblemPred == N->SubBestSuc || FixedOrCommon(N, N->SubproblemPred) || (N->SubBestSuc && (N->FixedTo1Saved == N->SubBestSuc || N->FixedTo2Saved == N->SubBestSuc))) && (N->SubproblemSuc == N->SubBestPred || FixedOrCommon(N, N->SubproblemSuc) || (N->SubBestPred && (N->FixedTo1Saved == N->SubBestPred || N->FixedTo2Saved == N->SubBestPred)))))) N->Subproblem = -CurrentSubproblem; else { if (!FirstNode) FirstNode = N; NewDimension++; } N->Head = N->Tail = 0; if (N->SubBestSuc) OldDimension++; } N->SubBestPred = N->SubBestSuc = 0; N->FixedTo1Saved = N->FixedTo1; N->FixedTo2Saved = N->FixedTo2; } while ((N = N->SubproblemSuc) != FirstNodeSaved); if ((Number = CurrentSubproblem % Subproblems) == 0) Number = Subproblems; if (NewDimension <= 3 || NewDimension == OldDimension) { if (TraceLevel >= 1 && NewDimension <= 3) printff ("\nSubproblem %d of %d: Dimension = %d (too small)\n", Number, Subproblems, NewDimension); FirstNode = FirstNodeSaved; return 0; } if (AscentCandidates > NewDimension - 1) AscentCandidates = NewDimension - 1; if (InitialPeriod < 0) { InitialPeriod = NewDimension / 2; if (InitialPeriod < 100) InitialPeriod = 100; } if (Excess < 0) Excess = 1.0 / NewDimension; if (MaxTrials == -1) MaxTrials = NewDimension; N = FirstNode; do { Next = N->SubproblemSuc; if (N->Subproblem == CurrentSubproblem) { N->Pred = N->Suc = N; if (N != FirstNode) Follow(N, Last); Last = N; } else if (Next->Subproblem == CurrentSubproblem && !Fixed(Last, Next)) { if (!Last->FixedTo1 || Last->FixedTo1->Subproblem != CurrentSubproblem) Last->FixedTo1 = Next; else Last->FixedTo2 = Next; if (!Next->FixedTo1 || Next->FixedTo1->Subproblem != CurrentSubproblem) Next->FixedTo1 = Last; else Next->FixedTo2 = Last; if (C == C_EXPLICIT) { if (Last->Id > Next->Id) Last->C[Next->Id] = 0; else Next->C[Last->Id] = 0; } } } while ((N = Next) != FirstNode); Dimension = NewDimension; AllocateSegments(); InitializeStatistics(); if (CacheSig) for (i = 0; i <= CacheMask; i++) CacheSig[i] = 0; OptimumSaved = Optimum; Optimum = 0; N = FirstNode; do { if (N->SubproblemSuc == N->InitialSuc || N->SubproblemPred == N->InitialSuc) InitialTourEdges++; if (!Fixed(N, N->Suc)) Optimum += Distance(N, N->Suc); if (N->FixedTo1 && N->Subproblem != N->FixedTo1->Subproblem) eprintf("Illegal fixed edge (%d,%d)", N->Id, N->FixedTo1->Id); if (N->FixedTo2 && N->Subproblem != N->FixedTo2->Subproblem) eprintf("Illegal fixed edge (%d,%d)", N->Id, N->FixedTo2->Id); } while ((N = N->Suc) != FirstNode); if (TraceLevel >= 1) printff ("\nSubproblem %d of %d: Dimension = %d, Upper bound = " GainFormat "\n", Number, Subproblems, Dimension, Optimum); FreeCandidateSets(); CreateCandidateSet(); for (Run = 1; Run <= Runs; Run++) { LastTime = GetTime(); Cost = Norm != 0 ? FindTour() : Optimum; /* Merge with subproblem tour */ Last = 0; N = FirstNode; do { if (N->Subproblem == CurrentSubproblem) { if (Last) Last->Next = N; Last = N; } } while ((N = N->SubproblemSuc) != FirstNode); Last->Next = FirstNode; Cost = MergeWithTour(); if (MaxPopulationSize > 1) { /* Genetic algorithm */ for (i = 0; i < PopulationSize; i++) Cost = MergeTourWithIndividual(i); if (!HasFitness(Cost)) { if (PopulationSize < MaxPopulationSize) { AddToPopulation(Cost); if (TraceLevel >= 1) PrintPopulation(); } else if (Cost < Fitness[PopulationSize - 1]) { ReplaceIndividualWithTour(PopulationSize - 1, Cost); if (TraceLevel >= 1) PrintPopulation(); } } } if (Cost < BestCost) { N = FirstNode; do { N->SubBestPred = N->Pred; N->SubBestSuc = N->Suc; } while ((N = N->Suc) != FirstNode); BestCost = Cost; } if (Cost < Optimum || (Cost != Optimum && OutputTourFileName)) { Improvement = Optimum - Cost; if (Improvement > 0) { BestCost = GlobalCost = *GlobalBestCost -= Improvement; Optimum = Cost; } else GlobalCost = *GlobalBestCost - Improvement; N = FirstNode; do N->Mark = 0; while ((N = N->SubproblemSuc) != FirstNode); do { N->Mark = N; if (!N->SubproblemSuc->Mark && (N->Subproblem != CurrentSubproblem || N->SubproblemSuc->Subproblem != CurrentSubproblem)) N->BestSuc = N->SubproblemSuc; else if (!N->SubproblemPred->Mark && (N->Subproblem != CurrentSubproblem || N->SubproblemPred->Subproblem != CurrentSubproblem)) N->BestSuc = N->SubproblemPred; else if (!N->Suc->Mark) N->BestSuc = N->Suc; else if (!N->Pred->Mark) N->BestSuc = N->Pred; else N->BestSuc = FirstNode; } while ((N = N->BestSuc) != FirstNode); Dimension = DimensionSaved; i = 0; do { if (ProblemType != ATSP) BetterTour[++i] = N->Id; else if (N->Id <= Dimension / 2) { i++; if (N->BestSuc->Id != N->Id + Dimension / 2) BetterTour[i] = N->Id; else BetterTour[Dimension / 2 - i + 1] = N->Id; } } while ((N = N->BestSuc) != FirstNode); BetterTour[0] = BetterTour[ProblemType != ATSP ? Dimension : Dimension / 2]; WriteTour(OutputTourFileName, BetterTour, GlobalCost); if (Improvement > 0) { do if (N->Subproblem != CurrentSubproblem) break; while ((N = N->SubproblemPred) != FirstNode); if (N->SubproblemSuc == N->BestSuc) { N = FirstNode; do { N->BestSuc->SubproblemPred = N; N = N->SubproblemSuc = N->BestSuc; } while (N != FirstNode); } else { N = FirstNode; do (N->SubproblemPred = N->BestSuc)->SubproblemSuc = N; while ((N = N->BestSuc) != FirstNode); } RecordBestTour(); WriteTour(TourFileName, BestTour, GlobalCost); } Dimension = NewDimension; if (TraceLevel >= 1) { printff("*** %d: Cost = " GainFormat, Number, GlobalCost); if (OptimumSaved != MINUS_INFINITY && OptimumSaved != 0) printff(", Gap = %04f%%", 100.0 * (GlobalCost - OptimumSaved) / OptimumSaved); printff(", Time = %0.2f sec. %s\n", fabs(GetTime() - LastTime), GlobalCost < OptimumSaved ? "<" : GlobalCost == OptimumSaved ? "=" : ""); } } Time = fabs(GetTime() - LastTime); UpdateStatistics(Cost, Time); if (TraceLevel >= 1 && Cost != PLUS_INFINITY) printff("Run %d: Cost = " GainFormat ", Time = %0.2f sec.\n\n", Run, Cost, Time); if (PopulationSize >= 2 && (PopulationSize == MaxPopulationSize || Run >= 2 * MaxPopulationSize) && Run < Runs) { Node *N; int Parent1, Parent2; Parent1 = LinearSelection(PopulationSize, 1.25); do Parent2 = LinearSelection(PopulationSize, 1.25); while (Parent1 == Parent2); ApplyCrossover(Parent1, Parent2); N = FirstNode; do { int d = C(N, N->Suc); AddCandidate(N, N->Suc, d, INT_MAX); AddCandidate(N->Suc, N, d, INT_MAX); N = N->InitialSuc = N->Suc; } while (N != FirstNode); } SRandom(++Seed); if (Norm == 0) break; } if (TraceLevel >= 1) PrintStatistics(); if (C == C_EXPLICIT) { N = FirstNode; do { for (i = 1; i < N->Id; i++) { N->C[i] -= N->Pi + NodeSet[i].Pi; N->C[i] /= Precision; } if (N->FixedTo1 && N->FixedTo1 != N->FixedTo1Saved) { if (N->Id > N->FixedTo1->Id) N->C[N->FixedTo1->Id] = Distance(N, N->FixedTo1); else N->FixedTo1->C[N->Id] = Distance(N, N->FixedTo1); } if (N->FixedTo2 && N->FixedTo2 != N->FixedTo2Saved) { if (N->Id > N->FixedTo2->Id) N->C[N->FixedTo2->Id] = Distance(N, N->FixedTo2); else N->FixedTo2->C[N->Id] = Distance(N, N->FixedTo2); } } while ((N = N->Suc) != FirstNode); } FreeSegments(); FreeCandidateSets(); FreePopulation(); if (InitialTourEdges == Dimension) { do N->InitialSuc = N->SubproblemSuc; while ((N = N->SubproblemSuc) != FirstNode); } else { do N->InitialSuc = 0; while ((N = N->SubproblemSuc) != FirstNode); } Dimension = ProblemType != ATSP ? DimensionSaved : 2 * DimensionSaved; N = FirstNode = FirstNodeSaved; do { N->Suc = N->BestSuc = N->SubproblemSuc; N->Suc->Pred = N; Next = N->FixedTo1; N->FixedTo1 = N->FixedTo1Saved; N->FixedTo1Saved = Next; Next = N->FixedTo2; N->FixedTo2 = N->FixedTo2Saved; N->FixedTo2Saved = Next; } while ((N = N->Suc) != FirstNode); Optimum = OptimumSaved; Excess = ExcessSaved; AscentCandidates = AscentCandidatesSaved; InitialPeriod = InitialPeriodSaved; MaxTrials = MaxTrialsSaved; return 1; }
int __doprint(FILE* f, char* fmt, va_list vl) { int cnt[2] = { 0, 0 }; // count, file write error indicator int c; int ljust, sign, alt, lzeroes; int width, precision, lmodifier; while ((c = (unsigned char)*fmt++) != '\0') { if (c != '%' || *fmt == '%') { __fputc(c, f, cnt); fmt += (c == '%'); continue; } if ((c = (unsigned char)*fmt++) == '\0') return -1; ljust = sign = alt = lzeroes = 0; for (;;) { if (c == '-') ljust = 1, lzeroes = 0; else if (c == '+') sign = '+'; else if (c == ' ') { if (!sign) sign = ' '; } else if (c == '#') alt = 1; else if (c == '0') { if (!ljust) lzeroes = 1; } else break; if ((c = (unsigned char)*fmt++) == '\0') return -1; } width = -1; if (isdigit(c)) { width = 0; while (isdigit(c)) { width = width * 10 + (c - '0'); // TBD??? overflow check??? if ((c = (unsigned char)*fmt++) == '\0') return -1; } } else if (c == '*') { width = *(int*)vl; vl += sizeof(int); if (width < 0) { ljust = 1; lzeroes = 0; width = -width; // TBD??? overflow check??? } if ((c = *fmt++) == '\0') return -1; } precision = -1; if (c == '.') { if ((c = (unsigned char)*fmt++) == '\0') return -1; precision = 0; if (isdigit(c)) { while (isdigit(c)) { precision = precision * 10 + (c - '0'); // TBD??? overflow check??? if ((c = (unsigned char)*fmt++) == '\0') return -1; } } else if (c == '*') { precision = *(int*)vl; vl += sizeof(int); if ((c = *fmt++) == '\0') return -1; } } lmodifier = 0; if (c == 'h') { if (*fmt == 'h') { fmt++; lmodifier = 'H'; } else { lmodifier = c; } } #ifdef __SMALLER_C_32__ else if (c == 'l' || c == 'L') { lmodifier = c; } #endif else if (strchr("jzt", c)) { lmodifier = c; } if (lmodifier) if ((c = (unsigned char)*fmt++) == '\0') return -1; if (c == 'n') { if (lmodifier == 'H') **(signed char**)vl = cnt[0], vl += sizeof(signed char*); else if (lmodifier == 'h') **(short**)vl = cnt[0], vl += sizeof(short*); else **(int**)vl = cnt[0], vl += sizeof(int*); continue; } if (c == 'i') c = 'd'; #ifdef __SMALLER_C_32__ if (!strchr("douxXcspeEfFgG", c)) return -1; #else if (!strchr("douxXcsp", c)) return -1; #endif if (c == 'c') { int ch = (unsigned char)*(int*)vl; vl += sizeof(int); if (!ljust) while (width > 1) __fputc(' ', f, cnt), width--; __fputc(ch, f, cnt); if (ljust) while (width > 1) __fputc(' ', f, cnt), width--; continue; } else if (c == 's') { char* s = *(char**)vl; int len, i; vl += sizeof(char*); if (!s) s = "(null)"; // Not defined/required by the standard, but helpful if (precision < 0) { len = strlen(s); // TBD??? overflow check??? } else { len = 0; while (len < precision) if (s[len]) len++; else break; } if (!ljust) while (width > len) __fputc(' ', f, cnt), width--; i = len; while (i--) __fputc(*s++, f, cnt); if (ljust) while (width > len) __fputc(' ', f, cnt), width--; continue; } #ifdef __SMALLER_C_32__ else if (strchr("eEfFgG", c)) { float v = *(float*)vl; vl += sizeof(v); printff(v, ljust, sign, alt, lzeroes, width, precision, c, f, cnt); continue; } #endif else { unsigned v = *(unsigned*)vl, tmp; char s[11]; // up to 11 octal digits in 32-bit numbers char* p = s + sizeof s; unsigned base = (c == 'p') ? 16 : 10; char* digits = "0123456789abcdef"; char* hexpfx = NULL; int dcnt; int len; vl += sizeof(unsigned); if (precision >= 0) lzeroes = 0; if (c == 'o') base = 8; else if (toupper(c) == 'X') { base = 16; if (c == 'X') digits = "0123456789ABCDEF"; if (alt && v) hexpfx = (c == 'X') ? "0X" : "0x"; } if (c != 'd') { if (lmodifier == 'H') v = (unsigned char)v; else if (lmodifier == 'h') v = (unsigned short)v; sign = 0; } else { if (lmodifier == 'H') v = (signed char)v; else if (lmodifier == 'h') v = (short)v; if ((int)v < 0) v = -v, sign = '-'; } tmp = v; do { *--p = digits[tmp % base]; tmp /= base; } while (tmp); dcnt = s + sizeof s - p; if (precision < 0) precision = 1; else if (v == 0 && precision == 0) dcnt = 0; if (alt && c == 'o') if ((v == 0 && precision == 0) || (v && precision <= dcnt)) precision = dcnt + 1; if (precision < dcnt) precision = dcnt; // width padding: // - left/right // - spaces/zeroes (zeroes are to appear after sign/base prefix) // sign: // - '-' if negative // - '+' or '-' always // - space if non-negative or empty // alt: // - octal: prefix 0 to conversion if non-zero or empty // - hex: prefix "0x"/"0X" to conversion if non-zero // precision: // - prefix conversion digits with zeroes to precision // - special case: 0 with precision=0 results in empty conversion // [leading spaces] [sign/hex prefix] [leading zeroes] [(precision-dcnt) zeroes] [dcnt digits] [trailing spaces] len = (sign != 0) + (hexpfx != NULL) * 2 + precision; if (!ljust && !lzeroes) while (width > len) __fputc(' ', f, cnt), width--; if (sign) __fputc(sign, f, cnt); else if (hexpfx) __fputc(hexpfx[0], f, cnt), __fputc(hexpfx[1], f, cnt); if (!ljust && lzeroes) while (width > len) __fputc('0', f, cnt), width--; while (precision-- > dcnt) __fputc('0', f, cnt); while (dcnt--) __fputc(*p++, f, cnt); if (ljust) while (width > len) __fputc(' ', f, cnt), width--; continue; } } return cnt[1] ? -1 : cnt[0]; }
int main(int argc, char *argv[]) { GainType Cost; double Time, LastTime = GetTime(); /* Read the specification of the problem */ if (argc >= 2) ParameterFileName = argv[1]; ReadParameters(); MaxMatrixDimension = 10000; ReadProblem(); if (SubproblemSize > 0) { if (DelaunayPartitioning) SolveDelaunaySubproblems(); else if (KarpPartitioning) SolveKarpSubproblems(); else if (KCenterPartitioning) SolveKCenterSubproblems(); else if (KMeansPartitioning) SolveKMeansSubproblems(); else if (RohePartitioning) SolveRoheSubproblems(); else if (MoorePartitioning || SierpinskiPartitioning) SolveSFCSubproblems(); else SolveTourSegmentSubproblems(); return EXIT_SUCCESS; } AllocateStructures(); CreateCandidateSet(); InitializeStatistics(); if (Norm != 0) BestCost = PLUS_INFINITY; else { /* The ascent has solved the problem! */ Optimum = BestCost = (GainType) LowerBound; UpdateStatistics(Optimum, GetTime() - LastTime); RecordBetterTour(); RecordBestTour(); WriteTour(OutputTourFileName, BestTour, BestCost); WriteTour(TourFileName, BestTour, BestCost); Runs = 0; } /* Find a specified number (Runs) of local optima */ for (Run = 1; Run <= Runs; Run++) { LastTime = GetTime(); Cost = FindTour(); /* using the Lin-Kernighan heuristic */ if (MaxPopulationSize > 1) { /* Genetic algorithm */ int i; for (i = 0; i < PopulationSize; i++) { GainType OldCost = Cost; Cost = MergeTourWithIndividual(i); if (TraceLevel >= 1 && Cost < OldCost) { printff(" Merged with %d: Cost = " GainFormat, i + 1, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Cost - Optimum) / Optimum); printff("\n"); } } if (!HasFitness(Cost)) { if (PopulationSize < MaxPopulationSize) { AddToPopulation(Cost); if (TraceLevel >= 1) PrintPopulation(); } else if (Cost < Fitness[PopulationSize - 1]) { i = ReplacementIndividual(Cost); ReplaceIndividualWithTour(i, Cost); if (TraceLevel >= 1) PrintPopulation(); } } } else if (Run > 1) Cost = MergeBetterTourWithBestTour(); if (Cost < BestCost) { BestCost = Cost; RecordBetterTour(); RecordBestTour(); WriteTour(OutputTourFileName, BestTour, BestCost); WriteTour(TourFileName, BestTour, BestCost); } if (Cost < Optimum) { if (FirstNode->InputSuc) { Node *N = FirstNode; while ((N = N->InputSuc = N->Suc) != FirstNode); } Optimum = Cost; printff("*** New optimum = " GainFormat " ***\n\n", Optimum); } Time = fabs(GetTime() - LastTime); UpdateStatistics(Cost, Time); if (TraceLevel >= 1 && Cost != PLUS_INFINITY) { printff("Run %d: Cost = " GainFormat, Run, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Cost - Optimum) / Optimum); printff(", Time = %0.2f sec. %s\n\n", Time, Cost < Optimum ? "<" : Cost == Optimum ? "=" : ""); } if (PopulationSize >= 2 && (PopulationSize == MaxPopulationSize || Run >= 2 * MaxPopulationSize) && Run < Runs) { Node *N; int Parent1, Parent2; Parent1 = LinearSelection(PopulationSize, 1.25); do Parent2 = LinearSelection(PopulationSize, 1.25); while (Parent2 == Parent1); ApplyCrossover(Parent1, Parent2); N = FirstNode; do { int d = C(N, N->Suc); AddCandidate(N, N->Suc, d, INT_MAX); AddCandidate(N->Suc, N, d, INT_MAX); N = N->InitialSuc = N->Suc; } while (N != FirstNode); } SRandom(++Seed); } PrintStatistics(); return EXIT_SUCCESS; }
void LKH::LKHAlg::GenerateCandidates(int MaxCandidates, GainType MaxAlpha, int Symmetric) { Node *From, *To; Candidate *NFrom, *NN; int a, d, Count; if (TraceLevel >= 2) printff("Generating candidates ... "); if (MaxAlpha < 0 || MaxAlpha > INT_MAX) MaxAlpha = INT_MAX; /* Initialize CandidateSet for each node */ FreeCandidateSets(); From = FirstNode; do From->Mark = 0; while ((From = From->Suc) != FirstNode); if (MaxCandidates > 0) { do { assert(From->CandidateSet = (Candidate *) malloc((MaxCandidates + 1) * sizeof(Candidate))); From->CandidateSet[0].To = 0; } while ((From = From->Suc) != FirstNode); } else { AddTourCandidates(); do { if (!From->CandidateSet) eprintf("MAX_CANDIDATES = 0: No candidates"); } while ((From = From->Suc) != FirstNode); return; } /* Loop for each node, From */ do { NFrom = From->CandidateSet; if (From != FirstNode) { From->Beta = INT_MIN; for (To = From; To->Dad != 0; To = To->Dad) { To->Dad->Beta = !FixedOrCommon(To, To->Dad) ? Max(To->Beta, To->Cost) : To->Beta; To->Dad->Mark = From; } } Count = 0; /* Loop for each node, To */ To = FirstNode; do { if (To == From) continue; d = c && !FixedOrCommon(From, To) ? (this->*c)(From, To) : (this->*D)(From, To); if (From == FirstNode) a = To == From->Dad ? 0 : d - From->NextCost; else if (To == FirstNode) a = From == To->Dad ? 0 : d - To->NextCost; else { if (To->Mark != From) To->Beta = !FixedOrCommon(To, To->Dad) ? Max(To->Dad->Beta, To->Cost) : To->Dad->Beta; a = d - To->Beta; } if (FixedOrCommon(From, To)) a = INT_MIN; else { if (From->FixedTo2 || To->FixedTo2 || Forbidden(From, To)) continue; if (InInputTour(From, To)) { a = 0; if (c) d = (this->*D)(From, To); } else if (c) { if (a > MaxAlpha || (Count == MaxCandidates && (a > (NFrom - 1)->Alpha || (a == (NFrom - 1)->Alpha && d >= (NFrom - 1)->Cost)))) continue; if (To == From->Dad) { d = From->Cost; a = 0; } else if (From == To->Dad) { d = To->Cost; a = 0; } else { a -= d; a += (d = (this->*D)(From, To)); } } } if (a <= MaxAlpha && IsPossibleCandidate(From, To)) { /* Insert new candidate edge in From->CandidateSet */ NN = NFrom; while (--NN >= From->CandidateSet) { if (a > NN->Alpha || (a == NN->Alpha && d >= NN->Cost)) break; *(NN + 1) = *NN; } NN++; NN->To = To; NN->Cost = d; NN->Alpha = a; if (Count < MaxCandidates) { Count++; NFrom++; } NFrom->To = 0; } } while ((To = To->Suc) != FirstNode); } while ((From = From->Suc) != FirstNode); AddTourCandidates(); if (Symmetric) SymmetrizeCandidateSet(); if (TraceLevel >= 2) printff("done\n"); }
void ReadParameters() { char *Line, *Keyword, *Token, *Name; unsigned int i; ProblemFileName = PiFileName = InputTourFileName = OutputTourFileName = TourFileName = 0; CandidateFiles = MergeTourFiles = 0; AscentCandidates = 50; BackboneTrials = 0; Backtracking = 0; CandidateSetSymmetric = 0; CandidateSetType = ALPHA; Crossover = ERXT; DelaunayPartitioning = 0; DelaunayPure = 0; Excess = -1; ExtraCandidates = 0; ExtraCandidateSetSymmetric = 0; ExtraCandidateSetType = QUADRANT; Gain23Used = 1; GainCriterionUsed = 1; InitialPeriod = -1; InitialStepSize = 0; InitialTourAlgorithm = WALK; InitialTourFraction = 1.0; KarpPartitioning = 0; KMeansPartitioning = 0; Kicks = 1; KickType = 0; MaxBreadth = INT_MAX; MaxCandidates = 5; MaxPopulationSize = 0; MaxSwaps = -1; MaxTrials = -1; MoorePartitioning = 0; MoveType = 5; NonsequentialMoveType = -1; Optimum = MINUS_INFINITY; PatchingA = 1; PatchingC = 0; PatchingAExtended = 0; PatchingARestricted = 0; PatchingCExtended = 0; PatchingCRestricted = 0; Precision = 100; RestrictedSearch = 1; RohePartitioning = 0; Runs = 0; Seed = 1; SierpinskiPartitioning = 0; StopAtOptimum = 1; Subgradient = 1; SubproblemBorders = 0; SubproblemsCompressed = 0; SubproblemSize = 0; SubsequentMoveType = 0; SubsequentPatching = 1; TimeLimit = DBL_MAX; TraceLevel = 1; if (ParameterFileName) { if (!(ParameterFile = fopen(ParameterFileName, "r"))) eprintf("Cannot open PARAMETER_FILE: \"%s\"", ParameterFileName); printff("PARAMETER_FILE = %s\n", ParameterFileName); } else { while (1) { printff("PARAMETER_FILE = "); if (!(ParameterFileName = GetFileName(ReadLine(stdin)))) { do { printff("PROBLEM_FILE = "); ProblemFileName = GetFileName(ReadLine(stdin)); } while (!ProblemFileName); return; } else if (!(ParameterFile = fopen(ParameterFileName, "r"))) printff("Cannot open \"%s\". Please try again.\n", ParameterFileName); else break; } } while ((Line = ReadLine(ParameterFile))) { if (!(Keyword = strtok(Line, Delimiters))) continue; if (Keyword[0] == '#') continue; for (i = 0; i < strlen(Keyword); i++) Keyword[i] = (char) toupper(Keyword[i]); if (!strcmp(Keyword, "ASCENT_CANDIDATES")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &AscentCandidates)) eprintf("ASCENT_CANDIDATES: integer expected"); if (AscentCandidates < 2) eprintf("ASCENT_CANDIDATES: >= 2 expected"); } else if (!strcmp(Keyword, "BACKBONE_TRIALS")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &BackboneTrials)) eprintf("BACKBONE_TRIALS: integer expected"); if (BackboneTrials < 0) eprintf("BACKBONE_TRIALS: non-negative integer expected"); } else if (!strcmp(Keyword, "BACKTRACKING")) { if (!ReadYesOrNo(&Backtracking)) eprintf("RESTRICTED_SEARCH: YES or NO expected"); } else if (!strcmp(Keyword, "CANDIDATE_FILE")) { if (!(Name = GetFileName(0))) eprintf("CANDIDATE_FILE: string expected"); if (CandidateFiles == 0) { assert(CandidateFileName = (char **) malloc(sizeof(char *))); CandidateFileName[CandidateFiles++] = Name; } else { int i; for (i = 0; i < CandidateFiles; i++) if (!strcmp(Name, CandidateFileName[i])) break; if (i == CandidateFiles) { assert(CandidateFileName = (char **) realloc(CandidateFileName, (CandidateFiles + 1) * sizeof(char *))); CandidateFileName[CandidateFiles++] = Name; } } } else if (!strcmp(Keyword, "CANDIDATE_SET_TYPE")) { if (!(Token = strtok(0, Delimiters))) eprintf("%s", "CANDIDATE_SET_TYPE: " "ALPHA, DELAUNAY, NEAREST-NEIGHBOR, " "or QUADRANT expected"); for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (!strncmp(Token, "ALPHA", strlen(Token))) CandidateSetType = ALPHA; else if (!strncmp(Token, "DELAUNAY", strlen(Token))) { CandidateSetType = DELAUNAY; } else if (!strncmp(Token, "NEAREST-NEIGHBOR", strlen(Token))) CandidateSetType = NN; else if (!strncmp(Token, "QUADRANT", strlen(Token))) CandidateSetType = QUADRANT; else eprintf("%s", "CANDIDATE_SET_TYPE: " "ALPHA, DELAUNAY, NEAREST-NEIGHBOR, " "or QUADRANT expected"); if (CandidateSetType == DELAUNAY) { if ((Token = strtok(0, Delimiters))) { for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (strncmp(Token, "PURE", strlen(Token))) eprintf("%s", "CANDIDATE_SET_TYPE (DELAUNAY): " "PURE or no token expected"); DelaunayPure = 1; } } } else if (!strcmp(Keyword, "COMMENT")) continue; else if (!strcmp(Keyword, "EOF")) break; else if (!strcmp(Keyword, "EXCESS")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%lf", &Excess)) eprintf("EXCESS: real expected"); if (Excess < 0) eprintf("EXCESS: non-negeative real expected"); } else if (!strcmp(Keyword, "EXTRA_CANDIDATES")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &ExtraCandidates)) eprintf("EXTRA_CANDIDATES: integer expected"); if (ExtraCandidates < 0) eprintf("EXTRA_CANDIDATES: non-negative integer expected"); if ((Token = strtok(0, Delimiters))) { for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (strncmp(Token, "SYMMETRIC", strlen(Token))) eprintf ("(EXTRA_CANDIDATES) Illegal SYMMETRIC specification"); ExtraCandidateSetSymmetric = 1; } } else if (!strcmp(Keyword, "EXTRA_CANDIDATE_SET_TYPE")) { if (!(Token = strtok(0, Delimiters))) eprintf("%s", "EXTRA_CANDIDATE_SET_TYPE: " "NEAREST-NEIGHBOR, or QUADRANT expected"); for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (!strncmp(Token, "NEAREST-NEIGHBOR", strlen(Token))) ExtraCandidateSetType = NN; else if (!strncmp(Token, "QUADRANT", strlen(Token))) ExtraCandidateSetType = QUADRANT; else eprintf("%s", "EXTRA_CANDIDATE_SET_TYPE: " "NEAREST-NEIGHBOR or QUADRANT expected"); } else if (!strcmp(Keyword, "GAIN23")) { if (!ReadYesOrNo(&Gain23Used)) eprintf("GAIN23: YES or NO expected"); } else if (!strcmp(Keyword, "GAIN_CRITERION")) { if (!ReadYesOrNo(&GainCriterionUsed)) eprintf("GAIN_CRITERION: YES or NO expected"); } else if (!strcmp(Keyword, "INITIAL_PERIOD")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &InitialPeriod)) eprintf("INITIAL_PERIOD: integer expected"); if (InitialPeriod < 0) eprintf("INITIAL_PERIOD: non-negative integer expected"); } else if (!strcmp(Keyword, "INITIAL_STEP_SIZE")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &InitialStepSize)) eprintf("INITIAL_STEP_SIZE: integer expected"); if (InitialStepSize <= 0) eprintf("INITIAL_STEP_SIZE: positive integer expected"); } else if (!strcmp(Keyword, "INITIAL_TOUR_ALGORITHM")) { if (!(Token = strtok(0, Delimiters))) eprintf("INITIAL_TOUR_ALGORITHM: " "BORUVKA, GREEDY, MOORE, NEAREST-NEIGHBOR,\n" "QUICK-BORUVKA, SIERPINSKI, or WALK expected"); for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (!strncmp(Token, "BORUVKA", strlen(Token))) InitialTourAlgorithm = BORUVKA; else if (!strncmp(Token, "GREEDY", strlen(Token))) InitialTourAlgorithm = GREEDY; else if (!strncmp(Token, "MOORE", strlen(Token))) InitialTourAlgorithm = MOORE; else if (!strncmp(Token, "NEAREST-NEIGHBOR", strlen(Token))) InitialTourAlgorithm = NEAREST_NEIGHBOR; else if (!strncmp(Token, "QUICK-BORUVKA", strlen(Token))) InitialTourAlgorithm = QUICK_BORUVKA; else if (!strncmp(Token, "SIERPINSKI", strlen(Token))) InitialTourAlgorithm = SIERPINSKI; else if (!strncmp(Token, "WALK", strlen(Token))) InitialTourAlgorithm = WALK; else eprintf("INITIAL_TOUR_ALGORITHM: " "BORUVKA, GREEDY, MOORE, NEAREST-NEIGHBOR,\n" "QUICK-BORUVKA, SIERPINSKI or WALK expected"); } else if (!strcmp(Keyword, "INITIAL_TOUR_FILE")) { if (!(InitialTourFileName = GetFileName(0))) eprintf("INITIAL_TOUR_FILE: string expected"); } else if (!strcmp(Keyword, "INITIAL_TOUR_FRACTION")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%lf", &InitialTourFraction)) eprintf("INITIAL_TOUR_FRACTION: real expected"); if (InitialTourFraction < 0 || InitialTourFraction > 1) eprintf("INITIAL_TOUR_FRACTION: >= 0 or <= 1 expected"); } else if (!strcmp(Keyword, "INPUT_TOUR_FILE")) { if (!(InputTourFileName = GetFileName(0))) eprintf("INPUT_TOUR_FILE: string expected"); } else if (!strcmp(Keyword, "KICK_TYPE")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &KickType)) eprintf("KICK_TYPE: integer expected"); if (KickType != 0 && KickType < 4) eprintf("KICK_TYPE: integer >= 4 expected"); } else if (!strcmp(Keyword, "KICKS")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &Kicks)) eprintf("KICKS: integer expected"); if (Kicks < 0) eprintf("KICKS: non-negative integer expected"); } else if (!strcmp(Keyword, "MAX_BREADTH")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &MaxBreadth)) eprintf("MAX_BREADTH: integer expected"); if (MaxBreadth < 0) eprintf("MAX_BREADTH: non-negative integer expected"); } else if (!strcmp(Keyword, "MAX_CANDIDATES")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &MaxCandidates)) eprintf("MAX_CANDIDATES: integer expected"); if (MaxCandidates < 0) eprintf("MAX_CANDIDATES: non-negative integer expected"); if ((Token = strtok(0, Delimiters))) { for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (!strncmp(Token, "SYMMETRIC", strlen(Token))) CandidateSetSymmetric = 1; else eprintf ("(MAX_CANDIDATES) Illegal SYMMETRIC specification"); } } else if (!strcmp(Keyword, "MAX_SWAPS")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &MaxSwaps)) eprintf("MAX_SWAPS: integer expected"); if (MaxSwaps < 0) eprintf("MAX_SWAPS: non-negative integer expected"); } else if (!strcmp(Keyword, "MAX_TRIALS")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &MaxTrials)) eprintf("MAX_TRIALS: integer expected"); if (MaxTrials < 0) eprintf("MAX_TRIALS: non-negative integer expected"); } else if (!strcmp(Keyword, "MERGE_TOUR_FILE")) { if (!(Name = GetFileName(0))) eprintf("MERGE_TOUR_FILE: string expected"); if (MergeTourFiles == 0) { assert(MergeTourFileName = (char **) malloc(sizeof(char *))); MergeTourFileName[MergeTourFiles++] = Name; } else { int i; for (i = 0; i < MergeTourFiles; i++) if (!strcmp(Name, MergeTourFileName[i])) break; if (i == MergeTourFiles) { assert(MergeTourFileName = (char **) realloc(MergeTourFileName, (MergeTourFiles + 1) * sizeof(char *))); MergeTourFileName[MergeTourFiles++] = Name; } } } else if (!strcmp(Keyword, "MOVE_TYPE")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &MoveType)) eprintf("MOVE_TYPE: integer expected"); if (MoveType < 2) eprintf("MOVE_TYPE: >= 2 expected"); } else if (!strcmp(Keyword, "NONSEQUENTIAL_MOVE_TYPE")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &NonsequentialMoveType)) eprintf("NONSEQUENTIAL_MOVE_TYPE: integer expected"); if (NonsequentialMoveType < 4) eprintf("NONSEQUENTIAL_MOVE_TYPE: >= 4 expected"); } else if (!strcmp(Keyword, "OPTIMUM")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, GainInputFormat, &Optimum)) eprintf("OPTIMUM: integer expected"); } else if (!strcmp(Keyword, "OUTPUT_TOUR_FILE")) { if (!(OutputTourFileName = GetFileName(0))) eprintf("OUTPUT_TOUR_FILE: string expected"); } else if (!strcmp(Keyword, "PATCHING_A")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &PatchingA)) eprintf("PATCHING_A: integer expected"); if (PatchingA < 0) eprintf("PATCHING_A: non-negative integer expected"); if ((Token = strtok(0, Delimiters))) { for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (!strncmp(Token, "RESTRICTED", strlen(Token))) PatchingARestricted = 1; else if (!strncmp(Token, "EXTENDED", strlen(Token))) PatchingAExtended = 1; else eprintf("%s", "(PATCHING_A) " "Illegal RESTRICTED or EXTENDED specification"); } } else if (!strcmp(Keyword, "PATCHING_C")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &PatchingC)) eprintf("PATCHING_C: integer expected"); if (PatchingC < 0) eprintf("PATCHING_C: non-negative integer expected"); if ((Token = strtok(0, Delimiters))) { for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (!strncmp(Token, "RESTRICTED", strlen(Token))) PatchingCRestricted = 1; else if (!strncmp(Token, "EXTENDED", strlen(Token))) PatchingCExtended = 1; else eprintf("%s", "(PATCHING_C) ", "Illegal RESTRICTED or EXTENDED specification"); } } else if (!strcmp(Keyword, "PI_FILE")) { if (!(PiFileName = GetFileName(0))) eprintf("PI_FILE: string expected"); } else if (!strcmp(Keyword, "POPULATION_SIZE")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &MaxPopulationSize)) eprintf("POPULATION_SIZE: integer expected"); } else if (!strcmp(Keyword, "PRECISION")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &Precision)) eprintf("PRECISION: integer expected"); } else if (!strcmp(Keyword, "PROBLEM_FILE")) { if (!(ProblemFileName = GetFileName(0))) eprintf("PROBLEM_FILE: string expected"); } else if (!strcmp(Keyword, "RESTRICTED_SEARCH")) { if (!ReadYesOrNo(&RestrictedSearch)) eprintf("RESTRICTED_SEARCH: YES or NO expected"); } else if (!strcmp(Keyword, "RUNS")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &Runs)) eprintf("RUNS: integer expected"); if (Runs <= 0) eprintf("RUNS: positive integer expected"); } else if (!strcmp(Keyword, "SEED")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%u", &Seed)) eprintf("SEED: integer expected"); } else if (!strcmp(Keyword, "STOP_AT_OPTIMUM")) { if (!ReadYesOrNo(&StopAtOptimum)) eprintf("STOP_AT_OPTIMUM: YES or NO expected"); } else if (!strcmp(Keyword, "SUBGRADIENT")) { if (!ReadYesOrNo(&Subgradient)) eprintf("SUBGRADIENT: YES or NO expected"); } else if (!strcmp(Keyword, "SUBPROBLEM_TOUR_FILE")) { if (!(SubproblemTourFileName = GetFileName(0))) eprintf("SUBPROBLEM_TOUR_FILE: string expected"); } else if (!strcmp(Keyword, "SUBPROBLEM_SIZE")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &SubproblemSize)) eprintf("SUBPROBLEM_SIZE: integer expected"); if (SubproblemSize < 3) eprintf("SUBPROBLEM_SIZE: >= 3 expected"); if ((Token = strtok(0, Delimiters))) { for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (!strncmp(Token, "DELAUNAY", strlen(Token))) DelaunayPartitioning = 1; else if (!strncmp(Token, "KARP", max(strlen(Token), 2))) KarpPartitioning = 1; else if (!strncmp(Token, "K-MEANS", max(strlen(Token), 2))) KMeansPartitioning = 1; else if (!strncmp(Token, "MOORE", strlen(Token))) MoorePartitioning = 1; else if (!strncmp(Token, "ROHE", strlen(Token))) RohePartitioning = 1; else if (!strncmp(Token, "SIERPINSKI", strlen(Token))) SierpinskiPartitioning = 1; else if (!strncmp(Token, "BORDERS", strlen(Token))) SubproblemBorders = 1; else if (!strncmp(Token, "COMPRESSED", strlen(Token))) SubproblemsCompressed = 1; else eprintf ("(SUBPROBLEM_SIZE) Illegal DELAUNAY, KARP, K-MEANS, " "MOORE, ROHE,\n SIERPINSKI, BORDERS or COMPRESSED " "specification"); while ((Token = strtok(0, Delimiters))) { for (i = 0; i < strlen(Token); i++) Token[i] = (char) toupper(Token[i]); if (!strncmp(Token, "BORDERS", strlen(Token))) SubproblemBorders = 1; else if (!strncmp(Token, "COMPRESSED", strlen(Token))) SubproblemsCompressed = 1; else eprintf ("(SUBPROBLEM_SIZE) Illegal BORDERS or " "COMPRESSED specification"); } } } else if (!strcmp(Keyword, "SUBSEQUENT_MOVE_TYPE")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &SubsequentMoveType)) eprintf("SUBSEQUENT_MOVE_TYPE: integer expected"); if (SubsequentMoveType != 0 && SubsequentMoveType < 2) eprintf("SUBSEQUENT_MOVE_TYPE: 0 or >= 2 expected"); } else if (!strcmp(Keyword, "SUBSEQUENT_PATCHING")) { if (!ReadYesOrNo(&SubsequentPatching)) eprintf("SUBSEQUENT_PATCHING: YES or NO expected"); } else if (!strcmp(Keyword, "TIME_LIMIT")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%lf", &TimeLimit)) eprintf("TIME_LIMIT: real expected"); if (TimeLimit < 0) eprintf("TIME_LIMIT: >= 0 expected"); } else if (!strcmp(Keyword, "TOUR_FILE")) { if (!(TourFileName = GetFileName(0))) eprintf("TOUR_FILE: string expected"); } else if (!strcmp(Keyword, "TRACE_LEVEL")) { if (!(Token = strtok(0, Delimiters)) || !sscanf(Token, "%d", &TraceLevel)) eprintf("TRACE_LEVEL: integer expected"); } else eprintf("Unknown keyword: %s", Keyword); if ((Token = strtok(0, Delimiters))) eprintf("Junk at end of line: %s", Token); } if (!ProblemFileName) eprintf("Problem file name is missing"); if (SubproblemSize == 0 && SubproblemTourFileName != 0) eprintf("SUBPROBLEM_SIZE specification is missing"); if (SubproblemSize > 0 && SubproblemTourFileName == 0) eprintf("SUBPROBLEM_TOUR_FILE specification is missing"); fclose(ParameterFile); free(LastLine); LastLine = 0; }
void _start(void){ while(1){ sleep(255,10); printff("hello papaya..\n"); } }
void SolveKarpSubproblems() { Node *N; int i; double EntryTime = GetTime(); AllocateStructures(); ReadPenalties(); /* Compute upper bound for the original problem */ GlobalBestCost = 0; N = FirstNode; do { if (!Fixed(N, N->SubproblemSuc)) GlobalBestCost += Distance(N, N->SubproblemSuc); N->Subproblem = 0; } while ((N = N->BestSuc = N->SubproblemSuc) != FirstNode); if (TraceLevel >= 1) { if (TraceLevel >= 2) printff("\n"); printff("*** Karp partitioning *** [Cost = " GainFormat "]\n", GlobalBestCost); } if (WeightType == GEO || WeightType == GEOM || WeightType == GEO_MEEUS || WeightType == GEOM_MEEUS) { N = FirstNode; do { N->Xc = N->X; N->Yc = N->Y; N->Zc = N->Z; if (WeightType == GEO || WeightType == GEO_MEEUS) GEO2XYZ(N->Xc, N->Yc, &N->X, &N->Y, &N->Z); else GEOM2XYZ(N->Xc, N->Yc, &N->X, &N->Y, &N->Z); } while ((N = N->SubproblemSuc) != FirstNode); CoordType = THREED_COORDS; } KDTree = BuildKDTree(); if (WeightType == GEO || WeightType == GEOM || WeightType == GEO_MEEUS || WeightType == GEOM_MEEUS) { N = FirstNode; do { N->X = N->Xc; N->Y = N->Yc; N->Z = N->Zc; } while ((N = N->SubproblemSuc) != FirstNode); CoordType = TWOD_COORDS; } CurrentSubproblem = 0; Subproblems = 1; for (i = Dimension - 1; i > SubproblemSize; i /= 2) Subproblems *= 2; RestrictedSearchSaved = RestrictedSearch; KarpPartition(0, Dimension - 1, 0); free(KDTree); printff("\nCost = " GainFormat, GlobalBestCost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.3f%%", 100.0 * (GlobalBestCost - Optimum) / Optimum); printff(", Time = %0.1f sec. %s\n", fabs(GetTime() - EntryTime), GlobalBestCost < Optimum ? "<" : GlobalBestCost == Optimum ? "=" : ""); if (SubproblemBorders && Subproblems > 1) SolveSubproblemBorderProblems(Subproblems); }
void CreateNearestNeighborCandidateSet(int K) { Node *From, *To; int i; if (TraceLevel >= 2) printff("Creating nearest neighbor candidate set ... "); KDTree = BuildKDTree(1); assert(XMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(XMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(YMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(YMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); if (CoordType == THREED_COORDS) { assert(ZMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(ZMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); } ComputeBounds(0, Dimension - 1); Contains = CoordType == THREED_COORDS ? Contains3D : Contains2D; BoxOverlaps = CoordType == THREED_COORDS ? BoxOverlaps3D : BoxOverlaps2D; assert(CandidateSet = (Candidate *) malloc((K + 1) * sizeof(Candidate))); From = FirstNode; do { NearestQuadrantNeighbors(From, 0, K); for (i = 0; i < Candidates; i++) { To = CandidateSet[i].To; AddCandidate(From, To, D(From, To), 1); } } while ((From = From->Suc) != FirstNode); free(CandidateSet); free(KDTree); free(XMin); free(XMax); free(YMin); free(YMax); if (CoordType == THREED_COORDS) { free(ZMin); free(ZMax); } if (Level == 0 && (WeightType == GEOM || WeightType == GEOM_MEEUS)) { Candidate **SavedCandidateSet; assert(SavedCandidateSet = (Candidate **) malloc((1 + DimensionSaved) * sizeof(Candidate *))); if (TraceLevel >= 2) printff("done\n"); /* Transform longitude (180 and -180 map to 0) */ From = FirstNode; do { SavedCandidateSet[From->Id] = From->CandidateSet; From->CandidateSet = 0; From->Yc = From->Y; From->Y += From->Y > 0 ? -180 : 180; } while ((From = From->Suc) != FirstNode); Level++; CreateNearestNeighborCandidateSet(K); Level--; From = FirstNode; do From->Y = From->Yc; while ((From = From->Suc) != FirstNode); do { Candidate *QCandidateSet = From->CandidateSet; Candidate *NFrom; From->CandidateSet = SavedCandidateSet[From->Id]; for (NFrom = QCandidateSet; (To = NFrom->To); NFrom++) AddCandidate(From, To, NFrom->Cost, NFrom->Alpha); free(QCandidateSet); } while ((From = From->Suc) != FirstNode); free(SavedCandidateSet); } if (Level == 0) { ResetCandidateSet(); AddTourCandidates(); if (CandidateSetSymmetric) SymmetrizeCandidateSet(); if (TraceLevel >= 2) printff("done\n"); } }
void CreateQuadrantCandidateSet(int K) { Node *From, *To; Candidate *NFrom; int L, Q, CandPerQ, Added, Count, i; if (K <= 0) return; if (TraceLevel >= 2) printff("Creating quadrant candidate set ... "); KDTree = BuildKDTree(1); assert(XMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(XMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(YMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(YMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); if (CoordType == THREED_COORDS) { assert(ZMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(ZMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); } ComputeBounds(0, Dimension - 1); Contains = CoordType == THREED_COORDS ? Contains3D : Contains2D; BoxOverlaps = CoordType == THREED_COORDS ? BoxOverlaps3D : BoxOverlaps2D; L = CoordType == THREED_COORDS ? 8 : 4; CandPerQ = K / L; assert(CandidateSet = (Candidate *) malloc((K + 1) * sizeof(Candidate))); From = FirstNode; do { Count = 0; for (NFrom = From->CandidateSet; NFrom && NFrom->To; NFrom++) if (FixedOrCommon(From, NFrom->To) && ++Count == 2) break; if (Count == 2) continue; Added = 0; for (Q = 1; Q <= L; Q++) { NearestQuadrantNeighbors(From, Q, CandPerQ); for (i = 0; i < Candidates; i++) { To = CandidateSet[i].To; if (AddCandidate(From, To, D(From, To), 1)) Added++; } } if (K > Added) { NearestQuadrantNeighbors(From, 0, K - Added); for (i = 0; i < Candidates; i++) { To = CandidateSet[i].To; AddCandidate(From, To, D(From, To), 2); } } } while ((From = From->Suc) != FirstNode); free(CandidateSet); free(KDTree); free(XMin); free(XMax); free(YMin); free(YMax); if (CoordType == THREED_COORDS) { free(ZMin); free(ZMax); } if (Level == 0 && (WeightType == GEO || WeightType == GEOM || WeightType == GEO_MEEUS || WeightType == GEOM_MEEUS)) { Candidate **SavedCandidateSet; assert(SavedCandidateSet = (Candidate **) malloc((1 + DimensionSaved) * sizeof(Candidate *))); if (TraceLevel >= 2) printff("done\n"); From = FirstNode; while ((From = From->Suc) != FirstNode) if ((From->Y > 0) != (FirstNode->Y > 0)) break; if (From != FirstNode) { /* Transform longitude (180 and -180 map to 0) */ From = FirstNode; do { SavedCandidateSet[From->Id] = From->CandidateSet; From->CandidateSet = 0; From->Zc = From->Y; if (WeightType == GEO || WeightType == GEO_MEEUS) From->Y = (int) From->Y + 5.0 * (From->Y - (int) From->Y) / 3.0; From->Y += From->Y > 0 ? -180 : 180; if (WeightType == GEO || WeightType == GEO_MEEUS) From->Y = (int) From->Y + 3.0 * (From->Y - (int) From->Y) / 5.0; } while ((From = From->Suc) != FirstNode); Level++; CreateQuadrantCandidateSet(K); Level--; From = FirstNode; do From->Y = From->Zc; while ((From = From->Suc) != FirstNode); do { Candidate *QCandidateSet = From->CandidateSet; From->CandidateSet = SavedCandidateSet[From->Id]; for (NFrom = QCandidateSet; (To = NFrom->To); NFrom++) AddCandidate(From, To, NFrom->Cost, NFrom->Alpha); free(QCandidateSet); } while ((From = From->Suc) != FirstNode); free(SavedCandidateSet); } } if (Level == 0) { ResetCandidateSet(); AddTourCandidates(); if (CandidateSetSymmetric) SymmetrizeCandidateSet(); if (TraceLevel >= 2) printff("done\n"); } }
GainType LinKernighan() { Node *t1, *t2, *SUCt1; GainType Gain, G0, Cost; int X2, i, it = 0; Candidate *Nt1; Segment *S; SSegment *SS; double EntryTime = GetTime(); Reversed = 0; S = FirstSegment; i = 0; do { S->Size = 0; S->Rank = ++i; S->Reversed = 0; S->First = S->Last = 0; } while ((S = S->Suc) != FirstSegment); SS = FirstSSegment; i = 0; do { SS->Size = 0; SS->Rank = ++i; SS->Reversed = 0; SS->First = SS->Last = 0; } while ((SS = SS->Suc) != FirstSSegment); FirstActive = LastActive = 0; Swaps = 0; /* Compute the cost of the initial tour, Cost. Compute the corresponding hash value, Hash. Initialize the segment list. Make all nodes "active" (so that they can be used as t1). */ Cost = 0; Hash = 0; i = 0; t1 = FirstNode; do { t2 = t1->OldSuc = t1->Suc; t1->OldPred = t1->Pred; t1->Rank = ++i; Cost += (t1->SucCost = t2->PredCost = C(t1, t2)) - t1->Pi - t2->Pi; Hash ^= Rand[t1->Id] * Rand[t2->Id]; t1->Cost = INT_MAX; for (Nt1 = t1->CandidateSet; (t2 = Nt1->To); Nt1++) if (t2 != t1->Pred && t2 != t1->Suc && Nt1->Cost < t1->Cost) t1->Cost = Nt1->Cost; t1->Parent = S; S->Size++; if (S->Size == 1) S->First = t1; S->Last = t1; if (SS->Size == 0) SS->First = S; S->Parent = SS; SS->Last = S; if (S->Size == GroupSize) { S = S->Suc; SS->Size++; if (SS->Size == SGroupSize) SS = SS->Suc; } t1->OldPredExcluded = t1->OldSucExcluded = 0; t1->Next = 0; if (KickType == 0 || Kicks == 0 || !InBestTour(t1, t1->Pred) || !InBestTour(t1, t1->Suc)) Activate(t1); } while ((t1 = t1->Suc) != FirstNode); if (S->Size < GroupSize) SS->Size++; Cost /= Precision; if (TraceLevel >= 3 || (TraceLevel == 2 && Cost < BetterCost)) { printff("Cost = " GainFormat, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Cost - Optimum) / Optimum); printff(", Time = %0.1f sec. %s\n", fabs(GetTime() - EntryTime), Cost < Optimum ? "<" : Cost == Optimum ? "=" : ""); } PredSucCostAvailable = 1; /* Loop as long as improvements are found */ do { /* Choose t1 as the first "active" node */ while ((t1 = RemoveFirstActive())) { /* t1 is now "passive" */ SUCt1 = SUC(t1); if ((TraceLevel >= 3 || (TraceLevel == 2 && Trial == 1)) && ++it % (Dimension >= 100000 ? 10000 : Dimension >= 10000 ? 1000 : 100) == 0) printff("#%d: Time = %0.1f sec.\n", it, fabs(GetTime() - EntryTime)); /* Choose t2 as one of t1's two neighbors on the tour */ for (X2 = 1; X2 <= 2; X2++) { t2 = X2 == 1 ? PRED(t1) : SUCt1; if (FixedOrCommon(t1, t2) || (RestrictedSearch && Near(t1, t2) && (Trial == 1 || (Trial > BackboneTrials && (KickType == 0 || Kicks == 0))))) continue; G0 = C(t1, t2); /* Try to find a tour-improving chain of moves */ do t2 = Swaps == 0 ? BestMove(t1, t2, &G0, &Gain) : BestSubsequentMove(t1, t2, &G0, &Gain); while (t2); if (Gain > 0) { /* An improvement has been found */ assert(Gain % Precision == 0); Cost -= Gain / Precision; if (TraceLevel >= 3 || (TraceLevel == 2 && Cost < BetterCost)) { printff("Cost = " GainFormat, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Cost - Optimum) / Optimum); printff(", Time = %0.1f sec. %s\n", fabs(GetTime() - EntryTime), Cost < Optimum ? "<" : Cost == Optimum ? "=" : ""); } StoreTour(); if (HashSearch(HTable, Hash, Cost)) goto End_LinKernighan; /* Make t1 "active" again */ Activate(t1); break; } RestoreTour(); } } if (HashSearch(HTable, Hash, Cost)) goto End_LinKernighan; HashInsert(HTable, Hash, Cost); /* Try to find improvements using non-sequential 4/5-opt moves */ Gain = 0; if (Gain23Used && (Gain = Gain23()) > 0) { /* An improvement has been found */ assert(Gain % Precision == 0); Cost -= Gain / Precision; StoreTour(); if (TraceLevel >= 3 || (TraceLevel == 2 && Cost < BetterCost)) { printff("Cost = " GainFormat, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Cost - Optimum) / Optimum); printff(", Time = %0.1f sec. + %s\n", fabs(GetTime() - EntryTime), Cost < Optimum ? "<" : Cost == Optimum ? "=" : ""); } if (HashSearch(HTable, Hash, Cost)) goto End_LinKernighan; } } while (Gain > 0); End_LinKernighan: PredSucCostAvailable = 0; NormalizeNodeList(); NormalizeSegmentList(); return Cost; }
GainType Ascent() { Node *t; GainType BestW, W, W0, Alpha, MaxAlpha = INT_MAX; int T, Period, P, InitialPhase, BestNorm; Start: /* Initialize Pi and BestPi */ t = FirstNode; do t->Pi = t->BestPi = 0; while ((t = t->Suc) != FirstNode); if (CandidateSetType == DELAUNAY) CreateDelaunayCandidateSet(); else AddTourCandidates(); /* Compute the cost of a minimum 1-tree */ W = Minimum1TreeCost(CandidateSetType == DELAUNAY || MaxCandidates == 0); /* Return this cost if either (1) subgradient optimization is not wanted, or (2) the norm of the tree (its deviation from a tour) is zero (in that case the true optimum has been found). */ if (!Subgradient || !Norm) return W; if (Optimum != MINUS_INFINITY && (Alpha = Optimum * Precision - W) > 0) MaxAlpha = Alpha; if (MaxCandidates > 0) { /* Generate symmetric candididate sets for all nodes */ if (CandidateSetType != DELAUNAY) GenerateCandidates(AscentCandidates, MaxAlpha, 1); else { OrderCandidateSet(AscentCandidates, MaxAlpha, 1); W = Minimum1TreeCost(1); if (!Norm || W / Precision == Optimum) return W; } } if (ExtraCandidates > 0) AddExtraCandidates(ExtraCandidates, ExtraCandidateSetType, ExtraCandidateSetSymmetric); if (TraceLevel >= 2) { CandidateReport(); printff("Subgradient optimization ...\n"); } /* Set LastV of every node to V (the node's degree in the 1-tree) */ t = FirstNode; do t->LastV = t->V; while ((t = t->Suc) != FirstNode); BestW = W0 = W; BestNorm = Norm; InitialPhase = 1; /* Perform subradient optimization with decreasing period length and decreasing step size */ for (Period = InitialPeriod, T = InitialStepSize * Precision; Period > 0 && T > 0 && Norm != 0; Period /= 2, T /= 2) { /* Period and step size are halved at each iteration */ if (TraceLevel >= 2) printff (" T = %d, Period = %d, BestW = %0.1f, Norm = %d\n", T, Period, (double) BestW / Precision, Norm); for (P = 1; T && P <= Period && Norm != 0; P++) { /* Adjust the Pi-values */ t = FirstNode; do { if (t->V != 0) { t->Pi += T * (7 * t->V + 3 * t->LastV) / 10; if (t->Pi > INT_MAX / 4) t->Pi = INT_MAX / 4; else if (t->Pi < -INT_MAX / 4) t->Pi = -INT_MAX / 4; } t->LastV = t->V; } while ((t = t->Suc) != FirstNode); /* Compute a minimum 1-tree in the sparse graph */ W = Minimum1TreeCost(1); /* Test if an improvement has been found */ if (W > BestW || (W == BestW && Norm < BestNorm)) { /* If the lower bound becomes greater than twice its initial value it is taken as a sign that the graph might be too sparse */ if (W - W0 > (W0 >= 0 ? W0 : -W0) && AscentCandidates > 0 && AscentCandidates < Dimension) { W = Minimum1TreeCost(CandidateSetType == DELAUNAY || MaxCandidates == 0); if (W < W0) { /* Double the number of candidate edges and start all over again */ if (TraceLevel >= 2) printff("Warning: AscentCandidates doubled\n"); if ((AscentCandidates *= 2) > Dimension) AscentCandidates = Dimension; goto Start; } W0 = W; } BestW = W; BestNorm = Norm; /* Update the BestPi-values */ t = FirstNode; do t->BestPi = t->Pi; while ((t = t->Suc) != FirstNode); if (TraceLevel >= 2) printff ("* T = %d, Period = %d, P = %d, BestW = %0.1f, Norm = %d\n", T, Period, P, (double) BestW / Precision, Norm); /* If in the initial phase, the step size is doubled */ if (InitialPhase && T * sqrt((double) Norm) > 0) T *= 2; /* If the improvement was found at the last iteration of the current period, then double the period */ if (CandidateSetType != DELAUNAY && P == Period && (Period *= 2) > InitialPeriod) Period = InitialPeriod; } else { if (TraceLevel >= 3) printff (" T = %d, Period = %d, P = %d, W = %0.1f, Norm = %d\n", T, Period, P, (double) W / Precision, Norm); if (InitialPhase && P > Period / 2) { /* Conclude the initial phase */ InitialPhase = 0; P = 0; T = 3 * T / 4; } } } } t = FirstNode; do { t->Pi = t->BestPi; t->BestPi = 0; } while ((t = t->Suc) != FirstNode); /* Compute a minimum 1-tree */ W = BestW = Minimum1TreeCost(CandidateSetType == DELAUNAY || MaxCandidates == 0); if (MaxCandidates > 0) { FreeCandidateSets(); if (CandidateSetType == DELAUNAY) CreateDelaunayCandidateSet(); } else { Candidate *Nt; t = FirstNode; do { for (Nt = t->CandidateSet; Nt && Nt->To; Nt++) Nt->Cost += t->Pi + Nt->To->Pi; } while ((t = t->Suc) != FirstNode); } if (TraceLevel >= 2) printff("Ascent: BestW = %0.1f, Norm = %d\n", (double) BestW / Precision, Norm); return W; }
void LKH::LKHAlg::PrintParameters() { int i; printff("ASCENT_CANDIDATES = %d\n", AscentCandidates); printff("BACKBONE_TRIALS = %d\n", BackboneTrials); printff("BACKTRACKING = %s\n", Backtracking ? "YES" : "NO"); if (CandidateFiles == 0) printff("# CANDIDATE_FILE =\n"); else for (i = 0; i < CandidateFiles; i++) printff("CANDIDATE_FILE = %s\n", CandidateFileName[i]); printff("CANDIDATE_SET_TYPE = %s%s\n", CandidateSetType == ALPHA ? "ALPHA" : CandidateSetType == DELAUNAY ? "DELAUNAY" : CandidateSetType == NN ? "NEAREST-NEIGHBOR" : CandidateSetType == QUADRANT ? "QUADRANT" : "", DelaunayPure ? " PURE" : ""); if (Excess >= 0) printff("EXCESS = %g\n", Excess); else printff("# EXCESS =\n"); printff("EXTRA_CANDIDATES = %d %s\n", ExtraCandidates, ExtraCandidateSetSymmetric ? "SYMMETRIC" : ""); printff("EXTRA_CANDIDATE_SET_TYPE = %s\n", ExtraCandidateSetType == NN ? "NEAREST-NEIGHBOR" : ExtraCandidateSetType == QUADRANT ? "QUADRANT" : ""); printff("GAIN23 = %s\n", Gain23Used ? "YES" : "NO"); printff("GAIN_CRITERION = %s\n", GainCriterionUsed ? "YES" : "NO"); if (InitialPeriod >= 0) printff("INITIAL_PERIOD = %d\n", InitialPeriod); else printff("# INITIAL_PERIOD =\n"); printff("INITIAL_STEP_SIZE = %d\n", InitialStepSize); printff("INITIAL_TOUR_ALGORITHM = %s\n", InitialTourAlgorithm == BORUVKA ? "BORUVKA" : InitialTourAlgorithm == GREEDY ? "GREEDY" : InitialTourAlgorithm == MOORE ? "MOORE" : InitialTourAlgorithm == NEAREST_NEIGHBOR ? "NEAREST-NEIGHBOR" : InitialTourAlgorithm == QUICK_BORUVKA ? "QUICK-BORUVKA" : InitialTourAlgorithm == SIERPINSKI ? "SIERPINSKI" : "WALK"); printff("%sINITIAL_TOUR_FILE = %s\n", InitialTourFileName ? "" : "# ", InitialTourFileName ? InitialTourFileName : ""); printff("INITIAL_TOUR_FRACTION = %0.3f\n", InitialTourFraction); printff("%sINPUT_TOUR_FILE = %s\n", InputTourFileName ? "" : "# ", InputTourFileName ? InputTourFileName : ""); printff("KICK_TYPE = %d\n", KickType); printff("KICKS = %d\n", Kicks); if (MaxBreadth == INT_MAX) printff("# MAX_BREADTH =\n"); else printff("MAX_BREADTH = %d\n", MaxBreadth); printff("MAX_CANDIDATES = %d %s\n", MaxCandidates, CandidateSetSymmetric ? "SYMMETRIC" : ""); if (MaxSwaps >= 0) printff("MAX_SWAPS = %d\n", MaxSwaps); else printff("# MAX_SWAPS =\n"); if (MaxTrials >= 0) printff("MAX_TRIALS = %d\n", MaxTrials); else printff("# MAX_TRIALS =\n"); if (MergeTourFiles == 0) printff("# MERGE_TOUR_FILE =\n"); else for (i = 0; i < MergeTourFiles; i++) printff("MERGE_TOUR_FILE = %s\n", MergeTourFileName[i]); printff("MOVE_TYPE = %d\n", MoveType); printff("%sNONSEQUENTIAL_MOVE_TYPE = %d\n", PatchingA > 1 ? "" : "# ", NonsequentialMoveType); if (Optimum == MINUS_INFINITY) printff("# OPTIMUM =\n"); else printff("OPTIMUM = " GainFormat "\n", Optimum); printff("%sOUTPUT_TOUR_FILE = %s\n", OutputTourFileName ? "" : "# ", OutputTourFileName ? OutputTourFileName : ""); printff("PATCHING_A = %d %s\n", PatchingA, PatchingARestricted ? "RESTRICTED" : PatchingAExtended ? "EXTENDED" : ""); printff("PATCHING_C = %d %s\n", PatchingC, PatchingCRestricted ? "RESTRICTED" : PatchingCExtended ? "EXTENDED" : ""); printff("%sPI_FILE = %s\n", PiFileName ? "" : "# ", PiFileName ? PiFileName : ""); if (*MaxPopulationSize == 0) printff("# "); printff("POPULATION_SIZE = %d\n", *MaxPopulationSize); printff("PRECISION = %d\n", Precision); printff("%sPROBLEM_FILE = %s\n", ProblemFileName ? "" : "# ", ProblemFileName ? ProblemFileName : ""); printff("RESTRICTED_SEARCH = %s\n", RestrictedSearch ? "YES" : "NO"); printff("RUNS = %d\n", Runs); printff("SEED = %u\n", Seed); printff("STOP_AT_OPTIMUM = %s\n", StopAtOptimum ? "YES" : "NO"); printff("SUBGRADIENT = %s\n", Subgradient ? "YES" : "NO"); if (SubproblemSize == 0) printff("# SUBPROBLEM_SIZE =\n"); else printff("SUBPROBLEM_SIZE = %d%s%s%s\n", SubproblemSize, DelaunayPartitioning ? " DELAUNAY" : KarpPartitioning ? " KARP" : KCenterPartitioning ? " K-CENTER" : KMeansPartitioning ? " K-MEANS" : MoorePartitioning ? " MOORE" : RohePartitioning ? " ROHE" : SierpinskiPartitioning ? " SIERPINSKI" : "", SubproblemBorders ? " BORDERS" : "", SubproblemsCompressed ? " COMPRESSED" : ""); printff("%sSUBPROBLEM_TOUR_FILE = %s\n", SubproblemTourFileName ? "" : "# ", SubproblemTourFileName ? SubproblemTourFileName : ""); printff("SUBSEQUENT_MOVE_TYPE = %d\n", SubsequentMoveType == 0 ? MoveType : SubsequentMoveType); printff("SUBSEQUENT_PATCHING = %s\n", SubsequentPatching ? "YES" : "NO"); if (TimeLimit == DBL_MAX) printff("# TIME_LIMIT =\n"); else printff("TIME_LIMIT = %0.1f\n", TimeLimit); printff("%sTOUR_FILE = %s\n", TourFileName ? "" : "# ", TourFileName ? TourFileName : ""); printff("TRACE_LEVEL = %d\n\n", TraceLevel); }
void SolveRoheSubproblems() { Node *N; int CurrentSubproblem, Subproblems, Remaining, i; GainType GlobalBestCost, OldGlobalBestCost; double XMin, XMax, YMin, YMax, ZMin, ZMax, DX, DY, DZ, CLow, CMid, CHigh; double EntryTime = GetTime(); AllocateStructures(); ReadPenalties(); Subproblems = 0; /* Compute upper bound for the original problem */ GlobalBestCost = 0; N = FirstNode; do { if (!Fixed(N, N->SubproblemSuc)) GlobalBestCost += Distance(N, N->SubproblemSuc); N->Subproblem = 0; } while ((N = N->SubproblemSuc) != FirstNode); if (TraceLevel >= 1) { if (TraceLevel >= 2) printff("\n"); printff("*** Rohe partitioning *** [Cost = " GainFormat "]\n", GlobalBestCost); } if (WeightType == GEO || WeightType == GEOM || WeightType == GEO_MEEUS || WeightType == GEOM_MEEUS) { N = FirstNode; do { N->Xc = N->X; N->Yc = N->Y; N->Zc = N->Z; if (WeightType == GEO || WeightType == GEO_MEEUS) GEO2XYZ(N->Xc, N->Yc, &N->X, &N->Y, &N->Z); else GEOM2XYZ(N->Xc, N->Yc, &N->X, &N->Y, &N->Z); } while ((N = N->SubproblemSuc) != FirstNode); CoordType = THREED_COORDS; } N = FirstNode; XMin = XMax = N->X; YMin = YMax = N->Y; ZMin = ZMax = N->Z; while ((N = N->SubproblemSuc) != FirstNode) { if (N->X < XMin) XMin = N->X; else if (N->X > XMax) XMax = N->X; if (N->Y < YMin) YMin = N->Y; else if (N->Y > YMax) YMax = N->Y; if (N->Z < ZMin) ZMin = N->Z; else if (N->Z > ZMax) ZMax = N->Z; } KDTree = BuildKDTree(SubproblemSize); Remaining = Dimension; while (Remaining > SubproblemSize) { N = FirstNode; i = Random() % Remaining; while (i--) N = N->Suc; DX = (0.5 + 0.5 * Random() / (PRANDMAX - 1)) * (XMax - XMin); DY = (0.5 + 0.5 * Random() / (PRANDMAX - 1)) * (YMax - YMin); DZ = (0.5 + 0.5 * Random() / (PRANDMAX - 1)) * (ZMax - ZMin); CLow = 0; CHigh = 2; /* Binary search */ do { CMid = (CLow + CHigh) / 2; Size = 0; WindowSize(N->X - CMid * DX, N->X + CMid * DX, N->Y - CMid * DY, N->Y + CMid * DY, N->Z - CMid * DZ, N->Z + CMid * DZ, 0, Dimension - 1); if (Size >= 2.0 / 3 * SubproblemSize && Size <= SubproblemSize) break; if (Size < 2.0 / 3 * SubproblemSize) CLow = CMid; else CHigh = CMid; } while (CHigh - CLow > DBL_EPSILON); MakeSubproblem(N->X - CMid * DX, N->X + CMid * DX, N->Y - CMid * DY, N->Y + CMid * DY, N->Z - CMid * DZ, N->Z + CMid * DZ, ++Subproblems, 0, Dimension - 1); Remaining -= Size; } if (Remaining > 3) { Subproblems++; N = FirstNode; do N->Subproblem = Subproblems; while ((N = N->Suc) != FirstNode); } if (WeightType == GEO || WeightType == GEOM || WeightType == GEO_MEEUS || WeightType == GEOM_MEEUS) { N = FirstNode; do { N->X = N->Xc; N->Y = N->Yc; N->Z = N->Zc; } while ((N = N->SubproblemSuc) != FirstNode); CoordType = TWOD_COORDS; } free(KDTree); for (CurrentSubproblem = 1; CurrentSubproblem <= Subproblems; CurrentSubproblem++) { OldGlobalBestCost = GlobalBestCost; SolveSubproblem(CurrentSubproblem, Subproblems, &GlobalBestCost); if (SubproblemsCompressed && GlobalBestCost == OldGlobalBestCost) SolveCompressedSubproblem(CurrentSubproblem, Subproblems, &GlobalBestCost); } printff("\nCost = " GainFormat, GlobalBestCost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (GlobalBestCost - Optimum) / Optimum); printff(", Time = %0.1f sec. %s\n", fabs(GetTime() - EntryTime), GlobalBestCost < Optimum ? "<" : GlobalBestCost == Optimum ? "=" : ""); if (SubproblemBorders && Subproblems > 1) SolveSubproblemBorderProblems(Subproblems, &GlobalBestCost); }
GainType SFCTour(int CurveType) { double XMin, XMax, YMin, YMax; Node *N, **Perm; int i; IndexFunction Index; GainType Cost; double EntryTime = GetTime(); if (CurveType == SIERPINSKI) { if (TraceLevel >= 1) printff("Sierpinski = "); Index = SierpinskiIndex; } else { if (TraceLevel >= 1) printff("Moore = "); Index = MooreIndex; } N = FirstNode; XMin = XMax = N->X; YMin = YMax = N->Y; N->V = 0; while ((N = N->Suc) != FirstNode) { if (N->X < XMin) XMin = N->X; else if (N->X > XMax) XMax = N->X; if (N->Y < YMin) YMin = N->Y; else if (N->Y > YMax) YMax = N->Y; } if (XMax == XMin) XMax = XMin + 1; if (YMax == YMin) YMax = YMin + 1; assert(Perm = (Node **) malloc(Dimension * sizeof(Node *))); for (i = 0, N = FirstNode; i < Dimension; i++, N = N->Suc) (Perm[i] = N)->V = Index((N->X - XMin) / (XMax - XMin), (N->Y - YMin) / (YMax - YMin)); qsort(Perm, Dimension, sizeof(Node *), compare); for (i = 1; i < Dimension; i++) Follow(Perm[i], Perm[i - 1]); free(Perm); /* Assure that all fixed or common edges belong to the tour */ N = FirstNode; do { N->LastV = 1; if (!FixedOrCommon(N, N->Suc) && N->CandidateSet) { Candidate *NN; for (NN = N->CandidateSet; NN->To; NN++) { if (!NN->To->LastV && FixedOrCommon(N, NN->To)) { Follow(NN->To, N); break; } } } } while ((N = N->Suc) != FirstNode); Cost = 0; N = FirstNode; do if (!Fixed(N, N->Suc)) Cost += Distance(N, N->Suc); while ((N = N->Suc) != FirstNode); if (TraceLevel >= 1) { printff(GainFormat, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.1f%%", 100.0 * (Cost - Optimum) / Optimum); printff(", Time = %0.2f sec.\n", fabs(GetTime() - EntryTime)); } return Cost; }
GainType LKH::LKHAlg::FindTour() { GainType Cost; Node *t; int i; double EntryTime = GetTime(); if(!OrdinalTourCost.get()) OrdinalTourCost.reset(new GainType(0)); t = FirstNode; do t->OldPred = t->OldSuc = t->NextBestSuc = t->BestSuc = 0; while ((t = t->Suc) != FirstNode); if (Run == 1 && Dimension == DimensionSaved) { *OrdinalTourCost = 0; for (i = 1; i < Dimension; i++) *OrdinalTourCost += (this->*C)(&NodeSet[i], &NodeSet[i + 1]) - NodeSet[i].Pi - NodeSet[i + 1].Pi; *OrdinalTourCost += (this->*C)(&NodeSet[Dimension], &NodeSet[1]) - NodeSet[Dimension].Pi - NodeSet[1].Pi; *OrdinalTourCost /= Precision; } BetterCost = PLUS_INFINITY; if (MaxTrials > 0) HashInitialize(HTable); else { Trial = 1; ChooseInitialTour(); } for (Trial = 1; Trial <= MaxTrials; Trial++) { if (GetTime() - EntryTime >= TimeLimit) { if (TraceLevel >= 1) printff("*** Time limit exceeded ***\n"); break; } /* Choose FirstNode at random */ if (Dimension == DimensionSaved) FirstNode = &NodeSet[1 + Random() % Dimension]; else for (i = Random() % Dimension; i > 0; i--) FirstNode = FirstNode->Suc; ChooseInitialTour(); Cost = LinKernighan(); if (FirstNode->BestSuc) { /* Merge tour with current best tour */ t = FirstNode; while ((t = t->Next = t->BestSuc) != FirstNode); Cost = MergeWithTour(); } if (Dimension == DimensionSaved && Cost >= *OrdinalTourCost && BetterCost > *OrdinalTourCost) { /* Merge tour with ordinal tour */ for (i = 1; i < Dimension; i++) NodeSet[i].Next = &NodeSet[i + 1]; NodeSet[Dimension].Next = &NodeSet[1]; Cost = MergeWithTour(); } if (Cost < BetterCost) { if (TraceLevel >= 1) { /* printff("* %d: Cost = " GainFormat, Trial, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Cost - Optimum) / Optimum); printff(", Time = %0.2f sec. %s\n", fabs(GetTime() - EntryTime), Cost < Optimum ? "<" : Cost == Optimum ? "=" : ""); */ } BetterCost = Cost; RecordBetterTour(); if (Dimension == DimensionSaved && BetterCost < BestCost) WriteTour(OutputTourFileName, BetterTour, BetterCost); if (StopAtOptimum && BetterCost == Optimum) break; AdjustCandidateSet(); HashInitialize(HTable); HashInsert(HTable, Hash, Cost); } else if (TraceLevel >= 2) printff(" %d: Cost = " GainFormat ", Time = %0.2f sec.\n", Trial, Cost, fabs(GetTime() - EntryTime)); /* Record backbones if wanted */ if (Trial <= BackboneTrials && BackboneTrials < MaxTrials) { SwapCandidateSets(this); AdjustCandidateSet(); if (Trial == BackboneTrials) { if (TraceLevel >= 1) { printff("# %d: Backbone candidates ->\n", Trial); CandidateReport(); } } else SwapCandidateSets(this); } } if (BackboneTrials > 0 && BackboneTrials < MaxTrials) { if (Trial > BackboneTrials || (Trial == BackboneTrials && (!StopAtOptimum || BetterCost != Optimum))) SwapCandidateSets(this); t = FirstNode; do { free(t->BackboneCandidateSet); t->BackboneCandidateSet = 0; } while ((t = t->Suc) != FirstNode); } t = FirstNode; if (Norm == 0) { do t = t->BestSuc = t->Suc; while (t != FirstNode); } do (t->Suc = t->BestSuc)->Pred = t; while ((t = t->BestSuc) != FirstNode); if (Trial > MaxTrials) Trial = MaxTrials; ResetCandidateSet(); return BetterCost; }
ostream& ppsig::print (ostream& fout) const { int i; double r; Tree c, sel, x, y, z, u, var, le, label, id, ff, largs, type, name, file; if ( isList(sig) ) { printlist(fout, sig); } else if ( isProj(sig, &i, x) ) { fout << "proj" << i << '(' << ppsig(x, fEnv) << ')'; } else if ( isRec(sig, var, le) ) { printrec(fout, var, le, fHideRecursion /*&& (getRecursivness(sig)==0)*/ ); } // debruinj notation else if ( isRec(sig, le) ) { printrec(fout, le, fHideRecursion ); } else if ( isRef(sig, i) ) { fout << "REF[" << i << "]"; } else if ( getUserData(sig) ) { printextended(fout, sig); } else if ( isSigInt(sig, &i) ) { fout << i; } else if ( isSigReal(sig, &r) ) { fout << T(r); } else if ( isSigWaveform(sig) ) { fout << "waveform{...}"; } else if ( isSigInput(sig, &i) ) { fout << "IN[" << i << "]"; } else if ( isSigOutput(sig, &i, x) ) { printout(fout, i, x) ; } else if ( isSigDelay1(sig, x) ) { fout << ppsig(x, fEnv, 9) << "'"; } //else if ( isSigFixDelay(sig, x, y) ) { printinfix(fout, "@", 8, x, y); } else if ( isSigFixDelay(sig, x, y) ) { printFixDelay(fout, x, y); } else if ( isSigPrefix(sig, x, y) ) { printfun(fout, "prefix", x, y); } else if ( isSigIota(sig, x) ) { printfun(fout, "iota", x); } else if ( isSigBinOp(sig, &i, x, y) ) { printinfix(fout, gBinOpTable[i]->fName, gBinOpTable[i]->fPriority, x, y); } else if ( isSigFFun(sig, ff, largs) ) { printff(fout, ff, largs); } else if ( isSigFConst(sig, type, name, file) ) { fout << tree2str(name); } else if ( isSigFVar(sig, type, name, file) ) { fout << tree2str(name); } else if ( isSigTable(sig, id, x, y) ) { printfun(fout, "TABLE", x, y); } else if ( isSigWRTbl(sig, id, x, y, z) ) { printfun(fout, "write", x, y, z); } else if ( isSigRDTbl(sig, x, y) ) { printfun(fout, "read", x, y); } else if ( isSigGen(sig, x) ) { fout << ppsig(x, fEnv, fPriority); } else if ( isSigDocConstantTbl(sig, x, y) ) { printfun(fout, "docConstantTbl", x, y); } else if ( isSigDocWriteTbl(sig, x, y, z, u) ) { printfun(fout, "docWriteTbl", x, y, z, u); } else if ( isSigDocAccessTbl(sig, x, y) ) { printfun(fout, "docAccessTbl", x, y); } else if ( isSigSelect2(sig, sel, x, y) ) { printfun(fout, "select2", sel, x, y); } else if ( isSigSelect3(sig, sel, x, y, z) ) { printfun(fout, "select3", sel, x, y, z); } else if ( isSigIntCast(sig, x) ) { printfun(fout, "int", x); } else if ( isSigFloatCast(sig, x) ) { printfun(fout, "float", x); } else if ( isSigButton(sig, label) ) { printui(fout, "button", label); } else if ( isSigCheckbox(sig, label) ) { printui(fout, "checkbox", label); } else if ( isSigVSlider(sig, label,c,x,y,z) ) { printui(fout, "vslider", label, c, x, y, z); } else if ( isSigHSlider(sig, label,c,x,y,z) ) { printui(fout, "hslider", label, c, x, y, z); } else if ( isSigNumEntry(sig, label,c,x,y,z) ) { printui(fout, "nentry", label, c, x, y, z); } else if ( isSigVBargraph(sig, label,x,y,z) ) { printui(fout, "vbargraph", label, x, y, z); } else if ( isSigHBargraph(sig, label,x,y,z) ) { printui(fout, "hbargraph", label, x, y, z); } else if ( isSigAttach(sig, x, y) ) { printfun(fout, "attach", x, y); } else { cerr << "NOT A SIGNAL : " << *sig << endl; //exit(1); } return fout; }
void LKH::LKHAlg::CreateCandidateSet() { GainType Cost, MaxAlpha, A; Node *Na; int CandidatesRead = 0, i; double EntryTime = GetTime(); Norm = 9999; if (C == &LKH::LKHAlg::C_EXPLICIT) { Na = FirstNode; do { for (i = 1; i < Na->Id; i++) Na->C[i] *= Precision; } while ((Na = Na->Suc) != FirstNode); } if (Distance == &LKH::LKHAlg::Distance_1 || (MaxTrials == 0 && (FirstNode->InitialSuc || InitialTourAlgorithm == SIERPINSKI || InitialTourAlgorithm == MOORE))) { ReadCandidates(MaxCandidates); AddTourCandidates(); if (ProblemType == HCP || ProblemType == HPP) Ascent(); goto End_CreateCandidateSet; } if (TraceLevel >= 2) printff("Creating candidates ...\n"); if (MaxCandidates > 0 && (CandidateSetType == QUADRANT || CandidateSetType == NN)) { ReadPenalties(); if (!(CandidatesRead = ReadCandidates(MaxCandidates)) && MaxCandidates > 0) { if (CandidateSetType == QUADRANT) CreateQuadrantCandidateSet(MaxCandidates); else if (CandidateSetType == NN) CreateNearestNeighborCandidateSet(MaxCandidates); } else { AddTourCandidates(); if (CandidateSetSymmetric) SymmetrizeCandidateSet(); } goto End_CreateCandidateSet; } if (!ReadPenalties()) { /* No PiFile specified or available */ Na = FirstNode; do Na->Pi = 0; while ((Na = Na->Suc) != FirstNode); CandidatesRead = ReadCandidates(MaxCandidates); Cost = Ascent(); if (Subgradient && SubproblemSize == 0) { WritePenalties(); PiFile = 0; } } else if ((CandidatesRead = ReadCandidates(MaxCandidates)) || MaxCandidates == 0) { AddTourCandidates(); if (CandidateSetSymmetric) SymmetrizeCandidateSet(); goto End_CreateCandidateSet; } else { if (CandidateSetType != DELAUNAY && MaxCandidates > 0) { if (TraceLevel >= 2) printff("Computing lower bound ... "); Cost = Minimum1TreeCost(0); if (TraceLevel >= 2) printff("done\n"); } else { CreateDelaunayCandidateSet(); Na = FirstNode; do { Na->BestPi = Na->Pi; Na->Pi = 0; } while ((Na = Na->Suc) != FirstNode); if (TraceLevel >= 2) printff("Computing lower bound ... "); Cost = Minimum1TreeCost(1); if (TraceLevel >= 2) printff("done\n"); Na = FirstNode; do { Na->Pi = Na->BestPi; Cost -= 2 * Na->Pi; } while ((Na = Na->Suc) != FirstNode); } } LowerBound = (double) Cost / Precision; if (TraceLevel >= 1) { /* printff("Lower bound = %0.1f", LowerBound); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.2f%%", 100.0 * (Optimum - LowerBound) / Optimum); if (!PiFile) printff(", Ascent time = %0.2f sec.", fabs(GetTime() - EntryTime)); printff("\n"); */ if (Optimum != MINUS_INFINITY && Optimum != 0) m_Gap=100.0 * (Optimum - LowerBound) / Optimum; if (!PiFile) m_AscentTime=fabs(GetTime() - EntryTime); } MaxAlpha = (GainType) fabs(Excess * Cost); if ((A = Optimum * Precision - Cost) > 0 && A < MaxAlpha) MaxAlpha = A; if (CandidateSetType == DELAUNAY || MaxCandidates == 0) OrderCandidateSet(MaxCandidates, MaxAlpha, CandidateSetSymmetric); else GenerateCandidates(MaxCandidates, MaxAlpha, CandidateSetSymmetric); End_CreateCandidateSet: if (ExtraCandidates > 0) { AddExtraCandidates(ExtraCandidates, ExtraCandidateSetType, ExtraCandidateSetSymmetric); AddTourCandidates(); } ResetCandidateSet(); Na = FirstNode; do { if (!Na->CandidateSet || !Na->CandidateSet[0].To) { if (MaxCandidates == 0) eprintf("MAX_CANDIDATES = 0: Node %d has no candidates", Na->Id); else eprintf("Node %d has no candidates", Na->Id); } } while ((Na = Na->Suc) != FirstNode); if (!CandidatesRead && SubproblemSize == 0) WriteCandidates(); if (C == &LKH::LKHAlg::C_EXPLICIT) { Na = FirstNode; do for (i = 1; i < Na->Id; i++) Na->C[i] += Na->Pi + NodeSet[i].Pi; while ((Na = Na->Suc) != FirstNode); } if (TraceLevel >= 1) { CandidateReport(); // printff("Preprocessing time = %0.2f sec.\n", // fabs(GetTime() - EntryTime)); } }
void CreateDelaunayCandidateSet() { Node *From, *To; point *u, *v; edge *e_start, *e; int d, i, Count; if (TraceLevel >= 2) printff("Creating Delaunay candidate set ... "); if (Level == 0 && MaxCandidates == 0) { AddTourCandidates(); From = FirstNode; do { if (!From->CandidateSet) eprintf("MAX_CANDIDATES = 0: No candidates"); } while ((From = From->Suc) != FirstNode); if (TraceLevel >= 2) printff("done\n"); return; } /* Find the Delaunay edges */ delaunay(Dimension); /* Add the Delaunay edges to the candidate set */ for (i = 0; i < Dimension; i++) { u = &p_array[i]; From = &NodeSet[u->id]; e_start = e = u->entry_pt; Count = 0; do { v = Other_point(e, u); if (u < v) { To = &NodeSet[v->id]; d = D(From, To); AddCandidate(From, To, d, 1); AddCandidate(To, From, d, 1); } } while ((e = Next(e, u)) != e_start && ++Count < Dimension); } free_memory(); if (Level == 0 && (WeightType == GEO || WeightType == GEOM || WeightType == GEO_MEEUS || WeightType == GEOM_MEEUS)) { if (TraceLevel >= 2) printff("done\n"); From = FirstNode; while ((From = From->Suc) != FirstNode) if ((From->Y > 0) != (FirstNode->Y > 0)) break; if (From != FirstNode) { /* Transform longitude (180 and -180 map to 0) */ From = FirstNode; do { From->Zc = From->Y; if (WeightType == GEO || WeightType == GEO_MEEUS) From->Y = (int) From->Y + 5.0 * (From->Y - (int) From->Y) / 3.0; From->Y += From->Y > 0 ? -180 : 180; if (WeightType == GEO || WeightType == GEO_MEEUS) From->Y = (int) From->Y + 3.0 * (From->Y - (int) From->Y) / 5.0; } while ((From = From->Suc) != FirstNode); Level++; CreateDelaunayCandidateSet(); Level--; From = FirstNode; do From->Y = From->Zc; while ((From = From->Suc) != FirstNode); } } if (Level == 0) { AddTourCandidates(); /* Add quadrant neighbors if any node has less than two candidates. That is, if it should happen that delaunay_edges fails. */ From = FirstNode; do { if (From->CandidateSet == 0 || From->CandidateSet[0].To == 0 || From->CandidateSet[1].To == 0) { if (TraceLevel >= 2) printff("*** Not complete ***\n"); AddExtraCandidates(CoordType == THREED_COORDS ? 8 : 4, QUADRANT, 1); break; } } while ((From = From->Suc) != FirstNode); if (TraceLevel >= 2) printff("done\n"); } }