示例#1
0
        public void branchAndBound()
        {
            // start our timer
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Start();

            int solNumber          = 0;
            int statesCreated      = 0;
            int branchesConsidered = 0;
            int statesStored       = 0;
            int statesPruned       = 0;

            // generate bssf
            initBSSF();
            double bsf     = costOfBssf();
            double initial = bsf;

            // generate initial cost matrix
            state s = new state(Cities.Length);

            for (int i = 0; i < Cities.Length; i++)
            {
                for (int j = 0; j < Cities.Length; j++)
                {
                    if (i == j)
                    {
                        s.costMatrix[i, j] = double.PositiveInfinity;
                    }
                    else
                    {
                        s.costMatrix[i, j] = Cities[i].costToGetTo(Cities[j]);
                    }
                }
            }
            reduce(s);

            // create priority queue and init with initial state
            PriorityQueue <state> pq = new PriorityQueue <state>();

            pq.Enqueue(s, 0);

            // loop - while !empty and cost < bssf{
            while (pq.Count > 0)
            {
                state cur = pq.Dequeue();
                if (cur.cost > bsf)
                {
                    statesPruned++;
                    continue;
                }

                state  nextInc = cur;
                state  nextEx;
                int    cityOut     = -1;
                int    cityIn      = -1;
                double improvement = double.NegativeInfinity;

                // for all edges
                for (int i = 0; i < cur.numEdges; i++)
                {
                    for (int j = 0; j < cur.numEdges; j++)
                    {
                        // if edge is 0
                        if (cur.costMatrix[i, j] == 0)
                        {
                            // calculate best if included
                            state tmp = includeEdge(cur, i, j);
                            branchesConsidered++;

                            // and improvement over exclude
                            double tmpImprov = worstCase(cur, i, j) - tmp.cost;

                            // and if keep if best improvement so far
                            if (improvement < tmpImprov)
                            {
                                nextInc     = tmp;
                                cityOut     = i;
                                cityIn      = j;
                                improvement = tmpImprov;
                            }
                        }
                    }
                }

                if (nextInc.cost < bsf)
                {
                    // is this state a complete solution?
                    if (nextInc.numAddedEdges == nextInc.numEdges)
                    {
                        // transform into bssf
                        ArrayList route = new ArrayList();
                        int       city  = 0;
                        do
                        {
                            route.Add(Cities[city]);
                            city = nextInc.outEdges[city];
                        } while (city != 0);

                        // update
                        bssf = new TSPSolution(route);
                        bsf  = costOfBssf();
                        solNumber++;
                    }
                    else
                    {
                        // we've found the state with the best improvement
                        // so calculate create the exclude state;
                        nextEx = new state(cur);
                        nextEx.costMatrix[cityOut, cityIn] = double.PositiveInfinity;
                        reduce(nextEx);

                        // enqueue both of the new states
                        pq.Enqueue(nextInc, Convert.ToInt32(nextInc.cost / (nextInc.numAddedEdges + 1)));
                        statesCreated += 2;

                        // enqueue if not infinite
                        if (nextEx.cost < bsf)
                        {
                            pq.Enqueue(nextEx, Convert.ToInt32(nextEx.cost / (nextInc.numAddedEdges + 1)));
                        }
                        else
                        {
                            statesPruned++;
                        }

                        // die with soemthing if we never actually expanded the state
                        if (nextInc == cur)
                        {
                            throw new NotSupportedException();
                        }
                    }
                    if (pq.Count > statesStored)
                    {
                        statesStored = pq.Count;
                    }
                }
            } // end while loop

            timer.Stop();

            Program.MainForm.tbCostOfTour.Text  = " " + bssf.costOfRoute();
            Program.MainForm.tbElapsedTime.Text = Convert.ToString(timer.Elapsed);
            Program.MainForm.tbStateInfo.Text   = Convert.ToString(statesCreated) + "-" + Convert.ToString(statesStored) + "-" + Convert.ToString(statesPruned);
            Program.MainForm.tbInitialBSF.Text  = Convert.ToString(initial);
            Program.MainForm.tbSolutionNum.Text = Convert.ToString(solNumber);
            // do a refresh.
            Program.MainForm.Invalidate();
        } // end function