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 ? "=" : ""); }
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); }
static void KarpPartition(int start, int end) { if (end - start + 1 <= SubproblemSize) { int i; CurrentSubproblem++; for (i = start; i <= end; i++) KDTree[i]->Subproblem = CurrentSubproblem; OldGlobalBestCost = GlobalBestCost; SolveSubproblem(CurrentSubproblem, Subproblems, &GlobalBestCost); if (SubproblemsCompressed && GlobalBestCost == OldGlobalBestCost) SolveCompressedSubproblem(CurrentSubproblem, Subproblems, &GlobalBestCost); } else { int mid = (start + end) / 2; KarpPartition(start, mid); KarpPartition(mid + 1, end); } }
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); }