Add knapsack implementation.
This commit is contained in:
parent
0dad7a3244
commit
3d45bd3da3
40
knapsack.cr
Normal file
40
knapsack.cr
Normal file
|
@ -0,0 +1,40 @@
|
|||
class Array(T)
|
||||
def knapsack(budget, &cv : T -> {Int32,Int32})
|
||||
cost_values = map &cv
|
||||
|
||||
memo = {} of {Int32, Int32} => Int32
|
||||
bt = {} of {Int32, Int32} => Bool
|
||||
compute = uninitialized Int32, Int32 -> Int32
|
||||
compute = ->(size : Int32, budget : Int32) {
|
||||
if m = memo[{size, budget}]?
|
||||
return m
|
||||
end
|
||||
return memo[{size, budget}] = 0 if size == 0
|
||||
|
||||
cost, value = cost_values[size-1]
|
||||
no_val = compute.call(size-1, budget)
|
||||
yes_val = (budget < cost) ? 0 : compute.call(size-1, budget - cost) + value
|
||||
|
||||
if yes_val > no_val
|
||||
bt[{size, budget}] = true
|
||||
return yes_val
|
||||
else
|
||||
bt[{size, budget}] = false
|
||||
return no_val
|
||||
end
|
||||
}
|
||||
|
||||
value = compute.call(size, budget)
|
||||
i = size
|
||||
items = [] of T
|
||||
puts bt
|
||||
while i != 0
|
||||
if bt[{i, budget}]
|
||||
items << self[i-1]
|
||||
budget -= cost_values[i-1][0]
|
||||
end
|
||||
i -= 1
|
||||
end
|
||||
{value, items}
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user