Exemple #1
0
        public void ScrambleMoveEvaluatorTest()
        {
            for (int i = 0; i < 500; i++)
            {
                ScrambleMove scramble = StochasticScrambleMultiMoveGenerator.GenerateRandomMove(assignment, random);

                // SYMMETRIC MATRICES
                double before = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
                double move   = QAPScrambleMoveEvaluator.Apply(assignment, scramble, symmetricWeights, symmetricDistances);
                ScrambleManipulator.Apply(assignment, scramble.StartIndex, scramble.ScrambledIndices);
                double after = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on symmetric matrices");

                // ASYMMETRIC MATRICES
                before = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
                move   = QAPScrambleMoveEvaluator.Apply(assignment, scramble, asymmetricWeights, asymmetricDistances);
                ScrambleManipulator.Apply(assignment, scramble.StartIndex, scramble.ScrambledIndices);
                after = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on asymmetric matrices");

                // NON-ZERO DIAGONAL ASYMMETRIC MATRICES
                before = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                move   = QAPScrambleMoveEvaluator.Apply(assignment, scramble, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                ScrambleManipulator.Apply(assignment, scramble.StartIndex, scramble.ScrambledIndices);
                after = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on non-zero diagonal matrices");
            }
        }
Exemple #2
0
        public void InversionMoveEvaluatorTest()
        {
            for (int i = 0; i < 500; i++)
            {
                int index1 = random.Next(ProblemSize);
                int index2 = random.Next(ProblemSize);
                if (index1 > index2)
                {
                    int h = index1; index1 = index2; index2 = h;
                }

                // SYMMETRIC MATRICES
                double before = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
                InversionManipulator.Apply(assignment, Math.Min(index1, index2), Math.Max(index1, index2));
                double after = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
                double move  = QAPInversionMoveEvaluator.Apply(assignment, new InversionMove(index1, index2, assignment), symmetricWeights, symmetricDistances);
                Assert.IsTrue(move.IsAlmost(before - after), "Failed on symmetric matrices");

                // ASYMMETRIC MATRICES
                before = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
                Permutation clone = (Permutation)assignment.Clone();
                InversionManipulator.Apply(assignment, index1, index2);
                after = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
                move  = QAPInversionMoveEvaluator.Apply(clone, new InversionMove(index1, index2), asymmetricWeights, asymmetricDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on asymmetric matrices");

                // NON-ZERO DIAGONAL ASYMMETRIC MATRICES
                before = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                clone  = (Permutation)assignment.Clone();
                InversionManipulator.Apply(assignment, index1, index2);
                after = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                move  = QAPInversionMoveEvaluator.Apply(clone, new InversionMove(index1, index2), nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on non-zero diagonal matrices");
            }
        }
Exemple #3
0
        public void TranslocationMoveEvaluatorTest()
        {
            for (int i = 0; i < 500; i++)
            {
                int index1           = random.Next(assignment.Length - 1);
                int index2           = random.Next(index1 + 1, assignment.Length);
                int insertPointLimit = assignment.Length - index2 + index1 - 1; // get insertion point in remaining part
                int insertPoint;
                if (insertPointLimit > 0)
                {
                    insertPoint = random.Next(insertPointLimit);
                }
                else
                {
                    insertPoint = 0;
                }

                // SYMMETRIC MATRICES
                double      before = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
                Permutation clone  = new Cloner().Clone(assignment);
                TranslocationManipulator.Apply(assignment, index1, index2, insertPoint);
                double after = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
                double move  = QAPTranslocationMoveEvaluator.Apply(clone, new TranslocationMove(index1, index2, insertPoint, assignment), symmetricWeights, symmetricDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on symmetric matrices");

                // ASYMMETRIC MATRICES
                before = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
                clone  = new Cloner().Clone(assignment);
                TranslocationManipulator.Apply(assignment, index1, index2, insertPoint);
                after = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
                move  = QAPTranslocationMoveEvaluator.Apply(clone, new TranslocationMove(index1, index2, insertPoint, assignment), asymmetricWeights, asymmetricDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on asymmetric matrices");

                // NON-ZERO DIAGONAL ASYMMETRIC MATRICES
                before = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                clone  = new Cloner().Clone(assignment);
                TranslocationManipulator.Apply(assignment, index1, index2, insertPoint);
                after = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                move  = QAPTranslocationMoveEvaluator.Apply(clone, new TranslocationMove(index1, index2, insertPoint, assignment), nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on non-zero diagonal matrices");
            }
        }
Exemple #4
0
        public void Swap2MoveEvaluatorFastEvaluationTest()
        {
            for (int i = 0; i < 500; i++)
            {
                Swap2Move   lastMove       = new Swap2Move(random.Next(ProblemSize), random.Next(ProblemSize));
                Permutation prevAssignment = (Permutation)assignment.Clone();
                Swap2Manipulator.Apply(assignment, lastMove.Index1, lastMove.Index2);
                Permutation nextAssignment = (Permutation)assignment.Clone();
                Swap2Move   currentMove    = new Swap2Move(random.Next(ProblemSize), random.Next(ProblemSize));
                Swap2Manipulator.Apply(nextAssignment, currentMove.Index1, currentMove.Index2);

                double moveBefore = QAPSwap2MoveEvaluator.Apply(prevAssignment, currentMove, symmetricWeights, symmetricDistances);
                double moveAfter  = QAPSwap2MoveEvaluator.Apply(assignment, currentMove,
                                                                moveBefore, symmetricWeights, symmetricDistances, lastMove);
                double before = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
                double after  = QAPEvaluator.Apply(nextAssignment, symmetricWeights, symmetricDistances);

                Assert.IsTrue(moveAfter.IsAlmost(after - before), "Failed on symmetric matrices: " + Environment.NewLine
                              + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveAfter + ".");

                moveBefore = QAPSwap2MoveEvaluator.Apply(prevAssignment, currentMove, asymmetricWeights, asymmetricDistances);
                moveAfter  = QAPSwap2MoveEvaluator.Apply(assignment, currentMove,
                                                         moveBefore, asymmetricWeights, asymmetricDistances, lastMove);
                before = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
                after  = QAPEvaluator.Apply(nextAssignment, asymmetricWeights, asymmetricDistances);

                Assert.IsTrue(moveAfter.IsAlmost(after - before), "Failed on asymmetric matrices: " + Environment.NewLine
                              + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveAfter + ".");

                moveBefore = QAPSwap2MoveEvaluator.Apply(prevAssignment, currentMove, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                moveAfter  = QAPSwap2MoveEvaluator.Apply(assignment, currentMove,
                                                         moveBefore, nonZeroDiagonalWeights, nonZeroDiagonalDistances, lastMove);
                before = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                after  = QAPEvaluator.Apply(nextAssignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);

                Assert.IsTrue(moveAfter.IsAlmost(after - before), "Failed on non-zero diagonal matrices: " + Environment.NewLine
                              + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveAfter + ".");
            }
        }
Exemple #5
0
    public override void Main()
    {
        DateTime start = DateTime.UtcNow;

        QuadraticAssignmentProblem qap;

        if (vars.Contains("qap"))
        {
            qap = vars.qap;
        }
        else
        {
            var provider = new DreznerQAPInstanceProvider();
            var instance = provider.GetDataDescriptors().Single(x => x.Name == "dre56");
            var data     = provider.LoadData(instance);
            qap = new QuadraticAssignmentProblem();
            qap.Load(data);
            vars.qap = qap;
        }

        const uint   seed         = 0;
        const int    popSize      = 100;
        const int    generations  = 1000;
        const double mutationRate = 0.05;

        var random     = new MersenneTwister(seed);
        var population = new Permutation[popSize];
        var qualities  = new double[popSize];
        var nextGen    = new Permutation[popSize];
        var nextQual   = new double[popSize];

        var qualityChart = new DataTable("Quality Chart");
        var qualityRow   = new DataRow("Best Quality");

        qualityChart.Rows.Add(qualityRow);
        vars.qualityChart = qualityChart;

        for (int i = 0; i < popSize; i++)
        {
            population[i] = new Permutation(PermutationTypes.Absolute, qap.Weights.Rows, random);
            qualities[i]  = QAPEvaluator.Apply(population[i], qap.Weights, qap.Distances);
        }
        var bestQuality           = qualities.Min();
        var bestQualityGeneration = 0;

        for (int g = 0; g < generations; g++)
        {
            var parents = population.SampleProportional(random, 2 * popSize, qualities, windowing: true, inverseProportional: true).ToArray();
            for (int i = 0; i < popSize; i++)
            {
                nextGen[i] = PartiallyMatchedCrossover.Apply(random, parents[i * 2], parents[i * 2 + 1]);
                if (random.NextDouble() < mutationRate)
                {
                    Swap2Manipulator.Apply(random, nextGen[i]);
                }
                nextQual[i] = QAPEvaluator.Apply(nextGen[i], qap.Weights, qap.Distances);
                if (nextQual[i] < bestQuality)
                {
                    bestQuality           = nextQual[i];
                    bestQualityGeneration = g;
                }
            }
            qualityRow.Values.Add(bestQuality);
            Array.Copy(nextGen, population, popSize);
            Array.Copy(nextQual, qualities, popSize);
        }

        vars.elapsed            = new TimeSpanValue(DateTime.UtcNow - start);
        vars.bestQuality        = bestQuality;
        vars.bestQualityFoundAt = bestQualityGeneration;
    }