Esempio n. 1
0
        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;
            }
        }
Esempio n. 2
0
        // 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);
        }