Пример #1
0
        public void partialTwoOpt()
        {
            bool           startAgain   = false;
            PathCalculator calc         = new PathCalculator();
            int            iterations   = 0;
            int            bestDistance = length;

            do
            {
                startAgain = false;
                for (int i = 1; i < path.Count - 1; i++)
                {
                    if (startAgain)
                    {
                        break;
                    }
                    for (int j = i + 1; j < path.Count - 2; j++)
                    {
                        int dist = Params.distances[path[i - 1], path[i]] + Params.distances[path[j], path[j + 1]] - Params.distances[path[i - 1], path[j]] - Params.distances[path[i], path[j + 1]];
                        if (dist > 0)
                        {
                            path          = modifyPath(path, i, j);
                            bestDistance -= dist;
                            startAgain    = true;
                            break;
                        }
                    }
                }
                iterations++;
            } while (startAgain && iterations < 5);
        }
Пример #2
0
        public static List <int> tryInserting(List <int> path, HashSet <int> usedTowns)
        {
            List <int> currentPath = new List <int>(path);

            HashSet <int> availableTowns = new HashSet <int>(aT);

            foreach (int k in usedTowns)
            {
                availableTowns.Remove(k);
            }
            PathCalculator PO = new PathCalculator();
            double         currentPathLength = PO.calculateDistance(currentPath);
            double         currentProfit     = 0;

            foreach (int i in currentPath)
            {
                currentProfit += Parameters.profits[i];
                availableTowns.Remove(i);
            }
            double bestPossibleGain          = 0;
            int    bestPossibleGainIndex     = -1;
            int    bestPossibleGainTown      = -1;
            double bestPossibleGainLengthInc = 0;
            int    iterations = 0;

            do
            {
                iterations++;
                bestPossibleGain      = 0;
                bestPossibleGainIndex = 0;
                bestPossibleGainTown  = -1;
                foreach (int i in availableTowns)
                {
                    for (int x = 0; x < currentPath.Count - 1; x++)
                    {
                        double dist = Parameters.distances[currentPath[x], i] + Parameters.distances[i, currentPath[x + 1]] - Parameters.distances[currentPath[x], currentPath[x + 1]];
                        if (currentPathLength + dist <= Parameters.maxLength)
                        {
                            if (Parameters.profits[i] * Parameters.profits[i] * Parameters.profits[i] / (currentPathLength + dist) * Parameters.maxLength / (currentPathLength + dist) > bestPossibleGain)
                            {
                                bestPossibleGainLengthInc = Parameters.distances[currentPath[x], i] + Parameters.distances[i, currentPath[x + 1]] - Parameters.distances[currentPath[x], currentPath[x + 1]];
                                bestPossibleGain          = Parameters.profits[i] * Parameters.profits[i] * Parameters.profits[i] / (currentPathLength + dist) * Parameters.maxLength / (currentPathLength + dist);
                                bestPossibleGainIndex     = x;
                                bestPossibleGainTown      = i;
                            }
                        }
                    }
                }
                if (bestPossibleGainTown != -1)
                {
                    currentPath.Insert(bestPossibleGainIndex + 1, bestPossibleGainTown);
                    currentProfit += bestPossibleGain;
                    availableTowns.Remove(bestPossibleGainTown);
                    currentPathLength = PO.calculateDistance(currentPath);
                }
            } while (bestPossibleGain != 0 && currentPathLength <= Parameters.maxLength && iterations < Parameters.rand.Next(1));

            return(currentPath);
        }
Пример #3
0
        public static List <int> trySwapping(List <int> path)
        {
            List <int>     currentPath       = new List <int>(path);
            HashSet <int>  availableTowns    = new HashSet <int>(aT);
            PathCalculator PO                = new PathCalculator();
            List <int>     added             = new List <int>();
            List <int>     removed           = new List <int>();
            int            currentPathLength = PO.calculateDistance(currentPath);
            double         currentProfit     = 0;

            foreach (int i in currentPath)
            {
                currentProfit += Params.profits[i];
                availableTowns.Remove(i);
            }
            for (int i = 2; i < currentPath.Count - 1; i++)
            {
                if (currentPath[i] == 1)
                {
                    continue;
                }
                foreach (int k in availableTowns)
                {
                    if (Params.profits[k] >= Params.profits[path[i]])
                    {
                        if (Params.profits[k] == Params.profits[path[i]])
                        {
                            if (Params.distances[currentPath[i - 1], currentPath[i]] + Params.distances[currentPath[i], currentPath[i + 1]] > Params.distances[currentPath[i - 1], k] + Params.distances[k, currentPath[i + 1]])
                            {
                                added.Add(currentPath[i]);
                                removed.Add(k);
                                currentPath[i] = k;
                            }
                        }
                        else
                        {
                            if (currentPathLength - Params.distances[currentPath[i - 1], currentPath[i]] - Params.distances[currentPath[i], currentPath[i + 1]] + Params.distances[currentPath[i - 1], k] + Params.distances[k, currentPath[i + 1]] <= Params.maxLength)
                            {
                                added.Add(path[i]);
                                removed.Add(k);
                                currentPath[i] = k;
                            }
                        }
                    }
                }
                foreach (int x in added)
                {
                    availableTowns.Add(x);
                }
                foreach (int x in removed)
                {
                    availableTowns.Remove(x);
                }
                added.Clear();
                removed.Clear();
            }
            return(currentPath);
        }
Пример #4
0
        public void generateFixedIndividual(int startingTown, HashSet <int> usedTowns)
        {
            HashSet <int>    availableTowns = new HashSet <int>();
            ContainerForDuos bestTowns      = new ContainerForDuos(5);
            PathCalculator   calc           = new PathCalculator();

            double pathDistance = 0;

            for (int i = 0; i <= Parameters.numberOfTowns; i++)
            {
                if (i == startingTown || usedTowns.Contains(i))
                {
                    continue;
                }

                availableTowns.Add(i);
            }
            List <int> newPath = new List <int>();

            newPath.Add(startingTown);

            profit  = 0;
            profit += Parameters.profits[startingTown];
            do
            {
                int k = Parameters.rand.Next(Parameters.To, Parameters.Td);
                bestTowns = new ContainerForDuos(k);
                foreach (int i in availableTowns)
                {
                    double value = calculateValue(newPath[newPath.Count - 1], i, pathDistance, startingTown);
                    if (value != -1)
                    {
                        bestTowns.Add(new Duo(value, i));
                    }
                }
                if (bestTowns.Count == 0)
                {
                    pathDistance += Parameters.distances[newPath[newPath.Count - 1], startingTown];
                    newPath.Add(startingTown);
                    break;
                }
                else
                {
                    int t = Parameters.rand.Next(bestTowns.Count - 1);
                    pathDistance += Parameters.distances[newPath[newPath.Count - 1], bestTowns.town(t)];
                    newPath.Add(bestTowns.town(t));
                    profit += Parameters.profits[bestTowns.town(t)];
                    availableTowns.Remove(bestTowns.town(t));
                }
            }while (newPath[newPath.Count - 1] != startingTown);
            length = pathDistance;
            path   = newPath;
            insertCapital();
            partialTwoOpt(5);
            evaluatePath();
        }
Пример #5
0
        public static List <int> tryMoving(List <int> path)
        {
            List <int>     bestPath = new List <int>(path);
            PathCalculator calc     = new PathCalculator();
            double         bestPathProfit;
            double         newProfit = 0;
            int            bestPathDist;

            evaluatePath(bestPath, out bestPathDist, out bestPathProfit);
            for (int i = 1; i < bestPath.Count - 2; i++)
            {
                for (int j = 1; j < bestPath.Count - 3; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    int newDist = bestPathDist;
                    newProfit = 0;

                    if (j == i + 1)
                    {
                        newDist = newDist - Params.distances[bestPath[i - 1], bestPath[i]] + Params.distances[bestPath[i - 1], bestPath[j]] + Params.distances[bestPath[i], bestPath[j + 1]] - Params.distances[bestPath[j], bestPath[j + 1]];
                    }
                    else if (i == j + 1)
                    {
                        newDist += -Params.distances[bestPath[j - 1], bestPath[j]] + Params.distances[bestPath[j - 1], bestPath[j + 1]] + Params.distances[bestPath[j], bestPath[j + 1]];
                    }
                    else if (i > j)
                    {
                        newDist = newDist - Params.distances[bestPath[i - 1], bestPath[i]] - Params.distances[bestPath[i], bestPath[i + 1]]
                                  - Params.distances[bestPath[j], bestPath[j + 1]]
                                  + Params.distances[bestPath[i - 1], bestPath[i + 1]] + Params.distances[bestPath[j], bestPath[i]] + Params.distances[bestPath[i], bestPath[j + 1]];
                    }
                    else if (j > i)
                    {
                        newDist += -Params.distances[bestPath[j - 1], bestPath[j]] - Params.distances[bestPath[j], bestPath[j + 1]]
                                   - Params.distances[bestPath[i - 1], bestPath[i]]
                                   + Params.distances[bestPath[j - 1], bestPath[j + 1]] + Params.distances[bestPath[i - 1], bestPath[j]] + Params.distances[bestPath[j], bestPath[i]];
                    }
                    if (newDist >= Params.maxLength)
                    {
                        continue;
                    }
                    List <int> newPath = new List <int>(bestPath);

                    int tmp = newPath[i];
                    newPath.Remove(newPath[i]);
                    newPath.Insert(j, tmp);
                    newPath = tryInserting(newPath);
                    evaluatePath(newPath, out newDist, out newProfit);
                    if (newProfit > bestPathProfit)
                    {
                        bestPath       = newPath;
                        bestPathProfit = newProfit;
                        bestPathDist   = newDist;
                    }
                }
            }

            return(bestPath);
        }