Example #1
0
 public bool extend()
 {
     if (citiesLeft.Count() != 0)
     {
         foreach (int i in citiesLeft)
         {
             double     initialCost = matrix[path.Last()][i] + cost;
             double[][] newMatrix   = this.matrix.Select(a => a.ToArray()).ToArray();
             for (int j = 0; j < matrix.Count(); j++)
             {
                 newMatrix[path.Last()][j] = Double.PositiveInfinity;
                 newMatrix[j][i]           = Double.PositiveInfinity;
             }
             List <int> newPath = path.Select(a => a).ToList();
             newPath.Add(i);
             List <int> newCitiesLeft = citiesLeft.Select(a => a).ToList();
             newCitiesLeft.Remove(i);
             BBState state = new BBState(newMatrix, newPath, newCitiesLeft, initialCost);
             PriorityQueue.getInstance().insert(state);
         }
         return(false);
     }
     else
     {
         cost = matrix[path.Last()][0] + cost;
         path.Add(0);
         return(true);
     }
 }
Example #2
0
 //initializes the distances with the given list and sets the lastIndex which
 //is used to track which elements have been checked
 //public PriorityQueue(List<double> costs)
 //{
 //    foreach (double distance in costs)
 //    {
 //        insert(distance);
 //    }
 //    lastIndex = costs.Count - 1;
 //}
 //adds element to the bottom of the tree and if its not the max value then bubble up
 //Insert is O(log(|v|)) because Heapify is O(log(|v|)) and add is O(1)
 public void insert(BBState state)
 {
     states.Add(state);
     double cost = state.getCost();
     this.cost.Insert(++lastIndex,cost);
     pointers.Add(pointers.Count);
     if (cost != Int32.MaxValue)
     {
         HeapifyUp(lastIndex);
     }
 }
Example #3
0
        //initializes the distances with the given list and sets the lastIndex which
        //is used to track which elements have been checked
        //public PriorityQueue(List<double> costs)
        //{
        //    foreach (double distance in costs)
        //    {
        //        insert(distance);
        //    }
        //    lastIndex = costs.Count - 1;
        //}
        //adds element to the bottom of the tree and if its not the max value then bubble up
        //Insert is O(log(|v|)) because Heapify is O(log(|v|)) and add is O(1)
        public void insert(BBState state)
        {
            states.Add(state);
            double cost = state.getCost();

            this.cost.Insert(++lastIndex, cost);
            pointers.Add(pointers.Count);
            if (cost != Int32.MaxValue)
            {
                HeapifyUp(lastIndex);
            }
        }
Example #4
0
        //swaps the minimum with the lastIndexed item and bubbles down
        //DeleteMin is O(log(|v|)), because of the reorder
        public BBState deletemin()
        {
            int node = pointers[0];

            pointers[0]         = pointers[lastIndex];
            pointers[lastIndex] = node;
            cost[0]             = cost[lastIndex];
            cost[lastIndex]     = -1;
            //this make it O(log(|v|))
            HeapifyDown(0);
            lastIndex--;
            BBState state = states.ElementAt(node);

            return(state);
            //return node;
        }
Example #5
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];
            double bssf = Double.PositiveInfinity;

            // TODO: Add your implementation for a branch and bound solver here.
            //List<int> citiesLeft = new List<int>();
            //double[][] matrix = new double[Cities.Length][];
            //for (int i = 0; i < Cities.Length; i++)
            //{
            //    citiesLeft.Add(i);
            //    matrix[i] = new double[Cities.Length];
            //    for (int j = 0; j < Cities.Length; j++)
            //    {
            //        if (i != j)
            //            matrix[i][j] = Cities[i].costToGetTo(Cities[j]);
            //        else
            //            matrix[i][j] = Double.PositiveInfinity;

            //    }
            //}
            //citiesLeft.RemoveAt(0);
            double[][] matrix = new double[4][];
            matrix[0] = new double[4] { Double.PositiveInfinity, 7, 3, 12 };
            matrix[1] = new double[4] { 3, Double.PositiveInfinity, 6, 14 };
            matrix[2] = new double[4] { 5, 8, Double.PositiveInfinity, 6 };
            matrix[3] = new double[4] { 9, 3, 5, Double.PositiveInfinity };
            BBState state = new BBState(matrix, new List<int>() { 0 }, new List<int>() { 1,2,3 },0);
            //BBState state = new BBState(matrix, new List<int>() { 0 }, citiesLeft,0);
            PriorityQueue.getInstance().insert(state);

            BBState current;
            while (!PriorityQueue.getInstance().isEmpty())
            {
                 current = PriorityQueue.getInstance().deletemin();
                if(state.extend())
                {
                    if(current.getCost() < bssf)
                    {
                        bssf = current.getCost();
                        PriorityQueue.getInstance().trim(bssf);
                    }

                }
            }


            results[COST] = "not implemented";    // load results into array here, replacing these dummy values
            results[TIME] = "-1";
            results[COUNT] = "-1";

            return results;
        }
Example #6
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];
            double   bssf    = Double.PositiveInfinity;

            // TODO: Add your implementation for a branch and bound solver here.
            //List<int> citiesLeft = new List<int>();
            //double[][] matrix = new double[Cities.Length][];
            //for (int i = 0; i < Cities.Length; i++)
            //{
            //    citiesLeft.Add(i);
            //    matrix[i] = new double[Cities.Length];
            //    for (int j = 0; j < Cities.Length; j++)
            //    {
            //        if (i != j)
            //            matrix[i][j] = Cities[i].costToGetTo(Cities[j]);
            //        else
            //            matrix[i][j] = Double.PositiveInfinity;

            //    }
            //}
            //citiesLeft.RemoveAt(0);
            double[][] matrix = new double[4][];
            matrix[0] = new double[4] {
                Double.PositiveInfinity, 7, 3, 12
            };
            matrix[1] = new double[4] {
                3, Double.PositiveInfinity, 6, 14
            };
            matrix[2] = new double[4] {
                5, 8, Double.PositiveInfinity, 6
            };
            matrix[3] = new double[4] {
                9, 3, 5, Double.PositiveInfinity
            };
            BBState state = new BBState(matrix, new List <int>()
            {
                0
            }, new List <int>()
            {
                1, 2, 3
            }, 0);

            //BBState state = new BBState(matrix, new List<int>() { 0 }, citiesLeft,0);
            PriorityQueue.getInstance().insert(state);

            BBState current;

            while (!PriorityQueue.getInstance().isEmpty())
            {
                current = PriorityQueue.getInstance().deletemin();
                if (state.extend())
                {
                    if (current.getCost() < bssf)
                    {
                        bssf = current.getCost();
                        PriorityQueue.getInstance().trim(bssf);
                    }
                }
            }


            results[COST]  = "not implemented";   // load results into array here, replacing these dummy values
            results[TIME]  = "-1";
            results[COUNT] = "-1";

            return(results);
        }
Example #7
0
        /**
        * Solve the TSP using an include/exclude B&B strategy
        *
        * First, get an upper bound, bssf.
        *
        * Generate the initial Reduced Cost Matrix, (RCM) which
        * will give us the initial lower bound.
        *
        *
        */
        public void solveBranchAndBound()
        {
            // Stats
            int totalStatesGenerated = 0, statesPruned = 0, maxStatesStored = 0;
            bool initialBssfIsFinal = true;

            // Get an upper bound
            getGreedyRoute();
            bssf = new TSPSolution(Route);

            // Generate the RCM, and get it's lower bound from the reduction
            double[,] rcm = generateRCM();
            double lowerBound = reduceCM(ref rcm);

            // Now we need to start throwing states on the queue and processing them..
            PriorityQueue<BBState> stateQueue = new PriorityQueue<BBState>();

            // Create initial state
            BBState initialState = new BBState(rcm, lowerBound);
            stateQueue.Enqueue(initialState, initialState.bound);
            totalStatesGenerated = maxStatesStored = 1;

            // Ok, now we kick off the process!
            // Start the timer..
            Stopwatch timer = new Stopwatch();
            timer.Start();

            BBState curState = null;
            while (stateQueue.Count > 0)
            {
                /*if (timer.ElapsedMilliseconds > 30000) // 30 seconds
                    break; */

                curState = stateQueue.Dequeue();

                // If this state's lower bound is greater than BSSF, then we
                // prune it out
                if (curState.bound > costOfBssf())
                {
                    statesPruned++;
                    continue;
                }

                // If it's not, then see if it's a complete solution. If it is,
                // then update BSSF.
                if (curState.isCompleteSolution(ref Cities))
                {
                    bssf = new TSPSolution(curState.getRoute(ref Cities));
                    initialBssfIsFinal = false;
                    continue;
                }

                // If it's not a complete solution, but it's within range, then
                // expand it into two child states, one with an included edge, one
                // with the same edge excluded.
                Tuple<int, int> edge = curState.getNextEdge();

                if (edge == null)
                    continue;

                // Ok, now we have the next edge to include and exclude in different states to maximize
                // the difference in bounds. So we need to create states corresponding to each and put
                // them in the queue.
                BBState incState = new BBState(curState.cm, curState.bound, curState.includedEdges);
                incState.includedEdges.Add(edge);

                incState.cm[edge.Item1, edge.Item2] = double.PositiveInfinity;
                incState.cm[edge.Item2, edge.Item1] = double.PositiveInfinity;

                for (int t = 0; t < incState.cm.GetLength(0); t++)
                    incState.cm[t, edge.Item2] = double.PositiveInfinity;

                for (int t = 0; t < incState.cm.GetLength(1); t++)
                    incState.cm[edge.Item1, t] = double.PositiveInfinity;

                // Need to take out edges in incState that could be used to complete a premature cycle
                if (incState.includedEdges.Count < incState.cm.GetLength(0) - 1)
                {
                    int start = edge.Item1, end = edge.Item2, city;

                    city = getCityExited(start, incState.includedEdges);
                    while (city != -1)
                    {
                        start = city;
                        city = getCityExited(start, incState.includedEdges);
                    }

                    city = getCityEntered(end, incState.includedEdges);
                    while (city != -1)
                    {
                        end = city;
                        city = getCityEntered(end, incState.includedEdges);
                    }

                    while (start != edge.Item2)
                    {
                        incState.cm[end, start] = double.PositiveInfinity;
                        incState.cm[edge.Item2, start] = double.PositiveInfinity;
                        start = getCityEntered(start, incState.includedEdges);
                    }
                }

                //  finish setting up the state and put it in the queue
                incState.bound = curState.bound + reduceCM(ref incState.cm);

                totalStatesGenerated++;
                if (incState.bound > costOfBssf())
                {
                    statesPruned++;
                }
                else
                {
                    stateQueue.Enqueue(incState, incState.bound);
                    if (stateQueue.Count > maxStatesStored)
                        maxStatesStored = stateQueue.Count;
                }

                BBState exState = new BBState(curState.cm, curState.bound, curState.includedEdges);

                exState.cm[edge.Item1, edge.Item2] = double.PositiveInfinity;
                exState.bound = curState.bound + reduceCM(ref exState.cm);

                totalStatesGenerated++;
                if (exState.bound > costOfBssf())
                {
                    statesPruned++;
                }
                else
                {
                    stateQueue.Enqueue(exState, exState.bound);
                    if (stateQueue.Count > maxStatesStored)
                        maxStatesStored = stateQueue.Count;
                }
            }

            timer.Stop();

            Program.MainForm.tbElapsedTime.Text = " " + timer.Elapsed;

            // update the cost of the tour.
            Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute();
            // do a refresh.
            Program.MainForm.Invalidate();

            String msg = "\tB&B RESULTS\n";
            if (timer.ElapsedMilliseconds > 30000)
                msg += "\nSearch timed out, 30 seconds expired.";
            if (initialBssfIsFinal)
                msg += "\nInitial BSSF (Greedy) is final solution.";
            else
                msg += "\nA better BSSF than the initial was found.";

            msg += "\n\n\tSTATS:";
            msg += "\nTotal States Created:\t" + totalStatesGenerated;
            msg += "\nTotal States Pruned:\t" + statesPruned;
            msg += "\nMax States Stored: \t" + maxStatesStored;

            MessageBox.Show(msg);

            return;
        }
Example #8
0
 public bool extend()
 {
     if (citiesLeft.Count() != 0)
     {
         foreach (int i in citiesLeft)
         {
             double initialCost = matrix[path.Last()][i] + cost;
             double[][] newMatrix = this.matrix.Select(a => a.ToArray()).ToArray();
             for(int j = 0; j < matrix.Count(); j++)
             {
                 newMatrix[path.Last()][j] = Double.PositiveInfinity;
                 newMatrix[j][i] = Double.PositiveInfinity;
             }
             List<int> newPath = path.Select(a => a).ToList();
             newPath.Add(i);
             List<int> newCitiesLeft = citiesLeft.Select(a => a).ToList();
             newCitiesLeft.Remove(i);
             BBState state = new BBState(newMatrix, newPath, newCitiesLeft, initialCost);
             PriorityQueue.getInstance().insert(state);
         }
         return false;
     }
     else
     {
         cost = matrix[path.Last()][0] + cost;
         path.Add(0);
         return true;
     }
 }