public static void Improve(IRandom random, Permutation assignment, DoubleMatrix weights, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, int neighborhoodSize, CancellationToken cancellation)
 {
     for (int i = localIterations.Value; i < maxIterations; i++)
     {
         ScrambleMove bestMove    = null;
         double       bestQuality = 0; // we have to make an improvement, so 0 is the baseline
         double       evaluations = 0.0;
         for (int j = 0; j < neighborhoodSize; j++)
         {
             var    move        = StochasticScrambleMultiMoveGenerator.GenerateRandomMove(assignment, random);
             double moveQuality = QAPScrambleMoveEvaluator.Apply(assignment, move, weights, distances);
             evaluations += 2.0 * move.ScrambledIndices.Length / assignment.Length;
             if (maximization && moveQuality > bestQuality ||
                 !maximization && moveQuality < bestQuality)
             {
                 bestQuality = moveQuality;
                 bestMove    = move;
             }
         }
         evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
         if (bestMove == null)
         {
             break;
         }
         ScrambleManipulator.Apply(assignment, bestMove.StartIndex, bestMove.ScrambledIndices);
         quality.Value += bestQuality;
         localIterations.Value++;
         cancellation.ThrowIfCancellationRequested();
     }
 }
Beispiel #2
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");
            }
        }
        public void ScrambleManipulatorApplyTest()
        {
            TestRandom  random = new TestRandom();
            Permutation parent, expected;

            // The following test is based on an example from Larranaga, P. et al. 1999. Genetic Algorithms for the Travelling Salesman Problem: A Review of Representations and Operators. Artificial Intelligence Review, 13
            random.Reset();
            random.IntNumbers = new int[] { 3, 6, 1, 1, 1, 0 };
            parent            = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 });
            Assert.IsTrue(parent.Validate());

            expected = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 0, 1, 2, 4, 5, 6, 3, 7 });
            Assert.IsTrue(expected.Validate());
            ScrambleManipulator.Apply(random, parent);
            Assert.IsTrue(parent.Validate());
            Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, parent));
        }