# Integer Knapsack as a Backtracking Problem -- With Bounding Function

Document Sample

```					                            Integer Knapsack as a Backtracking Problem — WITH Bounding Function
/**                                                                     /**
* Integer knapsack problem: Based on item weights and values,           * Integer knapsack through backtracking --- implementation
* find the combination of _multiples_ items to include in the           * to retain information about the knapsack contents.
* knapsack that will maximize the value, subject to a weight            *
* limitation.                                                           * Parameters:
*                                                                       *    maxWt     --- carrying capacity of the knapsack
* This uses adds a value bound to the backtracking --- the              *    used[]    --- current knapsack contents
* input data is sorted into decreasing val/wt ratios. Then              *    item      --- position being considered.
* the bounding function is to check whether completely filling          *    weight[] --- individual weights
* the sack with the current item _allowing_fractional_part_             *    value[]   --- individual values
* would generate a load better than the current maximum. If             *    pack[]    --- retain the OPTIMAL boolean vector
* not, backtrack immediately.                                           *    current[] --- [0] current weight, [1] current value,
*                                                                       *                  and [2] current MAXIMUM value
* For a dataset which, in the unbounded backtracking implementation,    *
* uses 89 invocations of the recursive method, this implementation      * Decision tree pruning: proceed if COMPLETELY filling
* uses 31 invocations.                                                  * the knapsack with the current item (including fractional
*                                                                       * part) is better than the current maximum.
* Author: Timothy Rolfe                                                 *
*/                                                                      * This presumes that the weight and value vectors have
import java.io.*;                                                        * been sorted to present items from greatest to smallest
import java.util.*;     // Scanner etc.                                  * value per weight ratio.
*/
public class IntKS_Bound
static void knapSack(int maxWt, int[] used, int item,
{//If DEBUG is turned on, show each new solution as discovered
int [] weight, int [] value,
final static boolean DEBUG = true;
int [] pack, int[] current)
static int nCalls;
{ double usable;     // How MUCH of this item could we get in?
/**
nCalls++;         // Tally number of method invocations
* Public method will call the recursive branch-and-bound method
// Check whether all positions have been considered
*
if (item == pack.length)
* The value bound demands that the weight and value vectors
{//Do we have a winner?
* be sorted into non-increasing value-per-weight ratios.
if ( current[1] > current[2] )
*
{ if (DEBUG)
* The recursive method needs to receive and update information
{ System.out.println (current[1] + " replaces " +
* on the current state and the optimal solution. This is
current[2]);
* handled through passing arrays.
display(weight, value, used);
*
System.out.println();
* current[] will hold [0] current weight, [1] current value,
}
* and [2] current MAXIMUM value;
// Save the state for this winner
*
current[2] = current[1];
* pack[] will be the int vector corresponding to that
System.arraycopy(used, 0, pack, 0, used.length);
* current MAXIMUM value. It contains the number of each
}
* item included in the winning load.
}
*
else
* used[] is the scratch int vector used to generate the
{//Compute how many of this item we would use if we just loaded
* possible knapsacks.
// up with it, then try from that value backwards to zero. Note
*/
// that bounding requires us to allow a fractional part.
public static void knapSack(int maxWt, int [] pack,
usable = (double) (maxWt - current[0]) / weight[item];
int [] weight, int [] value)
{ int[] current = { 0, 0, Integer.MIN_VALUE };                             // Bound based on increase in value from using JUST THIS, including
int[] used = new int[pack.length];                                      // a fractional part.
if ( usable >= 1 && usable*value[item]+current[1] > current[2] )
sort (weight, value);
{ used[item] = (int) usable;
knapSack(maxWt, used, 0, weight, value, pack, current);
current[0] += used[item] * weight[item];
}
current[1] += used[item] * value[item];

Printed on 2010-09-03 at 14:46
while ( used[item] > 0 )                                              System.out.println ("Total method invocations:   " + nCalls);
{ knapSack(maxWt, used, item+1, weight, value,                    }
pack, current);
static void swap ( int p, int q, int[] x)
// Back off on the number of this type item
{ int tmp = x[p]; x[p] = x[q]; x[q] = tmp;     }
used[item]--;
current[0] -= weight[item];                                    static void sort ( int[] wt, int[] val )
current[1] -= value[item];                                     { for ( int lim = wt.length-1; lim > 0; lim-- )
}                                                                    { int min = 0;
}
for ( int k = 1; k <= lim; k++ )
//**/     else if ( DEBUG && usable >= 1.0 )
if ( (double)val[k]/wt[k] < (double)val[min]/wt[min] )
//**/        System.out.println ("Bound function discards item " + item);
min = k;
// Whether we used one or not, go forward WITHOUT using any.                    swap ( min, lim, wt );
knapSack(maxWt, used, item+1, weight, value,                                 swap ( min, lim, val );
pack, current);                                                 }
}                                                                       }
}
static Scanner console = new Scanner(System.in);
static void display(int [] weight, int [] value, int [] pack)                static Scanner openInput ( String lineIn )
{ int k, sumWeight=0, sumValue=0;                                            { Scanner inp = null;
if ( lineIn == null || lineIn.length() == 0 )
for ( k = 0; k < pack.length; k++ )
{
if ( pack[k] > 0 )
System.out.print ("input file: ");
{ sumWeight += weight[k] * pack[k];
lineIn = console.nextLine();
sumValue += value[k] * pack[k];
}
System.out.println ("(" + pack[k] + " used: " +
weight[k] + ", " + value[k] + ")");               while ( inp == null )
}                                                                        { try
System.out.println ("Total weight: " + sumWeight);                             { File f = new File (lineIn);
System.out.println ("Total value:   " + sumValue);                                inp = new Scanner (f);
}                                                                                   }
catch (IOException e)
public static void main ( String[] args ) throws Exception
{ System.out.println ("Exception: " + e); }
{ int [] pack;
finally
int [] weight, value;
{ if (inp == null)
int k, n, maxWeight;
{ System.out.print ("Yo! Open failed for " + lineIn
String lineIn = "";
+ "\nPlease enter a valid file name: ");
Scanner inp = null;
System.out.flush();
int sumValue = 0, sumWeight = 0;
lineIn = console.nextLine();
if ( lineIn.length() == 0 )
// Debug option: program supports command-line argument of file name
{ System.out.println ("NULL name; aborting!");
if (args.length > 0)
System.exit(0);
{ lineIn = args[0];
}
System.out.println ("Reading data from file " + lineIn);
}
}
} // end try / catch / finally
inp = openInput (lineIn);
maxWeight = inp.nextInt();                                                    } // end while
n = inp.nextInt();
return inp;
weight = new int[n];
} // end openInput
value   = new int[n];
}
pack    = new int[n];
/* Specimen run with DEBUG off
for ( k = 0; k < n; k++ )
{ weight[k] = inp.nextInt();
Optimal knapsack:
value[k] = inp.nextInt();
(2 used: 6, 18)
}
Total weight: 12
knapSack (maxWeight, pack, weight, value);
Total value:   36
System.out.println ("Optimal knapsack:");
Total method invocations: 31
display(weight, value, pack);
*/

Printed on 2010-09-03 at 14:46

```
DOCUMENT INFO
Shared By:
Categories:
Stats:
 views: 94 posted: 9/3/2010 language: English pages: 2