Example #1
0
        public static void Verify(PathWithValues path, double[,] distances, int[] weights)
        {
            double newDist   = 0;
            int    newWeight = 0;
            var    visited   = new Dictionary <int, bool>();

            for (int i = 0; i < path.Nodes.Count - 1; i++)
            {
                newDist   += distances[path.GetNodeAt(i), path.GetNodeAt(i + 1)];
                newWeight += weights[path.GetNodeAt(i)];
                if (visited.ContainsKey(path.GetNodeAt(i)))
                {
                    throw new Exception();
                }
                visited[path.GetNodeAt(i)] = true;
            }
            newDist   += distances[path.GetNodeAt(path.Nodes.Count - 1), path.GetNodeAt(0)];
            newWeight += weights[path.GetNodeAt(path.Nodes.Count - 1)];

            if (Math.Abs(path.Distance - newDist) > 0.05)
            {
                throw new Exception();
            }
            if (newWeight != path.WeightsSum)
            {
                throw new Exception();
            }
        }
Example #2
0
        public static void RemoveRandomPath(PathWithValues path, double[,] distances, int[] weights, int degree)
        {
            PathGenerator.Verify(path, distances, weights);
            var random        = new Random();
            int startingPoint = 0;

            try
            {
                startingPoint = random.Next(2, path.Nodes.Count - 2 - (degree * 5));
            }
            catch (Exception)
            {
                return;
            }

            double dist       = 0;
            int    weightsSum = 0;


            for (int i = 0; i < 5 * degree; i++)
            {
                dist       -= distances[path.GetNodeAt(startingPoint + i), path.GetNodeAt(startingPoint + i + 1)];
                weightsSum -= weights[path.GetNodeAt(startingPoint + i + 1)];
            }

            dist -= distances[path.GetNodeAt(startingPoint + (5 * degree)),
                              path.GetNodeAt(startingPoint + 1 + (5 * degree))];
            dist += distances[path.GetNodeAt(startingPoint), path.GetNodeAt(startingPoint + 1 + (5 * degree))];

            path.Distance   += dist;
            path.WeightsSum += weightsSum;
            path.Nodes.RemoveRange(startingPoint + 1, degree * 5);
            PathGenerator.Verify(path, distances, weights);
        }
Example #3
0
        public static void LocalSearch2Opt(PathWithValues path, double[,] distances, int[] weights)
        {
            bool isBetter = true;

            while (isBetter)
            {
                isBetter = Opt2(path, distances, weights);
            }
        }
Example #4
0
        public static bool LocalSearchInsert(PathWithValues path, double[,] distances, int[] weights, int min)
        {
            bool isBetter = false;

            while (path.WeightsSum < min)
            {
                Insert(path, distances, weights);
                isBetter = true;
            }

            return(isBetter);
        }
Example #5
0
        private static bool Opt2(PathWithValues path, double[,] distances, int[] weights)
        {
            var tmpNodes = path.CloneNodes();

            int    totalNodesCount = path.Nodes.Count;
            double distDif         = 0;

            for (int i = 0; i < totalNodesCount - 2; i++)
            {
                for (int j = i + 2; j < totalNodesCount; j++)
                {
                    if (j == totalNodesCount - 1)
                    {
                        distDif = distances[path.GetNodeAt(i), path.GetNodeAt(j)] +
                                  distances[path.GetNodeAt(i + 1), path.GetNodeAt(0)]
                                  - (distances[path.GetNodeAt(i), path.GetNodeAt(i + 1)] +
                                     distances[path.GetNodeAt(j), path.GetNodeAt(0)]);
                    }
                    else
                    {
                        distDif = distances[path.GetNodeAt(i), path.GetNodeAt(j)] +
                                  distances[path.GetNodeAt(i + 1), path.GetNodeAt(j + 1)]
                                  - distances[path.GetNodeAt(i), path.GetNodeAt(i + 1)] -
                                  distances[path.GetNodeAt(j), path.GetNodeAt(j + 1)];
                    }

                    if (distDif < 0)
                    {
                        path.Distance += distDif;
                        for (int k = 0; k < j - i; k++)
                        {
                            path.Nodes[i + k + 1] = tmpNodes[j - k];
                        }

                        PathGenerator.Verify(path, distances, weights);
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #6
0
        private static void Insert(PathWithValues path, double[,] distances, int[] weights)
        {
            int nodesCount = weights.Count();


            double bestH             = 0;
            int    bestFirst         = 0;
            int    bestInsertedNode  = 0;
            double bestDistanceAdded = 0;
            int    bestWeight        = 0;

            int    first;
            int    second;
            double distanceAdded = 0;
            double newH          = 0;

            // h = weight/distance have to be big


            for (int i = 1; i < nodesCount; i++)
            {
                if (!path.Nodes.Contains(i))
                {
                    int weight = weights[i];
                    for (int j = 0; j < path.Nodes.Count - 1; j++)
                    {
                        first         = path.Nodes[j];
                        second        = path.Nodes[j + 1];
                        distanceAdded = distances[first, i] + distances[i, second] - distances[first, second];
                        if (distanceAdded <= 0)
                        {
                            newH = distanceAdded * -weight * 1000;
                        }
                        else
                        {
                            newH = weight / distanceAdded;
                        }

                        if (newH > bestH)
                        {
                            bestH             = newH;
                            bestFirst         = first;
                            bestInsertedNode  = i;
                            bestDistanceAdded = distanceAdded;
                            bestWeight        = weight;
                        }
                    }

                    first  = path.Nodes.Last();
                    second = path.Nodes.First();

                    distanceAdded = distances[first, i] + distances[i, second] - distances[first, second];


                    if (distanceAdded <= 0)
                    {
                        newH = distanceAdded * -weight * 1000;
                    }
                    else
                    {
                        newH = weight / distanceAdded;
                    }


                    if (newH > bestH)
                    {
                        bestH             = newH;
                        bestFirst         = first;
                        bestInsertedNode  = i;
                        bestDistanceAdded = distanceAdded;
                        bestWeight        = weight;
                    }
                }
            }

            path.Distance   += bestDistanceAdded;
            path.WeightsSum += bestWeight;
            int index = path.Nodes.IndexOf(bestFirst);

            if (index != path.Nodes.Count - 1)
            {
                path.Nodes.Insert(index + 1, bestInsertedNode);
            }
            else
            {
                path.Nodes.Add(bestInsertedNode);
            }

            PathGenerator.Verify(path, distances, weights);

            //return isBetter;
        }