-
Notifications
You must be signed in to change notification settings - Fork 0
/
dynamic_programming.jl
52 lines (43 loc) · 1.83 KB
/
dynamic_programming.jl
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
function build_config(A::Array{UInt32, 2}, take::BitArray{2}, weights::Array{UInt32, 1}, n_items::Int64, knapsack_capacity::UInt32)
""" Builds the optimal solution using the results of the DP algorithm """
best_config = falses(n_items)
weight = knapsack_capacity
for item = n_items : -1 : 1
if take[item + 1, weight + 1] == 1
best_config[item] = 1
weight -= weights[item]
end
end
return best_config
end
function dynamic_programming_knapsack(weights::Array{UInt32, 1}, values::Array{UInt32, 1}, knapsack_capacity::UInt32)
"""
Finds an optimal solution to the 0-1 Knapsack problem using Dynamic Programming:
OPT(n, w) = max(OPT(n-1, w - weights[w]), OPT(n-1, w))
"""
n_items = size(weights, 1)
A = zeros(UInt32, n_items + 1, knapsack_capacity + 1)
take = falses(n_items + 1, knapsack_capacity + 1)
for item = 2 : n_items + 1
for weight = 2 : knapsack_capacity + 1
if weights[item - 1] < weight
if values[item - 1] + A[item - 1, weight - weights[item - 1]] > A[item - 1, weight]
A[item, weight] = values[item - 1] + A[item - 1, weight - weights[item - 1]]
take[item, weight] = 1
else
A[item, weight] = A[item - 1, weight]
end
else
A[item, weight] = A[item - 1, weight]
end
end
end
return build_config(A, take, weights, n_items, knapsack_capacity)
end
function run_dp(weights::Array{UInt32, 1}, values::Array{UInt32, 1}, knapsack_capacity::UInt32)
""" runs the above function, while also returning the execution time """
exe_time = @timed begin
best_config = dynamic_programming_knapsack(weights, values, knapsack_capacity)
end
return best_config, exe_time.time
end