How to resolve the algorithm Knapsack problem/Unbounded step by step in the jq programming language
How to resolve the algorithm Knapsack problem/Unbounded step by step in the jq programming language
Table of Contents
Problem Statement
A traveler gets diverted and has to make an unscheduled stop in what turns out to be Shangri La. Opting to leave, he is allowed to take as much as he likes of the following items, so long as it will fit in his knapsack, and he can carry it. He knows that he can carry no more than 25 'weights' in total; and that the capacity of his knapsack is 0.25 'cubic lengths'. Looking just above the bar codes on the items he finds their weights and volumes. He digs out his recent copy of a financial paper and gets the value of each item.
He can only take whole units of any item, but there is much more of any item than he could ever carry
Show how many of each item does he take to maximize the value of items he is carrying away with him.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Knapsack problem/Unbounded step by step in the jq programming language
Source code in the jq programming language
def Item($name; $value; $weight; $volume):
{$name, $value, $weight, $volume};
def items:[
Item("panacea"; 3000; 0.3; 0.025),
Item("ichor"; 1800; 0.2; 0.015),
Item("gold"; 2500; 2; 0.002)
];
def array($init): [range(0; .) | $init];
# input: {count, best, bestvalue}
def knapsack($i; $value; $weight; $volume):
(items|length) as $n
| if $i == $n
then if $value > .bestValue
then .bestValue = $value
| reduce range(0; $n) as $j (.; .best[$j] = .count[$j])
else .
end
else (($weight / items[$i].weight)|floor) as $m1
| (($volume / items[$i].volume)|floor) as $m2
| .count[$i] = ([$m1, $m2] | min)
| until (.count[$i] < 0;
knapsack(
$i + 1;
$value + .count[$i] * (items[$i].value);
$weight - .count[$i] * (items[$i].weight);
$volume - .count[$i] * (items[$i].volume)
)
| .count[$i] += -1
)
end ;
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
def solve($maxWeight; $maxVolume):
def rnd: 100 * . | round / 100;
def rnd($width): if type == "string" then lpad($width) else rnd|lpad($width) end;
def f(a;b;c;d;f):
"\(a|lpad(11)) \(b|rnd(6)) \(c|rnd(6)) \(d|rnd(6)) \(f|rnd(6))" ;
def f: . as [$a,$b,$c,$d,$f] | f($a;$b;$c;$d;$f);
(items|length) as $n
| def init:
{ count: ($n|array(0)),
best : ($n|array(0)),
bestValue: 0,
maxWeight: $maxWeight,
maxVolume: $maxVolume };
f("Item Chosen"; "Number"; "Value"; "Weight"; "Volume"),
"----------- ------ ------ ------ ------",
( init
| knapsack(0; 0; $maxWeight; $maxVolume)
| reduce range(0; $n) as $i (
. + {itemCount:0, sumNumber:0, sumWeight:0, sumVolume:0 };
if (.best[$i]) != 0
then .itemCount += 1
| .name = items[$i].name
| .number = .best[$i]
| .value = items[$i].value * .number
| .weight = items[$i].weight * .number
| .volume = items[$i].volume * .number
| .sumNumber += .number
| .sumWeight += .weight
| .sumVolume += .volume
| .emit += [ f(.name; .number; .value; .weight; .volume) ]
else .
end)
| .emit[],
"----------- ------ ------ ------ ------",
f(.itemCount; .sumNumber; .bestValue; .sumWeight; .sumVolume) );
solve(25; 0.25)
You may also check:How to resolve the algorithm Kernighans large earthquake problem step by step in the Ruby programming language
You may also check:How to resolve the algorithm Sieve of Eratosthenes step by step in the Cowgol programming language
You may also check:How to resolve the algorithm Ethiopian multiplication step by step in the Draco programming language
You may also check:How to resolve the algorithm Best shuffle step by step in the Haskell programming language
You may also check:How to resolve the algorithm String prepend step by step in the OCaml programming language