public static double EvaluateMove(Permutation tour, InversionMove move, Func <int, int, double> distance, DoubleArray probabilities)
        {
            var afterMove = (Permutation)tour.Clone();

            InversionManipulator.Apply(afterMove, move.Index1, move.Index2);
            return(AnalyticalProbabilisticTravelingSalesmanProblem.Evaluate(afterMove, distance, probabilities));
        }
        public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, DoubleArray probabilities, CancellationToken cancellation)
        {
            var distanceM = (DistanceMatrix)distances;
            Func <int, int, double> distance = (a, b) => distanceM[a, b];

            for (var i = localIterations.Value; i < maxIterations; i++)
            {
                InversionMove bestMove    = null;
                var           bestQuality = quality.Value; // we have to make an improvement, so current quality is the baseline
                var           evaluations = 0.0;
                foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment))
                {
                    var moveQuality = PTSPAnalyticalInversionMoveEvaluator.EvaluateMove(assignment, move, distance, probabilities);
                    evaluations++;
                    if (maximization && moveQuality > bestQuality ||
                        !maximization && moveQuality < bestQuality)
                    {
                        bestQuality = moveQuality;
                        bestMove    = move;
                    }
                }
                evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
                if (bestMove == null)
                {
                    break;
                }
                InversionManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2);
                quality.Value = bestQuality;
                localIterations.Value++;
                cancellation.ThrowIfCancellationRequested();
            }
        }
Beispiel #3
0
        public static double Apply(Permutation assignment, InversionMove move, DoubleMatrix weights, DoubleMatrix distances)
        {
            if (move.Index1 == move.Index2)
            {
                return(0);
            }
            double moveQuality = 0;
            int    min         = Math.Min(move.Index1, move.Index2);
            int    max         = Math.Max(move.Index1, move.Index2);

            for (int i = min; i <= max; i++)
            {
                int locI    = assignment[i];
                int newlocI = assignment[max - i + min];

                for (int j = 0; j < assignment.Length; j++)
                {
                    int locJ = assignment[j];
                    if (j >= min && j <= max)
                    {
                        int newlocJ = assignment[max - j + min];
                        moveQuality += weights[i, j] * (distances[newlocI, newlocJ] - distances[locI, locJ]);
                    }
                    else
                    {
                        moveQuality += weights[i, j] * (distances[newlocI, locJ] - distances[locI, locJ]);
                        moveQuality += weights[j, i] * (distances[locJ, newlocI] - distances[locJ, locI]);
                    }
                }
            }
            return(moveQuality);
        }
Beispiel #4
0
        public static double EvaluateByCoordinates(Permutation permutation, InversionMove move, DoubleMatrix coordinates, TSPInversionMovePathEvaluator evaluator)
        {
            int edge1source = permutation.GetCircular(move.Index1 - 1);
            int edge1target = permutation[move.Index1];
            int edge2source = permutation[move.Index2];
            int edge2target = permutation.GetCircular(move.Index2 + 1);

            if (move.Index2 - move.Index1 >= permutation.Length - 2)
            {
                return(0);
            }
            double moveQuality = 0;

            // remove two edges
            moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
                                                       coordinates[edge1target, 0], coordinates[edge1target, 1]);
            moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
                                                       coordinates[edge2target, 0], coordinates[edge2target, 1]);
            // add two edges
            moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
                                                       coordinates[edge2source, 0], coordinates[edge2source, 1]);
            moveQuality += evaluator.CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1],
                                                       coordinates[edge2target, 0], coordinates[edge2target, 1]);
            return(moveQuality);
        }
Beispiel #5
0
 public static void Improve(Permutation assignment, DoubleMatrix weights, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, CancellationToken cancellation)
 {
     for (int i = localIterations.Value; i < maxIterations; i++)
     {
         InversionMove bestMove    = null;
         double        bestQuality = 0; // we have to make an improvement, so 0 is the baseline
         double        evaluations = 0.0;
         foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment))
         {
             double moveQuality = QAPInversionMoveEvaluator.Apply(assignment, move, weights, distances);
             evaluations += 2 * (move.Index2 - move.Index1 + 1) / (double)assignment.Length;
             if (maximization && moveQuality > bestQuality ||
                 !maximization && moveQuality < bestQuality)
             {
                 bestQuality = moveQuality;
                 bestMove    = move;
             }
         }
         evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
         if (bestMove == null)
         {
             break;
         }
         InversionManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2);
         quality.Value += bestQuality;
         localIterations.Value++;
         cancellation.ThrowIfCancellationRequested();
     }
 }
Beispiel #6
0
        public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, ItemList <BoolArray> realizations, CancellationToken cancellation)
        {
            var distanceM = (DistanceMatrix)distances;
            Func <int, int, double> distance = (a, b) => distanceM[a, b];

            for (var i = localIterations.Value; i < maxIterations; i++)
            {
                InversionMove bestMove    = null;
                double        bestQuality = 0; // we have to make an improvement, so 0 is the baseline
                double        evaluations = 0.0;
                foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment))
                {
                    double moveQuality = PTSPEstimatedInversionMoveEvaluator.EvaluateMove(assignment, move, distance, realizations);
                    evaluations += realizations.Count * 4.0 / (assignment.Length * assignment.Length);
                    if (maximization && moveQuality > bestQuality ||
                        !maximization && moveQuality < bestQuality)
                    {
                        bestQuality = moveQuality;
                        bestMove    = move;
                    }
                }
                evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
                if (bestMove == null)
                {
                    break;
                }
                InversionManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2);
                quality.Value += bestQuality;
                localIterations.Value++;
                cancellation.ThrowIfCancellationRequested();
            }
        }
Beispiel #7
0
        public override IOperation Apply()
        {
            InversionMove move = InversionMoveParameter.ActualValue;

            if (move == null)
            {
                throw new InvalidOperationException("Inversion move is not found.");
            }
            Permutation  assignment = PermutationParameter.ActualValue;
            DoubleMatrix distances  = DistancesParameter.ActualValue;
            DoubleMatrix weights    = WeightsParameter.ActualValue;

            double moveQuality = QualityParameter.ActualValue.Value;

            moveQuality += Apply(assignment, move, weights, distances);
            MoveQualityParameter.ActualValue = new DoubleValue(moveQuality);
            return(base.Apply());
        }
Beispiel #8
0
        public static double EvaluateByDistanceMatrix(Permutation permutation, InversionMove move, DistanceMatrix distanceMatrix)
        {
            int edge1source = permutation.GetCircular(move.Index1 - 1);
            int edge1target = permutation[move.Index1];
            int edge2source = permutation[move.Index2];
            int edge2target = permutation.GetCircular(move.Index2 + 1);

            if (move.Index2 - move.Index1 >= permutation.Length - 2)
            {
                return(0);
            }
            double moveQuality = 0;

            // remove two edges
            moveQuality -= distanceMatrix[edge1source, edge1target];
            moveQuality -= distanceMatrix[edge2source, edge2target];
            // add two edges
            moveQuality += distanceMatrix[edge1source, edge2source];
            moveQuality += distanceMatrix[edge1target, edge2target];
            return(moveQuality);
        }
Beispiel #9
0
        public static double EvaluateMove(Permutation tour, InversionMove move, Func <int, int, double> distance, ItemList <BoolArray> realizations)
        {
            double moveQuality = 0;
            var    edges       = new int[4];
            var    indices     = new int[4];

            edges[0]   = tour.GetCircular(move.Index1 - 1);
            indices[0] = move.Index1 - 1;
            if (indices[0] == -1)
            {
                indices[0] = tour.Length - 1;
            }
            edges[1]   = tour[move.Index1];
            indices[1] = move.Index1;
            edges[2]   = tour[move.Index2];
            indices[2] = move.Index2;
            edges[3]   = tour.GetCircular(move.Index2 + 1);
            indices[3] = move.Index2 + 1;
            if (indices[3] == tour.Length + 1)
            {
                indices[3] = 0;
            }
            var aPosteriori = new int[4];

            foreach (var realization in realizations)
            {
                for (var i = 0; i < edges.Length; i++)
                {
                    if (realization[edges[i]])
                    {
                        aPosteriori[i] = edges[i];
                    }
                    else
                    {
                        var j = 1;
                        if (i % 2 == 0)
                        {
                            // find nearest predecessor in realization if source edge
                            while (!realization[tour.GetCircular(indices[i] - j)])
                            {
                                j++;
                            }
                            aPosteriori[i] = tour.GetCircular(indices[i] - j);
                        }
                        else
                        {
                            // find nearest successor in realization if target edge
                            while (!realization[tour.GetCircular(indices[i] + j)])
                            {
                                j++;
                            }
                            aPosteriori[i] = tour.GetCircular(indices[i] + j);
                        }
                    }
                }
                // compute cost difference between the two a posteriori solutions
                if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3]))
                {
                    moveQuality = moveQuality + distance(aPosteriori[0], aPosteriori[2]) + distance(aPosteriori[1], aPosteriori[3])
                                  - distance(aPosteriori[0], aPosteriori[1]) - distance(aPosteriori[2], aPosteriori[3]);
                }
                Array.Clear(aPosteriori, 0, aPosteriori.Length);
            }
            // return average of cost differences
            return(moveQuality / realizations.Count);
        }