forked from lemonbashar/java-algo-expert
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIOKnapsack.java
More file actions
99 lines (83 loc) · 3.27 KB
/
IOKnapsack.java
File metadata and controls
99 lines (83 loc) · 3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package algoexpert.hard;
import java.util.ArrayList;
import java.util.List;
/*
PROBLEM:
Given array of items with values and weights (in order) and maximum capacity of knapsack.
Maximize value in knapsack without exceeding capacity.
- items cannot be repeated
- assume there will be only one combination of items that maximizes the total value in knapsack
Output Format -> [[max_value_within_capacity], [indexes of items chosen]]
EXAMPLE:
[ [1,2], [4,3], [5,6], [6,7] ], 10 -> [ [10], [1,3]]
LOGIC:
- item can be either added to knapsack or left out
- create a 2D array with rows representing the items until that point | col representing capacity | entry representing max_value_achievable_till
if capacity > currentWeight:
- then item can be added
- maxValue[row][col] = max (item not added, item added)
- maxValue[row][col] = max (maxValue[row - 1][col], maxValues[row - 1][c - currentWeight] + currentValue)
- in backtracking just check if we added the item or not (currentValue == value at [row - 1] or not)
SOLUTION:
1. Dynamic Programming & Backtracking (to find indexes) -> time : O(nc) | space : O(nc)
*/
public class IOKnapsack
{
public static void test()
{
int[][] testItems = { {1,2}, {4,3}, {5,6}, {6,7} };
System.out.println(knapsackProblem(testItems, 10));
int[][] input = {{1, 2}, {70, 70}, {30, 30}, {69, 69}, {100, 100}};
System.out.println(knapsackProblem(input, 100));
}
private static List<List<Integer>> generateSolution(int[][] maxValues, int[][] items)
{
List<List<Integer>> solution = new ArrayList<List<Integer>> ();
List<Integer> maxValue = new ArrayList<>();
List<Integer> indexes = new ArrayList<>();
int row = maxValues.length - 1;
int col = maxValues[0].length - 1;
maxValue.add(maxValues[row][col]);
solution.add(maxValue);
while (row > 0 && col >= 0)
{
// checks if we added the item to the knapsack?
if (maxValues[row][col] == maxValues[row - 1][col]) // not added
{
row = row - 1;
}
else // added
{
indexes.add(0, row - 1); // insert at front otherwise need to reverse
row = row - 1;
col = col - items[row][1]; // itemWeight
}
}
solution.add(indexes);
return solution;
}
// time : O(nc) | space : O(nc)
public static List<List<Integer>> knapsackProblem(int[][] items, int capacity)
{
int maxValues [][] = new int[items.length + 1][capacity+1];
for (int row = 1; row < maxValues.length; ++row)
{
int currentValue = items[row - 1][0];
int currentWeight = items[row - 1][1];
for (int c = 0; c <= capacity; ++c)
{
if (c < currentWeight)
{
// item not added
maxValues[row][c] = maxValues[row - 1][c];
}
else
{
// item can be added
maxValues[row][c] = Math.max(maxValues[row - 1][c], maxValues[row - 1][c - currentWeight] + currentValue);
}
}
}
return generateSolution(maxValues, items);
}
}