public void findGreatestDiff(State state)          //O(n^3)
        {
            int    chosenX      = 0;                       //city x to city y
            int    chosenY      = 0;
            double greatestDiff = double.NegativeInfinity; //initialize to -oo to find what the greatest
                                                           //difference is
            List <PointF> points = new List <PointF>();

            for (int i = 0; i < state.getMap().GetLength(0); i++)     //rows, O(n)
            {
                for (int j = 0; j < state.getMap().GetLength(1); j++) //columns
                {
                    if (state.getPoint(i, j) == 0)                    //if point is 0
                    {
                        points.Add(new PointF(i, j));                 //store all 0's in a point array
                    }
                }
            }
            for (int i = 0; i < points.Count; i++)                                                                            //loop through 0's to find the greatest difference
            {                                                                                                                 //O(n^3)                               there will be atmost n points, because the entire
             //matrix will be 0
                int possibleMax = findExcludeMinusInclude(Convert.ToInt32(points[i].X), Convert.ToInt32(points[i].Y), state); //O(n^2)
                if (possibleMax >= greatestDiff)                                                                              //set the point to point values, if it is 0 is covered by =
                {
                    chosenX      = Convert.ToInt32(points[i].X);
                    chosenY      = Convert.ToInt32(points[i].Y);
                    greatestDiff = possibleMax;
                }
            }
            State include = makeInclude(chosenX, chosenY, state); //O(n^2)

            if (BSSF > include.getLB())                           //if include's lowerbound is better than the BSSF
            {
                include.setEdge(chosenX, chosenY);                //set the edge in the dictionary
                checkCycles(include, chosenX, chosenY);           //O(n), make sure there are no potential cycles
                queue.Add(include);                               //add to the queue to be popped off later
            }

            if (isDictionaryFilled(include)) //O(n), have all of the edges been filled? then the include.LB is better
            {                                //than the current BSSF, set the BSSF
                BSSF      = include.getLB();
                bestState = include;         //save the "bestState"
            }

            State exclude = makeExclude(chosenX, chosenY, state); //O(n^2)

            if (BSSF > exclude.getLB())                           //if exclude's lowerbound is than the BSSF, add it to the queue
            {
                queue.Add(exclude);
            }
            if (isDictionaryFilled(exclude)) //O(n), have all of the edges been filled?
            {                                // then exclude's lowerbound is better, set the BSSF to exclude.LB
                BSSF      = exclude.getLB();
                bestState = exclude;
            }
        }
        public State makeInclude(int x, int y, State state)                                              //O(n^2)
        {
            State includeState = new State(copyMatrix(state.getMap()), state.getLB(), state.getEdges()); //O(n^2)

            includeState.setPoint(y, x, double.PositiveInfinity);                                        //set the "opposite point to infinity"
            for (int j = 0; j < includeState.getMap().GetLength(1); j++)                                 //set the row to infinity, O(n)
            {
                includeState.setPoint(x, j, double.PositiveInfinity);
            }
            for (int i = 0; i < includeState.getMap().GetLength(0); i++) //set the column to infinity, O(n)
            {
                includeState.setPoint(i, y, double.PositiveInfinity);
            }
            reduceMatrix(includeState);              //O(n^2)
            includeState.setEdges(state.getEdges()); //initialize includeState's dictionary of edges
            return(includeState);
        }
        public State makeExclude(int x, int y, State state)                                              //O(n^2)
        {
            State excludeState = new State(copyMatrix(state.getMap()), state.getLB(), state.getEdges()); //O(n^2)

            excludeState.setPoint(x, y, double.PositiveInfinity);                                        //make chosen point infinity
            reduceMatrix(excludeState);                                                                  //O(n^2)
            excludeState.setEdges(state.getEdges());                                                     //initialize excludeStates edges
            return(excludeState);
        }
        public void reduceMatrix(State currentState) //O(n^2)
        {
            double lowerBound = currentState.getLB();

            for (int i = 0; i < currentState.getMap().GetLength(0); i++) // reduce rows
            {                                                            //O(n^2)
                double minimum = double.PositiveInfinity;                //find the lowest value in that row to reduce
                for (int j = 0; j < currentState.getMap().GetLength(1); j++)
                {
                    if (currentState.getPoint(i, j) < minimum)
                    {
                        minimum = currentState.getPoint(i, j);
                    }
                }
                if (minimum == 0) //if there is already a 0 in that row, don't waste time looping through it
                {
                    continue;
                }
                if (minimum != double.PositiveInfinity)
                {
                    for (int j = 0; j < currentState.getMap().GetLength(1); j++)
                    { //reduce the other entire row by that value
                        double reducedPoint = currentState.getPoint(i, j) - minimum;
                        currentState.setPoint(i, j, reducedPoint);
                    }
                    lowerBound += minimum; //add that lowest value to the lowerBound
                }
            }
            for (int j = 0; j < currentState.getMap().GetLength(1); j++) //reduce columns
            {                                                            //O(n^2)
                double minimum = double.PositiveInfinity;
                for (int i = 0; i < currentState.getMap().GetLength(0); i++)
                {
                    if (currentState.getPoint(i, j) < minimum)
                    {
                        minimum = currentState.getPoint(i, j); //find the lowest value in the column
                    }
                }
                if (minimum == 0) //if there is already a 0 in that column, don't waste time looping through it
                {
                    continue;
                }
                if (minimum != double.PositiveInfinity)
                {
                    for (int i = 0; i < currentState.getMap().GetLength(0); i++)
                    {//reduce the entire column by that value
                        double lowerPoint = currentState.getPoint(i, j) - minimum;
                        currentState.setPoint(i, j, lowerPoint);
                    }
                    lowerBound += minimum; //add that minimum value to the lowerBound
                }
            }
            currentState.setLB(lowerBound); //set the lowerbound
        }
 //O(n^2)
 public void reduceMatrix(State currentState)
 {
     double lowerBound = currentState.getLB();
     for (int i = 0; i < currentState.getMap().GetLength(0); i++) // reduce rows
     {//O(n^2)
         double minimum = double.PositiveInfinity; //find the lowest value in that row to reduce
         for (int j = 0; j < currentState.getMap().GetLength(1); j++)
         {
             if (currentState.getPoint(i, j) < minimum)
                 minimum = currentState.getPoint(i, j);
         }
         if (minimum == 0) //if there is already a 0 in that row, don't waste time looping through it
             continue;
         if (minimum != double.PositiveInfinity)
         {
             for (int j = 0; j < currentState.getMap().GetLength(1); j++)
             { //reduce the other entire row by that value
                 double reducedPoint = currentState.getPoint(i, j) - minimum;
                 currentState.setPoint(i, j, reducedPoint);
             }
             lowerBound += minimum; //add that lowest value to the lowerBound
         }
     }
     for (int j = 0; j < currentState.getMap().GetLength(1); j++) //reduce columns
     {//O(n^2)
         double minimum = double.PositiveInfinity;
         for (int i = 0; i < currentState.getMap().GetLength(0); i++)
         {
             if (currentState.getPoint(i, j) < minimum)
                 minimum = currentState.getPoint(i, j); //find the lowest value in the column
         }
         if (minimum == 0) //if there is already a 0 in that column, don't waste time looping through it
             continue;
         if (minimum != double.PositiveInfinity)
         {
             for (int i = 0; i < currentState.getMap().GetLength(0); i++)
             {//reduce the entire column by that value
                 double lowerPoint = currentState.getPoint(i, j) - minimum;
                 currentState.setPoint(i, j, lowerPoint);
             }
             lowerBound += minimum; //add that minimum value to the lowerBound
         }
     }
     currentState.setLB(lowerBound); //set the lowerbound
 }
 //O(n^2)
 public State makeInclude(int x, int y, State state)
 {
     State includeState = new State(copyMatrix(state.getMap()), state.getLB(), state.getEdges()); //O(n^2)
     includeState.setPoint(y, x, double.PositiveInfinity); //set the "opposite point to infinity"
     for (int j = 0; j < includeState.getMap().GetLength(1); j++) //set the row to infinity, O(n)
     {
         includeState.setPoint(x, j, double.PositiveInfinity);
     }
     for (int i = 0; i < includeState.getMap().GetLength(0); i++) //set the column to infinity, O(n)
     {
         includeState.setPoint(i, y, double.PositiveInfinity);
     }
     reduceMatrix(includeState); //O(n^2)
     includeState.setEdges(state.getEdges()); //initialize includeState's dictionary of edges
     return includeState;
 }
 //O(n^2)
 public State makeExclude(int x, int y, State state)
 {
     State excludeState = new State(copyMatrix(state.getMap()), state.getLB(), state.getEdges()); //O(n^2)
     excludeState.setPoint(x, y, double.PositiveInfinity); //make chosen point infinity
     reduceMatrix(excludeState); //O(n^2)
     excludeState.setEdges(state.getEdges()); //initialize excludeStates edges
     return excludeState;
 }
        //O(n^3)
        public void findGreatestDiff(State state)
        {
            int chosenX = 0; //city x to city y
            int chosenY = 0;
            double greatestDiff = double.NegativeInfinity; //initialize to -oo to find what the greatest
                                                           //difference is
            List<PointF> points = new List<PointF>();
            for (int i = 0; i < state.getMap().GetLength(0); i++) //rows, O(n)
            {
                for (int j = 0; j < state.getMap().GetLength(1); j++) //columns
                {
                    if (state.getPoint(i, j) == 0) //if point is 0
                    {
                        points.Add(new PointF(i, j)); //store all 0's in a point array

                    }
                }
            }
            for (int i = 0; i < points.Count; i++) //loop through 0's to find the greatest difference
            {//O(n^3)                               there will be atmost n points, because the entire
             //matrix will be 0
                int possibleMax = findExcludeMinusInclude(Convert.ToInt32(points[i].X), Convert.ToInt32(points[i].Y), state); //O(n^2)
                if (possibleMax >= greatestDiff) //set the point to point values, if it is 0 is covered by =
                {
                    chosenX = Convert.ToInt32(points[i].X);
                    chosenY = Convert.ToInt32(points[i].Y);
                    greatestDiff = possibleMax;
                }
            }
            State include = makeInclude(chosenX, chosenY, state); //O(n^2)
            if (BSSF > include.getLB()) //if include's lowerbound is better than the BSSF
            {
                include.setEdge(chosenX, chosenY); //set the edge in the dictionary
                checkCycles(include, chosenX, chosenY); //O(n), make sure there are no potential cycles
                queue.Add(include); //add to the queue to be popped off later
            }

            if (isDictionaryFilled(include))//O(n), have all of the edges been filled? then the include.LB is better
            {                               //than the current BSSF, set the BSSF
                BSSF = include.getLB();
                bestState = include; //save the "bestState"
            }

            State exclude = makeExclude(chosenX, chosenY, state);//O(n^2)
            if (BSSF > exclude.getLB()) //if exclude's lowerbound is than the BSSF, add it to the queue
                queue.Add(exclude);
            if (isDictionaryFilled(exclude))//O(n), have all of the edges been filled?
            {                               // then exclude's lowerbound is better, set the BSSF to exclude.LB
                BSSF = exclude.getLB();
                bestState = exclude;
            }
        }