コード例 #1
0
        /// <summary>
        /// Calculates an efficient path between all waypoints based on time or distance.
        /// </summary>
        /// <param name="matrix">A precalculated distance matrix (n x n).</param>
        /// <param name="tspOptimization">The metric in which to base the TSP algorithm.</param>
        /// <returns>An efficient path between all waypoints based on time or distance.</returns>
        public override async Task <TspResult> Solve(DistanceMatrix matrix, TspOptimizationType tspOptimization)
        {
            return(await Task <TspResult> .Run <TspResult>(() =>
            {
                var tour = new int[matrix.Origins.Count];

                for (var i = 0; i < matrix.Origins.Count; i++)
                {
                    tour[i] = i;
                }

                double minWeight = double.MaxValue;
                double weight;
                int[] minTour = tour;

                while (NextPermutation(tour))
                {
                    //Break out if the first location isn't in the first position.
                    if (tour[0] != 0)
                    {
                        break;
                    }

                    if (tspOptimization == TspOptimizationType.TravelTime)
                    {
                        weight = matrix.GetEdgeTime(tour, true);
                    }
                    else
                    {
                        weight = matrix.GetEdgeDistance(tour, true);
                    }

                    if (weight < minWeight)
                    {
                        minWeight = weight;
                        minTour = (int[])tour.Clone();
                    }
                }

                return new TspResult()
                {
                    DistanceMatrix = matrix,
                    OptimizedWeight = minWeight,
                    OptimizedWaypoints = GetOptimizedWaypoints(matrix.Origins, minTour)
                };
            }));
        }
コード例 #2
0
 ///<summary>
 ///  Solves the travelling salesmen problem.
 /// </summary>
 /// <param name="matrix">A precalculated distance matrix (n x n).</param>
 /// <param name="tspOptimization">The metric in which to base the TSP algorithm.</param>
 /// <returns>An efficient path between all waypoints based on time or distance.</returns>
 public static async Task <TspResult> Solve(DistanceMatrix matrix, TspOptimizationType tspOptimization)
 {
     return(await GetTspAlgorithm(matrix.Origins).Solve(matrix, tspOptimization).ConfigureAwait(false));
 }
コード例 #3
0
        /// <summary>
        /// Calculates an efficient path between all waypoints based on time or distance.
        /// </summary>
        /// <param name="matrix">A precalculated distance matrix (n x n).</param>
        /// <param name="tspOptimization">The metric in which to base the TSP algorithm.</param>
        /// <returns>An efficient path between all waypoints based on time or distance.</returns>
        public override async Task <TspResult> Solve(DistanceMatrix matrix, TspOptimizationType tspOptimization)
        {
            return(await Task <TspResult> .Run <TspResult>(() =>
            {
                int population = matrix.Origins.Count;

                double[] weight = new double[population];

                var minTour = new int[population];

                int[,] chromosome = new int[population, population];

                double minWeight = double.MaxValue;

                for (int p = 0; p < population; p++)
                {
                    bool[] used = new bool[population];
                    int[] currentOrder = new int[population];

                    for (int n = 0; n < population; n++)
                    {
                        used[n] = false;
                    }

                    for (int n = 0; n < population; n++)
                    {
                        int i;

                        do
                        {
                            i = random.Next(population);
                        }while (used[i]);

                        used[i] = true;
                        currentOrder[n] = i;
                    }

                    for (int n = 0; n < population; n++)
                    {
                        chromosome[p, n] = currentOrder[n];
                    }

                    if (tspOptimization == TspOptimizationType.TravelTime)
                    {
                        weight[p] = matrix.GetEdgeTime(currentOrder, true);
                    }
                    else
                    {
                        weight[p] = matrix.GetEdgeDistance(currentOrder, true);
                    }

                    if (weight[p] < minWeight)
                    {
                        minWeight = weight[p];

                        for (int n = 0; n < population; n++)
                        {
                            minTour[n] = chromosome[p, n];
                        }
                    }
                }

                for (int g = 0; g < Generations; g++)
                {
                    if (random.NextDouble() < MutationRate)
                    {
                        int i, j, parent1, parent2;
                        int[] p1 = new int[population];
                        int[] p2 = new int[population];
                        int[] o1 = new int[population];
                        int[] o2 = new int[population];

                        i = random.Next(population);
                        j = random.Next(population);

                        if (weight[i] < weight[j])
                        {
                            parent1 = i;
                        }
                        else
                        {
                            parent1 = j;
                        }

                        i = random.Next(population);
                        j = random.Next(population);

                        if (weight[i] < weight[j])
                        {
                            parent2 = i;
                        }
                        else
                        {
                            parent2 = j;
                        }

                        for (i = 0; i < population; i++)
                        {
                            p1[i] = chromosome[parent1, i];
                            p2[i] = chromosome[parent2, i];
                        }

                        int cp1 = -1, cp2 = -1;

                        do
                        {
                            cp1 = random.Next(population);
                            cp2 = random.Next(population);
                        } while (cp1 == cp2 || cp1 > cp2);

                        Crossover(cp1, cp2, p1, p2, o1, o2, population, random);

                        double o1Fitness;

                        if (tspOptimization == TspOptimizationType.TravelTime)
                        {
                            o1Fitness = matrix.GetEdgeTime(o1, true);
                        }
                        else
                        {
                            o1Fitness = matrix.GetEdgeDistance(o1, true);
                        }

                        if (o1Fitness < weight[parent1])
                        {
                            for (i = 0; i < population; i++)
                            {
                                chromosome[parent1, i] = o1[i];
                            }
                        }

                        double o2Fitness;

                        if (tspOptimization == TspOptimizationType.TravelTime)
                        {
                            o2Fitness = matrix.GetEdgeTime(o2, true);
                        }
                        else
                        {
                            o2Fitness = matrix.GetEdgeDistance(o2, true);
                        }

                        if (o2Fitness < weight[parent2])
                        {
                            for (i = 0; i < population; i++)
                            {
                                chromosome[parent2, i] = o2[i];
                            }
                        }

                        for (int p = 0; p < population; p++)
                        {
                            if (weight[p] < minWeight)
                            {
                                minWeight = weight[p];

                                for (int n = 0; n < population; n++)
                                {
                                    minTour[n] = chromosome[p, n];
                                }
                            }
                        }
                    }
                    else
                    {
                        int i, j, p;
                        int[] child = new int[population];

                        i = random.Next(population);
                        j = random.Next(population);

                        if (weight[i] < weight[j])
                        {
                            p = i;
                        }
                        else
                        {
                            p = j;
                        }

                        double childWeight;

                        for (int n = 0; n < population; n++)
                        {
                            child[n] = chromosome[p, n];
                        }

                        do
                        {
                            i = random.Next(population);
                            j = random.Next(population);
                        }while (i == j);

                        int t = child[i];

                        child[i] = child[j];
                        child[j] = t;

                        if (tspOptimization == TspOptimizationType.TravelTime)
                        {
                            childWeight = matrix.GetEdgeTime(child, true);
                        }
                        else
                        {
                            childWeight = matrix.GetEdgeDistance(child, true);
                        }

                        int maxIndex = int.MaxValue;
                        double maxD = double.MinValue;

                        for (int q = 0; q < population; q++)
                        {
                            if (weight[q] >= maxD)
                            {
                                maxIndex = q;
                                maxD = weight[q];
                            }
                        }

                        int[] index = new int[population];
                        int count = 0;

                        for (int q = 0; q < population; q++)
                        {
                            if (weight[q] == maxD)
                            {
                                index[count++] = q;
                            }
                        }

                        maxIndex = index[random.Next(count)];

                        if (childWeight < weight[maxIndex])
                        {
                            weight[maxIndex] = childWeight;

                            for (int n = 0; n < population; n++)
                            {
                                chromosome[maxIndex, n] = child[n];
                            }

                            if (childWeight < minWeight)
                            {
                                minWeight = childWeight;

                                for (int n = 0; n < population; n++)
                                {
                                    minTour[n] = child[n];
                                }
                            }
                        }
                    }
                }

                //Ensure first point is the starting point. Indicies form a cycle, so just need to shift.
                if (minTour[0] != 0)
                {
                    var minTourList = minTour.ToList();
                    var startIdx = minTourList.IndexOf(0);

                    var order = new List <int>();
                    order.AddRange(minTourList.GetRange(startIdx, minTourList.Count - startIdx));
                    order.AddRange(minTourList.GetRange(0, startIdx));

                    minTour = order.ToArray();
                }

                return new TspResult()
                {
                    DistanceMatrix = matrix,
                    OptimizedWeight = minWeight,
                    OptimizedWaypoints = GetOptimizedWaypoints(matrix.Origins, minTour)
                };
            }));
        }
コード例 #4
0
 /// <summary>
 /// Calculates an efficient path between all waypoints based on time or distance.
 /// </summary>
 /// <param name="matrix">A precalculated distance matrix (n x n).</param>
 /// <param name="tspOptimization">The metric in which to base the TSP algorithm.</param>
 /// <returns>An efficient path between all waypoints based on time or distance.</returns>
 #pragma warning disable 1998
 public virtual async Task <TspResult> Solve(DistanceMatrix matrix, TspOptimizationType tspOptimization)
 {
     throw new NotImplementedException();
 }