- Take the largest of the IN set and put the new set S. (item 2, value 18)
- Try to find the largest element with a value of <= (20 - 18): none, add S to the list of sets.
- if IN is not empty GOTO 1
Iterations:
IN: 9, 18, 7, 8, 4, 9, 11, 15, 3, 8 S1 (18) : 2:18 IN: 9, _, 7, 8, 4, 9, 11, 15, 3, 8 S2 (19) : 8:15, 5:4 IN: 9, _, 7, 8, _, 9, 11, _, 3, 8 S3 (20) : 7:11, 1:9 IN: _, _, 7, 8, _, 9, _, _, 3, 8 S4 (20) : 6: 9, 4:8, 0:3 IN: _, _, 7, _, _, _, _, _, _, 8 S5 (15) : 10: 8, 3:7 IN: _, _, _, _, _, _, _, _, _, _
The code:
public class Knapsack { public static void knapsack( int capacity, int[] values, List< int[] > indices ) { int[] in = Arrays.copyOf( values, values.length ); List< Integer > workspace = new LinkedList<>(); int wCapacity = capacity; boolean inProgress = true; while( inProgress ) { int greatestValue = -1; int greatestIndex = -1; for( int i = 0; i < in.length; ++i ) { int value = in[i]; if( value > Integer.MIN_VALUE && greatestValue < value && value <= wCapacity ) { greatestValue = value; greatestIndex = i; } } if( greatestIndex >= 0 ) { workspace.add( greatestIndex ); in[greatestIndex] = Integer.MIN_VALUE; wCapacity -= greatestValue; } else if( workspace.isEmpty()) { inProgress = false; } else { int[] ws = new int[workspace.size()]; for( int i = 0; i < workspace.size(); ++i ) { ws[i] = workspace.get(i).intValue(); } indices.add( ws ); workspace = new LinkedList<>(); wCapacity = capacity; } } } static void print( int[] values, List< int[] > indices ) { int r = 0; for( int[] t : indices ) { String items = ""; int sum = 0; for( int index : t ) { int value = values[index]; if( ! items.isEmpty()) { items += ", "; } items += index + ":" + value; sum += value; } System.out.println( "S" + ++r + " (" + sum + ") : " + items ); } } public static void main( String[] args ) { int[] values = { 9, 18, 7, 8, 4, 9, 11, 15, 3, 8 }; List< int[] > indices = new LinkedList<>(); knapsack( 20, values, indices ); print( values, indices ); } }
Result:
S1 (18) : 1:18 S2 (19) : 7:15, 4:4 S3 (20) : 6:11, 0:9 S4 (20) : 5:9, 3:8, 8:3 S5 (15) : 9:8, 2:7