예제 #1
0
        private Node getPartialRoute(Node node, int rowNum, int colNum)
        {
            double[,] updated = new double[Cities.Length, Cities.Length];
            for (int i = 0; i < Cities.Length; i++)
            {
                for (int k = 0; k < Cities.Length; k++)
                {
                    updated[i, k] = node.getMatrix()[i, k];
                }
            }
            ArrayList partialRoute = new ArrayList();

            for (int i = 0; i < node.getRoute().Count; i++)
            {
                partialRoute.Add(node.getRoute()[i]);
            }

            double newbssf = node.getbssf() + node.getMatrix()[rowNum, colNum];

            for (int i = 0; i < Cities.Length; i++)
            {
                updated[rowNum, i] = double.PositiveInfinity;
                updated[i, colNum] = double.PositiveInfinity;
            }
            updated[rowNum, colNum] = double.PositiveInfinity;
            updated[colNum, rowNum] = double.PositiveInfinity;
            partialRoute.Add(Cities[colNum]);
            Node newNode = new Node(newbssf, updated, partialRoute);

            newNode.setNum(colNum);
            return(reduceMatrix(newNode));
        }
예제 #2
0
        private Node reduceMatrix(Node node)
        {
            double[,] updated = new double[Cities.Length, Cities.Length];
            double updatedbssf = node.getbssf();

            for (int i = 0; i < Cities.Length; i++)
            {
                for (int k = 0; k < Cities.Length; k++)
                {
                    updated[i, k] = node.getMatrix()[i, k];
                }
            }

            for (int i = 0; i < Cities.Length; i++)     //for each row
            {
                double min = double.PositiveInfinity;
                for (int k = 0; k < Cities.Length; k++)     //get minimum for each row
                {
                    if (updated[i, k] < min)
                    {
                        min = updated[i, k];
                    }
                }
                if (min != 0 && min != double.PositiveInfinity)
                {
                    for (int k = 0; k < Cities.Length; k++) //subtract minimum from each value
                    {
                        updated[i, k] -= min;
                    }
                    updatedbssf += min;
                }
            }

            for (int i = 0; i < Cities.Length; i++)     //for each column
            {
                double min = double.PositiveInfinity;
                for (int k = 0; k < Cities.Length; k++)     //get minimum for each column
                {
                    if (updated[k, i] < min)
                    {
                        min = updated[k, i];
                    }
                }
                if (min != 0 && min != double.PositiveInfinity)
                {
                    for (int k = 0; k < Cities.Length; k++) //subtract minimum from each value
                    {
                        updated[k, i] -= min;
                    }
                    updatedbssf += min;
                }
            }
            Node newNode = new Node(updatedbssf, updated, node.getRoute());

            newNode.setNum(node.getNum());
            return(newNode);
        }
예제 #3
0
        /// <summary>
        /// performs a Branch and Bound search of the state space of partial tours
        /// stops when time limit expires and uses BSSF as solution
        /// </summary>
        /// <returns>results array for GUI that contains three ints: cost of solution, time spent to find solution, number of solutions found during search (not counting initial BSSF estimate)</returns>
        public string[] bBSolveProblem()
        {
            string[] results     = new string[3];
            string[] origResults = defaultSolveProblem();
            double   origbssf    = Convert.ToDouble(origResults[COST]);

            double[,] originalDistances = new double[Cities.Length, Cities.Length];
            List <Node> todoNodes      = new List <Node>();
            int         numSolutions   = 0;
            int         numChildStates = 0;
            int         statesPruned   = 0;
            int         numBSSF        = 0;
            int         maxNumOfStates = 0;
            double      bestSolution   = origbssf;
            ArrayList   routeSolution  = new ArrayList();

            for (int i = 0; i < Cities.Length; i++) //make original matrix from default route
            {
                for (int k = 0; k < Cities.Length; k++)
                {
                    if (i == k)
                    {
                        originalDistances[i, k] = double.PositiveInfinity;
                    }
                    else
                    {
                        originalDistances[i, k] = Cities[i].costToGetTo(Cities[k]);
                    }
                }
            }

            Stopwatch timer = new Stopwatch();

            timer.Start();
            routeSolution.Add(Cities[0]);
            Node startNode = new Node(0, originalDistances, routeSolution);

            //put nodes in queue
            todoNodes.Add(reduceMatrix(startNode));

            while (todoNodes.Count > 0)  //while the list is not empty
            {
                if (timer.Elapsed.TotalSeconds >= TIME_LIMIT)
                {
                    break;
                }
                Node node = todoNodes[0];                   //get first element
                if (node.getRoute().Count == Cities.Length) //if a leaf node
                {
                    numSolutions++;
                    TSPSolution sol = new TSPSolution(node.getRoute());
                    if (sol.costOfRoute() < bestSolution)   //reset the best solution if it is lower
                    {
                        bestSolution  = sol.costOfRoute();
                        routeSolution = node.getRoute();
                        numBSSF++;
                    }
                }
                else                                    //if not a leaf node
                {
                    if (node.getbssf() <= bestSolution) //pruning not needed
                    {
                        for (int i = 1; i < Cities.Length; i++)
                        {
                            if (node.getMatrix()[node.getNum(), i] != double.PositiveInfinity)
                            {
                                todoNodes.Add(getPartialRoute(node, node.getNum(), i));
                                numChildStates++;
                            }
                        }
                    }
                    else
                    {
                        statesPruned++;
                    }
                }

                if (todoNodes.Count > maxNumOfStates)
                {
                    maxNumOfStates = todoNodes.Count;
                }
                todoNodes.RemoveAt(0); //remove the node when finished calculating
                todoNodes.Sort();      //sorting based on priority
            }
            timer.Stop();
            bssf = new TSPSolution(routeSolution);
            Console.WriteLine("Number of child states is " + numChildStates);
            Console.WriteLine("Number of states pruned is " + statesPruned);
            Console.WriteLine("Number of bssf updates is " + numBSSF);
            Console.WriteLine("Number of stored states is " + maxNumOfStates);

            results[COST]  = bssf.costOfRoute().ToString();   // load results into array here, replacing these dummy values
            results[TIME]  = timer.Elapsed.ToString();
            results[COUNT] = numSolutions.ToString();
            return(results);
        }