// finds the best tour possible using the branch and bound method of attack
        // For an example of what to return, see DefaultSolver.solve() method.
        public Problem solve()
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();

            State beginningState = new State(cityData.size);

            SolverHelper.initializeState(beginningState, cityData);
            this.q.Enqueue(beginningState);
            Problem determineBSSFProblem = SolverHelper.clone(cityData);

            this.cityData.bssf = GreedySolver.solve(determineBSSFProblem).bssf;

            while (q.Count > 0)
            {
                recur(q.Dequeue());
                //Clear out any states that have a BSSF less than
                //that of the current
            }

            timer.Stop();
            cityData.timeElasped = timer.Elapsed;

            return(cityData);
        }
 public TSPSolution(City[] cities, List <int> cityOrder, double costOfRoute)
 {
     // From the list of city indexes, create the list of cities
     route = new List <City>(cityOrder.Count);
     foreach (int i in cityOrder)
     {
         City temp = SolverHelper.clone(cities[i]);
         route.Add(temp);
     }
     this.costOfRoute = costOfRoute;
 }
        // Returns the index of the last city to be visited in the cycle
        private static void recur(State state)
        {
            //state.printState();
            int currCityIndex = state.currCityIndex;

            // All cities have been visited; finish and return
            if (state.getCitiesVisited() == state.size - 1)
            {
                // The current path cannot be completed bc there is no path from the last city to the first
                if (state.matrix[currCityIndex, state.cityOfOriginIndex] == double.PositiveInfinity)
                {
                    state.lowerBound = double.PositiveInfinity;
                }
                else
                {
                    state.addCity(currCityIndex);
                    state.lowerBound += state.matrix[currCityIndex, state.cityOfOriginIndex];
                    return;
                }
            }

            state.addCity(currCityIndex);

            // find the smallest distance to any other city
            double closestCityDistance = double.PositiveInfinity;
            int    closestCityIndex    = -1;

            for (int j = 1; j < state.matrix.GetLength(1); j++)
            {
                // For a different starting city, the following code
                // would have to be added:
                //for (int j = 0; j < state.matrix.GetLength(1); j++)
                //if (j == state.startCityIndex)
                //    continue;
                if (state.matrix[currCityIndex, j] < closestCityDistance)
                {
                    closestCityIndex    = j;
                    closestCityDistance = state.matrix[currCityIndex, j];
                }
            }

            // add [i,j]
            state.lowerBound += closestCityDistance;

            // Blank out appropriate spaces
            SolverHelper.blankOut(state, closestCityIndex);

            // reduce
            SolverHelper.reduce(state);

            state.currCityIndex = closestCityIndex;
            recur(state);
        }
        // finds the greedy tour starting from each city and keeps the best (valid) one
        // For an example of what to return, see DefaultSolver.solve() method.
        public static Problem solve(Problem cityData)
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();

            State state = new State(cityData.size);

            SolverHelper.initializeState(state, cityData);
            state.currCityIndex = 0;
            recur(state);

            timer.Stop();

            // Since cityData is static, it is pointing to the cityData object
            // that was passed in. Setting it's BSSF here will set the BSSF
            // of the cityData object in the Form1 class.
            cityData.bssf        = new TSPSolution(cityData.cities, state.cityOrder, state.lowerBound);
            cityData.timeElasped = timer.Elapsed;
            cityData.solutions   = 1;

            return(cityData);
        }
        private void recur(State state)
        {
            // This is a leaf
            // All cities have been visited; finish and return
            if (state.getCitiesVisited() == cityData.size - 1)
            {
                // The path to the last city is blocked
                if (state.matrix[state.currCityIndex, state.cityOfOriginIndex]
                    == SolverHelper.SPACE_PLACEHOLDER)
                {
                    return;
                }

                state.addCity(state.currCityIndex);

                // Since we've hit a leaf node, we've found another possible solution
                cityData.solutions++;

                // Add the last hop to the lower bound to get the cost of the complete cycle
                state.lowerBound += state.matrix[state.currCityIndex, state.cityOfOriginIndex];

                // Check to see if this route is smaller than the current BSSF
                // If so, replace the current BSSF
                if (state.lowerBound < cityData.bssf.costOfRoute)
                {
                    cityData.bssf = new TSPSolution(cityData.cities, state.cityOrder, state.lowerBound);
                }

                return;
            }

            state.addCity(state.currCityIndex);

            for (int j = 1; j < state.matrix.GetLength(1); j++)
            {
                //Console.WriteLine(state.currCityIndex + " " + j);
                //state.printState();

                double currDistVal = state.matrix[state.currCityIndex, j];
                if (currDistVal != SolverHelper.SPACE_PLACEHOLDER &&
                    state.lowerBound + currDistVal < cityData.bssf.costOfRoute)
                {
                    State childState = SolverHelper.clone(state);

                    // add [i,j]
                    childState.lowerBound += currDistVal;

                    // Blank out the appropriate values with the placeholder
                    SolverHelper.blankOut(childState, j);
                    //childState.printState();

                    // reduce
                    SolverHelper.reduce(childState);

                    childState.currCityIndex = j;

                    if (childState.lowerBound < cityData.bssf.costOfRoute)
                    {
                        q.Enqueue(childState);
                    }
                }
            }
        }