public void FindRoute(ref double[,] existingPheromones) { int[] path = new int[Costs.GetLength(0)]; HashSet <int> visited = new HashSet <int>(); // Choose a random city to start from path[0] = random.Next(path.Length); visited.Add(path[0]); // Is a path possible? bool success = FindRoute(0, ref path, visited, ref existingPheromones); if (success) { // If so, store that path. AntRoute = path; // Find and store the route cost StoreRouteCost(); } else { Console.WriteLine("Setting Route to null. Edit this output to debug."); AntRoute = null; RouteCost = Double.MaxValue; } }
// Follows a route // Returns a new matrix with the same values, changed so that // the route from node i to node j has been followed. Makes it // so that nothing from i or to j will be followed again. Also // makes it so that the route from j to the beginning node can't // be followed. Returns a reduced matrix. public Matrix FollowRoute(int i, int j) { double[,] costs = Costs.Clone() as double[, ]; for (int k = 0; k < Costs.GetLength(0); k++) { costs[i, k] = Double.PositiveInfinity; costs[k, j] = Double.PositiveInfinity; } // Make it so that it can't go to the start city (unless this is the last city if (CitiesVisited < Cities.Length - 2) { costs[j, 0] = Double.PositiveInfinity; } return(new Matrix(Cities, costs, LowerBound, CitiesVisited + 1).Reduce()); }
public double[,] solveUV(out int cycles) { //Account for minimum delivery adjustMinimumDelivery_FromSupplyAndDemand(false); //Subtract away //Get dimensions int rows = Costs.GetLength(0); int cols = Costs.GetLength(1); //Get Northwest approximation double[,] solutionCurr = solveNorthWest(false); //Cycle until end condion met cycles = 0; //For statistics while (true) { #region Calculate UV values double[] u; double[] v; calculateUV_Values(solutionCurr, out u, out v); #endregion #region Calculate penalty values, track location of greatest penalty double[,] penalties = new double[rows, cols]; int rMax = -1; int cMax = -1; double penaltyMax = double.NegativeInfinity; bool allNegative = true; //Calculate penalties for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { //Calculate only for unassigned cells if (solutionCurr[r, c] == 0) { //Get and store value double penalty = u[r] + v[c] - Costs[r, c]; penalties[r, c] = penalty; //Check sign if (penalty > 0) { allNegative = false; } //Check for max if (penalty > penaltyMax) { penaltyMax = penalty; rMax = r; cMax = c; } } } } #endregion //Check end condion if (allNegative) { //Finished break; } #region Generate new iteration of solution //Identify loop int rLoopStart = rMax; int cLoopStart = cMax; int[,] loop = findLoop(solutionCurr, rLoopStart, cLoopStart); //Get lowest number in "negative" group (odd entries of loop) double minValue = double.PositiveInfinity; for (int p = 0; p < loop.GetLength(0); p++) { //Get cell value int r = loop[p, 0]; int c = loop[p, 1]; //Determine current operation if (p % 2 == 1) //odd (negative operation numbers) { if (solutionCurr[r, c] < minValue) { minValue = solutionCurr[r, c]; } } } //Adjust current solution for (int p = 0; p < loop.GetLength(0); p++) { //Get cell value int r = loop[p, 0]; int c = loop[p, 1]; //Determine current operation if (p % 2 == 0) //even or zero { //Add the minimum value to the solution solutionCurr[r, c] += minValue; } else //odd { //Remove the minimum value from the solution solutionCurr[r, c] -= minValue; } } #endregion cycles++; } //Account for minimum delivery addMinimumDelivery_ToSolution(solutionCurr); adjustMinimumDelivery_FromSupplyAndDemand(true); //Add back return(solutionCurr); }