コード例 #1
0
ファイル: Statistics.c プロジェクト: ashleywang1/TSP-solver
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));
}
コード例 #2
0
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");
}
コード例 #3
0
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;
}
コード例 #4
0
ファイル: Genetic.c プロジェクト: liu-wenwu/CodeCraft-LTZ
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");
    }
}
コード例 #5
0
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 ? "=" : "");
}
コード例 #6
0
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);
    }
}
コード例 #7
0
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);
}
コード例 #8
0
ファイル: g.c プロジェクト: pinaki1994/class
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);
}
コード例 #9
0
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);
}
コード例 #10
0
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;
}
コード例 #11
0
ファイル: Genetic.c プロジェクト: liu-wenwu/CodeCraft-LTZ
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();
}
コード例 #12
0
ファイル: ReadProblem.c プロジェクト: ashleywang1/TSP-solver
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;
}
コード例 #13
0
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;
}
コード例 #14
0
ファイル: doprint.c プロジェクト: alexfru/SmallerC
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];
}
コード例 #15
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;
}
コード例 #16
0
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");
}
コード例 #17
0
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;
}
コード例 #18
0
ファイル: hw.c プロジェクト: CrazyTeaFs/papaya
void _start(void){
	while(1){
		sleep(255,10);
		printff("hello papaya..\n");	
	}
}
コード例 #19
0
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);
}
コード例 #20
0
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");
    }
}
コード例 #21
0
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");
    }
}
コード例 #22
0
ファイル: LinKernighan.c プロジェクト: ashleywang1/TSP-solver
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;
}
コード例 #23
0
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;
}
コード例 #24
0
ファイル: PrintParameters.cpp プロジェクト: Changhe160/OFEC
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);
}
コード例 #25
0
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);
}
コード例 #26
0
ファイル: SFCTour.c プロジェクト: PQYPLZXHGF/elkai
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;
}
コード例 #27
0
ファイル: FindTour.cpp プロジェクト: Changhe160/OFEC
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;
}
コード例 #28
0
ファイル: ppsig.cpp プロジェクト: kitchenSinkCollection/faust
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;
}
コード例 #29
0
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));
    }
}
コード例 #30
0
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");
    }
}