Data Structures, Algorithms, & Applications in Java
Chapter 21, Exercise 15

(a)
Every tour contains exactly one edge that leaves each vertex. The sum of the weights of these edges cannot exceed (sum from i=1 to n) Maxi. Therefore, if the digraph has a tour, its cost must be less than (sum from i=1 to n) Maxi+1.
(b)
To make use of this observation, we must initialize costOfBestTourSoFar to (sum from i=1 to n) Maxi+1 rather than to null in btSalesperson (Program 20.11). Once this is done, we can eliminate the tests bestc == null from rTSP (Program 20.12).

The modified code is given below. Changes from Programs 20.11 and 20.12 are shown in red.

public class BTSalespersonWithBetterInitialBound
             extends AdjacencyWDigraph
{

   // class data members
   static int [] partialTour;
   static int [] bestTourSoFar;
   static Object costOfBestTourSoFar;
   static Operable costOfPartialTour;

   // constructors
   public BTSalespersonWithBetterInitialBound(int theVertices)
      {super(theVertices);}

   public BTSalespersonWithBetterInitialBound()
      {this(0);}
   
   /** traveling salesperson by backtracking, modified to use a better
     * starting bound
     * param theZero zero weight
     * param theOne any positive weight
     * param bestTour bestTour[1:n] is set to best tour
     * return cost of best tour */
   public Object btSalesperson2(int [] bestTour, Operable theZero,
                                Operable theOne)
   {
      // compute initial value of costOfBestTourSoFar
      costOfBestTourSoFar = theOne;
      for (int i = 1; i <= n; i++)
      {// find max cost edge out of vertex i
         // maxCost will eventually be max weight of an out edge from i
         Operable maxCost = theZero;
         // outEdge will become true iff i has an out edge
         boolean outEdge = false;
         for (int j = 1; j <= n; j++)
            if (a[i][j] != null)
            {// found an out edge from vertex i
               outEdge = true;
               if (((Operable) a[i][j]).compareTo(maxCost) > 0)
                  maxCost = (Operable) a[i][j];
            }
   
         // make sure vertex i has an out edge
         if (!outEdge)
            // no edge out of vertex i, no tour is possible
            return null;;
   
         // vertex i has an out edge
         ((Operable) costOfBestTourSoFar).increment(maxCost);
        }
   
      // set partialTour to identity permutation
      partialTour = new int [n + 1];
      for (int i = 1; i <= n; i++)
         partialTour[i] = i;
   
      bestTourSoFar = bestTour;
      costOfPartialTour = theZero;
   
      // search permutations of partialTour[2:n]
      rTSP2(2);
   
      return costOfBestTourSoFar;
   }
   
   /** recursive backtracking code for traveling salesperson
     * using a better starting bound
     * search the permutation tree for best tour */
   private void rTSP2(int currentLevel)
   {
      if (currentLevel == n)
      {// at parent of a leaf
         // complete tour by adding last two edges
         if (a[partialTour[n - 1]][partialTour[n]] != null &&
             a[partialTour[n]][1] != null &&
             ((Operable) ((Operable) costOfPartialTour
               .add(a[partialTour[n - 1]][partialTour[n]]))
               .add(a[partialTour[n]][1]))
               .compareTo(costOfBestTourSoFar) < 0)
         {// better tour found
            for (int j = 1; j <= n; j++)
               bestTourSoFar[j] = partialTour[j];
            costOfBestTourSoFar = ((Operable) costOfPartialTour
                         .add(a[partialTour[n - 1]][partialTour[n]]))
                         .add(a[partialTour[n]][1]);
         }
      }
      else
      {// try out subtrees
         for (int j = currentLevel; j <= n; j++)
            // is move to subtree labeled partialTour[j] possible?
            if (a[partialTour[currentLevel - 1]][partialTour[j]] != null &&
                ((Operable) costOfPartialTour
                  .add(a[partialTour[currentLevel - 1]][partialTour[j]]))
                  .compareTo(costOfBestTourSoFar) < 0)
            {// search this subtree
               MyMath.swap(partialTour, currentLevel, j);
               costOfPartialTour.increment(a[partialTour[currentLevel - 1]]
                             [partialTour[currentLevel]]);
               rTSP2(currentLevel + 1);
               costOfPartialTour.decrement(a[partialTour[currentLevel - 1]]
                             [partialTour[currentLevel]]);
               MyMath.swap(partialTour, currentLevel, j);
            }
      }
   }
}