Ejemplo n.º 1
0
        private TspState GreedyCalc(TspState state)
        {
            var n = state.CostMatrix.GetLength(0);

            while (!state.IsComplete)
            {
                TspState cheapestBranch      = null;
                var      cheapestBranchValue = double.PositiveInfinity;
                for (var toCity = 0; toCity < n; ++toCity)
                {
                    if (!state.CanVisit(toCity))
                    {
                        continue;
                    }
                    var testBranch = state.Visit(toCity);
                    if (testBranch.LowerBound >= cheapestBranchValue)
                    {
                        continue;
                    }
                    cheapestBranch      = testBranch;
                    cheapestBranchValue = testBranch.LowerBound;
                }
                if (cheapestBranch == null)
                {
                    return(null);
                }
                state = cheapestBranch;
            }
            return(state);
        }
Ejemplo n.º 2
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[] BranchBoundSolveProblem()
        {
            var results = new string[3];

            var timer = new Stopwatch();

            Debug.Assert(_cities.Length > 0);
            var baseState = new TspState(_cities);

            timer.Start();

            var n     = _cities.Length;
            var queue = new FastPriorityQueue <TspState>(n * n * n);

            baseState = baseState.Visit(0);
            queue.Enqueue(baseState, baseState.Heuristic());
            // The current best complete route
            var bestState  = GreedyCalc(baseState);
            var upperBound = bestState?.LowerBound ?? double.PositiveInfinity;
            var stored     = 0;
            var pruned     = 0;
            var maxStates  = 0;
            var updates    = 0;

            while (queue.Count > 0)
            {
                if (queue.Count > maxStates)
                {
                    maxStates = queue.Count;
                }
                // Get best state to check based on heuristic.
                // Runs in O(log n) time.
                var state = queue.Dequeue();
                // Branch
                for (var toCity = 0; toCity < n; ++toCity)
                {
                    // If we can't visit the city, no need to consider it
                    if (!state.CanVisit(toCity))
                    {
                        continue;
                    }
                    var branchState = state.Visit(toCity);
                    // Bound
                    if (branchState.LowerBound < upperBound)
                    {
                        if (branchState.IsComplete)
                        {
                            ++updates;
                            // On a complete instance, no need to add it to the queue.
                            Debug.Assert(branchState.CostMatrix.Cast <double>().All(double.IsPositiveInfinity),
                                         "Cost Matrix is not all infinity");
                            upperBound = branchState.LowerBound;
                            bestState  = branchState;
                            continue;
                        }
                        ++stored;
                        if (queue.Count + 5 >= queue.MaxSize)
                        {
                            queue.Resize(queue.MaxSize * 2);
                        }
                        // Runs in O(log n) time
                        queue.Enqueue(branchState, branchState.Heuristic());
                    }
                    else
                    {
                        ++pruned;
                    }
                }
                // Abandon ship and give the best result otherwise
                if (timer.ElapsedMilliseconds > _timeLimit)
                {
                    break;
                }
            }
            timer.Stop();

            Debug.Assert(bestState != null && bestState.IsComplete);
            _bssf = StateToSolution(bestState);

            results[Cost]  = CostOfBssf().ToString(CultureInfo.InvariantCulture); // load results array
            results[Time]  = timer.Elapsed.ToString();
            results[Count] = $"{maxStates}/{updates}/{stored}/{pruned}";

            return(results);
        }