int main(int argc, char *argv[])
{
    GainType Cost;
    double Time, LastTime = GetTime();

    /* Read the specification of the problem */
    if (argc >= 2)
        ParameterFileName = argv[1];
    ReadParameters();
    MaxMatrixDimension = 10000;
    ReadProblem();

    if (SubproblemSize > 0) {
        if (DelaunayPartitioning)
            SolveDelaunaySubproblems();
        else if (KarpPartitioning)
            SolveKarpSubproblems();
        else if (KCenterPartitioning)
            SolveKCenterSubproblems();
        else if (KMeansPartitioning)
            SolveKMeansSubproblems();
        else if (RohePartitioning)
            SolveRoheSubproblems();
        else if (MoorePartitioning || SierpinskiPartitioning)
            SolveSFCSubproblems();
        else
            SolveTourSegmentSubproblems();
        return EXIT_SUCCESS;
    }
    AllocateStructures();
    CreateCandidateSet();
    InitializeStatistics();

    if (Norm != 0)
        BestCost = PLUS_INFINITY;
    else {
        /* The ascent has solved the problem! */
        Optimum = BestCost = (GainType) LowerBound;
        UpdateStatistics(Optimum, GetTime() - LastTime);
        RecordBetterTour();
        RecordBestTour();
        WriteTour(OutputTourFileName, BestTour, BestCost);
        WriteTour(TourFileName, BestTour, BestCost);
        Runs = 0;
    }

    /* Find a specified number (Runs) of local optima */
    for (Run = 1; Run <= Runs; Run++) {
        LastTime = GetTime();
        Cost = FindTour();      /* using the Lin-Kernighan heuristic */
        if (MaxPopulationSize > 1) {
            /* Genetic algorithm */
            int i;
            for (i = 0; i < PopulationSize; i++) {
                GainType OldCost = Cost;
                Cost = MergeTourWithIndividual(i);
                if (TraceLevel >= 1 && Cost < OldCost) {
                    printff("  Merged with %d: Cost = " GainFormat, i + 1,
                            Cost);
                    if (Optimum != MINUS_INFINITY && Optimum != 0)
                        printff(", Gap = %0.4f%%",
                                100.0 * (Cost - Optimum) / Optimum);
                    printff("\n");
                }
            }
            if (!HasFitness(Cost)) {
                if (PopulationSize < MaxPopulationSize) {
                    AddToPopulation(Cost);
                    if (TraceLevel >= 1)
                        PrintPopulation();
                } else if (Cost < Fitness[PopulationSize - 1]) {
                    i = ReplacementIndividual(Cost);
                    ReplaceIndividualWithTour(i, Cost);
                    if (TraceLevel >= 1)
                        PrintPopulation();
                }
            }
        } else if (Run > 1)
            Cost = MergeBetterTourWithBestTour();
        if (Cost < BestCost) {
            BestCost = Cost;
            RecordBetterTour();
            RecordBestTour();
            WriteTour(OutputTourFileName, BestTour, BestCost);
            WriteTour(TourFileName, BestTour, BestCost);
        }
        if (Cost < Optimum) {
            if (FirstNode->InputSuc) {
                Node *N = FirstNode;
                while ((N = N->InputSuc = N->Suc) != FirstNode);
            }
            Optimum = Cost;
            printff("*** New optimum = " GainFormat " ***\n\n", Optimum);
        }
        Time = fabs(GetTime() - LastTime);
        UpdateStatistics(Cost, Time);
        if (TraceLevel >= 1 && Cost != PLUS_INFINITY) {
            printff("Run %d: Cost = " GainFormat, Run, Cost);
            if (Optimum != MINUS_INFINITY && Optimum != 0)
                printff(", Gap = %0.4f%%",
                        100.0 * (Cost - Optimum) / Optimum);
            printff(", Time = %0.2f sec. %s\n\n", Time,
                    Cost < Optimum ? "<" : Cost == Optimum ? "=" : "");
        }
        if (PopulationSize >= 2 &&
                (PopulationSize == MaxPopulationSize ||
                 Run >= 2 * MaxPopulationSize) && Run < Runs) {
            Node *N;
            int Parent1, Parent2;
            Parent1 = LinearSelection(PopulationSize, 1.25);
            do
                Parent2 = LinearSelection(PopulationSize, 1.25);
            while (Parent2 == Parent1);
            ApplyCrossover(Parent1, Parent2);
            N = FirstNode;
            do {
                int d = C(N, N->Suc);
                AddCandidate(N, N->Suc, d, INT_MAX);
                AddCandidate(N->Suc, N, d, INT_MAX);
                N = N->InitialSuc = N->Suc;
            }
            while (N != FirstNode);
        }
        SRandom(++Seed);
    }
    PrintStatistics();
    return EXIT_SUCCESS;
}
void ChooseInitialTour()
{
    Node *N, *NextN, *FirstAlternative, *Last;
    Candidate *NN;
    int Alternatives, Count, i;

    if (KickType > 0 && Kicks > 0 && Trial > 1) {
        for (Last = FirstNode; (N = Last->BestSuc) != FirstNode; Last = N)
            Follow(N, Last);
        for (i = 1; i <= Kicks; i++)
            KSwapKick(KickType);
        return;
    }
    if (Trial == 1 && (!FirstNode->InitialSuc || InitialTourFraction < 1)) {
        if (InitialTourAlgorithm == BORUVKA ||
            InitialTourAlgorithm == GREEDY ||
            InitialTourAlgorithm == MOORE ||
            InitialTourAlgorithm == NEAREST_NEIGHBOR ||
            InitialTourAlgorithm == QUICK_BORUVKA ||
            InitialTourAlgorithm == SIERPINSKI) {
            GainType Cost = InitialTourAlgorithm == MOORE ||
                InitialTourAlgorithm == SIERPINSKI ?
                SFCTour(InitialTourAlgorithm) : GreedyTour();
            if (MaxTrials == 0) {
                BetterCost = Cost;
                RecordBetterTour();
            }
            if (!FirstNode->InitialSuc)
                return;
        }
    }

Start:
    /* Mark all nodes as "not chosen" by setting their V field to zero */
    N = FirstNode;
    do
        N->V = 0;
    while ((N = N->Suc) != FirstNode);
    Count = 0;

    /* Choose FirstNode without two incident fixed or common candidate edges */
    do {
        if (FixedOrCommonCandidates(N) < 2)
            break;
    }
    while ((N = N->Suc) != FirstNode);
    if (ProblemType == ATSP && N->Id <= DimensionSaved)
        N += DimensionSaved;
    FirstNode = N;

    /* Move nodes with two incident fixed or common candidate edges in 
       front of FirstNode */
    for (Last = FirstNode->Pred; N != Last; N = NextN) {
        NextN = N->Suc;
        if (FixedOrCommonCandidates(N) == 2)
            Follow(N, Last);
    }

    /* Mark FirstNode as chosen */
    FirstNode->V = 1;
    N = FirstNode;

    /* Loop as long as not all nodes have been chosen */
    while (N->Suc != FirstNode) {
        FirstAlternative = 0;
        Alternatives = 0;
        Count++;

        /* Case A */
        for (NN = N->CandidateSet; (NextN = NN->To); NN++) {
            if (!NextN->V && Fixed(N, NextN)) {
                Alternatives++;
                NextN->Next = FirstAlternative;
                FirstAlternative = NextN;
            }
        }
        if (Alternatives == 0 && MergeTourFiles > 1) {
            for (NN = N->CandidateSet; (NextN = NN->To); NN++) {
                if (!NextN->V && IsCommonEdge(N, NextN)) {
                    Alternatives++;
                    NextN->Next = FirstAlternative;
                    FirstAlternative = NextN;
                }
            }
        }
        if (Alternatives == 0 && FirstNode->InitialSuc && Trial == 1 &&
            Count <= InitialTourFraction * Dimension) {
            /* Case B */
            for (NN = N->CandidateSet; (NextN = NN->To); NN++) {
                if (!NextN->V && InInitialTour(N, NextN)) {
                    Alternatives++;
                    NextN->Next = FirstAlternative;
                    FirstAlternative = NextN;
                }
            }
        }
        if (Alternatives == 0 && Trial > 1 &&
            ProblemType != HCP && ProblemType != HPP) {
            /* Case C */
            for (NN = N->CandidateSet; (NextN = NN->To); NN++) {
                if (!NextN->V && FixedOrCommonCandidates(NextN) < 2 &&
                    NN->Alpha == 0 && (InBestTour(N, NextN) ||
                                       InNextBestTour(N, NextN))) {
                    Alternatives++;
                    NextN->Next = FirstAlternative;
                    FirstAlternative = NextN;
                }
            }
        }
        if (Alternatives == 0) {
            /* Case D */
            for (NN = N->CandidateSet; (NextN = NN->To); NN++) {
                if (!NextN->V && FixedOrCommonCandidates(NextN) < 2) {
                    Alternatives++;
                    NextN->Next = FirstAlternative;
                    FirstAlternative = NextN;
                }
            }
        }
        if (Alternatives == 0) {
            /* Case E (actually not really a random choice) */
            NextN = N->Suc;
            while ((FixedOrCommonCandidates(NextN) == 2 || Forbidden(N, NextN))
                   && NextN->Suc != FirstNode)
                NextN = NextN->Suc;
            if (FixedOrCommonCandidates(NextN) == 2 || Forbidden(N, NextN)) {
                FirstNode = FirstNode->Suc;
                goto Start;
            }
        } else {
            NextN = FirstAlternative;
            if (Alternatives > 1) {
                /* Select NextN at random among the alternatives */
                i = Random() % Alternatives;
                while (i--)
                    NextN = NextN->Next;
            }
        }
        /* Include NextN as the successor of N */
        Follow(NextN, N);
        N = NextN;
        N->V = 1;
    }
    if (Forbidden(N, N->Suc)) {
        FirstNode = FirstNode->Suc;
        goto Start;
    }
    if (MaxTrials == 0) {
        GainType Cost = 0;
        N = FirstNode;
        do
            Cost += C(N, N->Suc) - N->Pi - N->Suc->Pi;
        while ((N = N->Suc) != FirstNode);
        Cost /= Precision;
        if (Cost < BetterCost) {
            BetterCost = Cost;
            RecordBetterTour();
        }
    }
}
Beispiel #3
0
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;
}
Beispiel #4
0
int tsp_lkh()
{
	GainType Cost, OldOptimum;
	double Time, LastTime = GetTime();

	/* Read the specification of the problem */


	ReadParameters();
	MaxMatrixDimension = 10000;

	init();


	AllocateStructures();
	CreateCandidateSet();
	InitializeStatistics();


	BestCost = PLUS_INFINITY;



	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 = MergeTourWithBestTour();
		if (Cost < BestCost) {
			BestCost = Cost;
			RecordBetterTour();
			RecordBestTour();

		}
		OldOptimum = Optimum;
		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 (StopAtOptimum && Cost == OldOptimum && MaxPopulationSize >= 1) {
			Runs = Run;
			break;
		}
		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 {
				if (ProblemType != HCP && ProblemType != HPP) {
					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();

	for (int i = 0; i < TSP_N; i++)
	{
		TSP_RESULT[i] = BestTour[i] - 1;
	}
	//		printf("%d -¡·",BestTour[i]-1);

	return BestCost;
}
Beispiel #5
0
ReturnFlag LKH::LKHAlg::run_()
{
	GainType Cost, OldOptimum;
    double Time, LastTime = GetTime();

    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();
    }
    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,this);
                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,this);
                    if (TraceLevel >= 1)
                        PrintPopulation(this);
                } else if (Cost < Fitness.get()[*PopulationSize - 1]) {
                    i = ReplacementIndividual(Cost,this);
                    ReplaceIndividualWithTour(i, Cost,this);
                    if (TraceLevel >= 1)
                        PrintPopulation(this);
                }
            }
        } else if (Run > 1)
            Cost = MergeBetterTourWithBestTour();
        if (Cost < BestCost) {
            BestCost = Cost;
            RecordBetterTour();
            RecordBestTour();
            WriteTour(OutputTourFileName, BestTour, BestCost);
            WriteTour(TourFileName, BestTour, BestCost);
        }
        OldOptimum = Optimum;
        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, Global::msp_global->m_runId, 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 ? "=" : "");
			printff(", Time = %0.2f sec. \n", Time);
        }
        if (StopAtOptimum && Cost == OldOptimum && *MaxPopulationSize >= 1) {
            Runs = Run;
            break;
        }
        if (*PopulationSize >= 2 &&
            (*PopulationSize == *MaxPopulationSize ||
             Run >= 2 * *MaxPopulationSize) && Run < Runs) {
            Node *N;
            int Parent1, Parent2;
            Parent1 = LinearSelection(*PopulationSize, 1.25,this);
            do
                Parent2 = LinearSelection(*PopulationSize, 1.25,this);
            while (Parent2 == Parent1);
            ApplyCrossover(Parent1, Parent2,this);
            N = FirstNode;
            do {
                int d = (this->*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);
        }
		mv_cost[Global::msp_global->m_runId]=Cost;
        SRandom(++Seed);
    }
 //   PrintStatistics();
	freeAll();
	FreeStructures();
	return Return_Terminate;
}