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