Knapsack problem/Unbounded: Difference between revisions
m
→{{header|Wren}}: Minor tidy
(Whole Scala contribution erased without a reason.) |
m (→{{header|Wren}}: Minor tidy) |
||
(28 intermediate revisions by 16 users not shown) | |||
Line 1:
{{task|Classic CS problems and programs}}
A traveler gets diverted and has to make an unscheduled stop in what turns out to be Shangri La. Opting to leave,
Looking just above the bar codes on the items he finds their weights and volumes
<table
cellpadding="2" cellspacing="2"><tr><td
valign="middle">Explanation</td><td
valign="middle">Volume (each)</td></tr><tr><td
(vials of)</td><td align="left" nowrap="nowrap"
align="left" nowrap="nowrap" valign="middle">0.025</td></tr><tr><td
(ampules of)</td><td align="left" nowrap="nowrap"
align="left" nowrap="nowrap" valign="middle">0.015</td></tr><tr><td
(bars)</td><td
valign="middle">Shiney shiney</td><td align="left"
align="left" nowrap="nowrap" valign="middle">0.002</td></tr><tr><td
style="background-color: rgb(255, 204, 255);" align="left"
nowrap="nowrap" valign="middle">Knapsack</td><td
style="background-color: rgb(255, 204, 255);" align="left"
nowrap="nowrap" valign="middle">For the carrying of</td><td
style="background-color: rgb(255, 204, 255);" align="left"
nowrap="nowrap" valign="middle">-</td><td
style="background-color: rgb(255, 204, 255);" align="left"
nowrap="nowrap" valign="middle"><=25</td><td
style="background-color: rgb(255, 204, 255);" align="left"
nowrap="nowrap" valign="middle"><=0.25 </td></tr>
</table>
<br>
;Task:
Show how many of each item
;Note:
* There are four solutions that maximize the value taken. Only one ''need'' be given.
<!-- All solutions
# ((value, -weight, -volume), (#panacea, #ichor, #gold)
[((54500, -25.0, -0.24699999999999997), (0, 15, 11)),
Line 53 ⟶ 71:
# (9, 0, 11) also minimizes weight and volume within the limits of calculation
-->
;Related tasks:
* [[Knapsack problem/Bounded]]
* [[Knapsack problem/Continuous]]
* [[Knapsack problem/0-1]]
<br><br>
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">T Bounty
Int value
Float weight, volume
F (value, weight, volume)
(.value, .weight, .volume) = (value, weight, volume)
V panacea = Bounty(3000, 0.3, 0.025)
V ichor = Bounty(1800, 0.2, 0.015)
V gold = Bounty(2500, 2.0, 0.002)
V sack = Bounty( 0, 25.0, 0.25)
V best = Bounty( 0, 0, 0)
V current = Bounty( 0, 0, 0)
V best_amounts = (0, 0, 0)
V max_panacea = Int(min(sack.weight I/ panacea.weight, sack.volume I/ panacea.volume))
V max_ichor = Int(min(sack.weight I/ ichor.weight, sack.volume I/ ichor.volume))
V max_gold = Int(min(sack.weight I/ gold.weight, sack.volume I/ gold.volume))
L(npanacea) 0 .< max_panacea
L(nichor) 0 .< max_ichor
L(ngold) 0 .< max_gold
current.value = npanacea * panacea.value + nichor * ichor.value + ngold * gold.value
current.weight = npanacea * panacea.weight + nichor * ichor.weight + ngold * gold.weight
current.volume = npanacea * panacea.volume + nichor * ichor.volume + ngold * gold.volume
I current.value > best.value & current.weight <= sack.weight & current.volume <= sack.volume
best = current
best_amounts = (npanacea, nichor, ngold)
print(‘Maximum value achievable is ’best.value)
print(‘This is achieved by carrying (one solution) #. panacea, #. ichor and #. gold’.format(best_amounts[0], best_amounts[1], best_amounts[2]))
print(‘The weight to carry is #2.1 and the volume used is #.3’.format(best.weight, best.volume))</syntaxhighlight>
{{out}}
<pre>
Maximum value achievable is 54500
This is achieved by carrying (one solution) 0 panacea, 15 ichor and 11 gold
The weight to carry is 25.0 and the volume used is 0.247
</pre>
=={{header|360 Assembly}}==
{{trans|Visual Basic}}
The program uses two ASSIST macros (XDECO,XPRNT) to keep the code as short as possible.
<
KNAPSACK CSECT
USING KNAPSACK,R13 base register
Line 256 ⟶ 321:
PG DS CL72
YREGS
END KNAPSACK</
{{out}}
<pre>
Value Weight Volume Panacea Ichor Gold
54500 24.7 0.247 9 0 11
54500 24.8 0.247 6 5 11
Line 264 ⟶ 330:
54500 25.0 0.247 0 15 11
</pre>
=={{header|Ada}}==
{{trans|Python}}
<
procedure Knapsack_Unbounded is
Line 331 ⟶ 397:
Ada.Text_IO.Put_Line ("Ichor: " & Natural'Image (Best_Amounts (2)));
Ada.Text_IO.Put_Line ("Gold: " & Natural'Image (Best_Amounts (3)));
end Knapsack_Unbounded;</
=={{header|ALGOL 68}}==
{{trans|Python}}<
[]BOUNTY items = (
Line 442 ⟶ 509:
name OF items, max items));
printf(($" The weight to carry is "f(d)", and the volume used is "f(d)l$,
weight OF max, volume OF max))</
The number of (panacea, ichor, gold) items to achieve this is: ( 9, 0, 11) respectively
The weight to carry is 247, and the volume used is 247</pre>
=={{header|AutoHotkey}}==
Brute Force.
<
Value = 3000,1800,2500
Weight= 3,2,20 ; *10
Line 473 ⟶ 540:
}
}
MsgBox Value = %$%`n`nPanacea`tIchor`tGold`tWeight`tVolume`n%t%</
=={{header|Bracmat}}==
<
( things
= (panacea.3000.3/10.25/1000)
Line 545 ⟶ 613:
!knapsack;
</syntaxhighlight>
Output:
<pre>Take 15 items of ichor.
Finally take 11 items of gold.
The value in the knapsack is 54500.</pre>
=={{header|C}}==
figures out the best (highest value) set by brute forcing every possible subset.
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
Line 609 ⟶ 681:
return 0;
}
</syntaxhighlight>
{{output}}<pre>9 panacea
0 ichor
11 gold
best value: 54500
</pre>
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">/* Items Value Weight Volume
a 30 3 25
b 18 2 15
c 25 20 2
<=250 <=250 */
using System;
class Program
{
static void Main()
{
uint[] r = items1();
Console.WriteLine(r[0] + " v " + r[1] + " a " + r[2] + " b"); // 0 15 11
var sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 1000; i > 0; i--) items1();
Console.Write(sw.Elapsed); Console.Read();
}
static uint[] items0() // 1.2 µs
{
uint v, v0 = 0, a, b, c, a0 = 0, b0 = 0, c0 = 0;
for (a = 0; a <= 10; a++)
for (b = 0; a * 5 + b * 3 <= 50; b++)
for (c = 0; a * 25 + b * 15 + c * 2 <= 250 && a * 3 + b * 2 + c * 20 <= 250; c++)
if (v0 < (v = a * 30 + b * 18 + c * 25))
{
v0 = v; a0 = a; b0 = b; c0 = c;
//Console.WriteLine("{0,5} {1,5} {2,5} {3,5}", v, a, b, c);
}
return new uint[] { a0, b0, c0 };
}
static uint[] items1() // 0,22 µs
{
uint v, v0 = 0, a, b, c, a0 = 0, b0 = 0, c0 = 0, c1 = 0;
for (a = 0; a <= 10; a++)
for (b = 0; a * 5 + b * 3 <= 50; b++)
{
c = (250 - a * 25 - b * 15) / 2;
if ((c1 = (250 - a * 3 - b * 2) / 20) < c) c = c1;
if (v0 < (v = a * 30 + b * 18 + c * 25))
{ v0 = v; a0 = a; b0 = b; c0 = c; }
}
return new uint[] { a0, b0, c0 };
}
}</syntaxhighlight>
=={{header|C_sharp|C#}}==
<
This model finds the integer optimal packing of a knapsack
Line 669 ⟶ 792:
}
}
}</
Produces:
<pre>
===Solver Foundation Service Report===
Date: 28/01/2012 17:18:56
Version: Microsoft Solver Foundation 3.0.1.10599 Express Edition
Line 704 ⟶ 829:
take(Panacea): 9
take(Ichor): 0
take(Gold): 11
</pre>
=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
struct Item {
std::string name;
int32_t value;
double weight;
double volume;
};
const std::vector<Item> items = {
Item("panacea", 3000, 0.3, 0.025),
Item("ichor", 1800, 0.2, 0.015),
Item("gold", 2500, 2.0, 0.002)
};
constexpr double MAX_WEIGHT = 25.0;
constexpr double MAX_VOLUME = 0.25;
std::vector<int32_t> count(items.size(), 0);
std::vector<int32_t> best(items.size(), 0);
int32_t best_value = 0;
void knapsack(const uint64_t& i, const int32_t& value, const double& weight, const double& volume) {
if ( i == items.size() ) {
if ( value > best_value ) {
best_value = value;
best = count;
}
return;
}
int32_t measure1 = (int32_t) std::floor( weight / items[i].weight );
int32_t measure2 = (int32_t) std::floor( volume / items[i].volume );
int32_t measure = std::min(measure1, measure2);
count[i] = measure;
while ( 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]--;
}
}
int main() {
knapsack(0, 0, MAX_WEIGHT, MAX_VOLUME);
std::cout << "Item Chosen Number Value Weight Volume" << std::endl;
std::cout << "----------- ------ ----- ------ ------" << std::endl;
int32_t item_count = 0;
int32_t number_sum = 0;
double weight_sum = 0.0;
double volume_sum = 0.0;
for ( uint64_t i = 0; i < items.size(); ++i ) {
if ( best[i] == 0 ) {
continue;
}
item_count++;
std::string name = items[i].name;
int32_t number = best[i];
int32_t value = items[i].value * number;
double weight = items[i].weight * number;
double volume = items[i].volume * number;
number_sum += number;
weight_sum += weight;
volume_sum += volume;
std::cout << std::setw(11) << name << std::setw(6) << number << std::setw(8) << value << std::fixed
<< std::setw(8) << std::setprecision(2) << weight
<< std::setw(8) << std::setprecision(2) << volume << std::endl;
}
std::cout << "----------- ------ ----- ------ ------" << std::endl;
std::cout << std::setw(5) << item_count << " items" << std::setw(6) << number_sum << std::setw(8) << best_value
<< std::setw(8) << weight_sum << std::setw(8) << volume_sum << std::endl;
}
</syntaxhighlight>
{{ out }}
<pre>
Item Chosen Number Value Weight Volume
----------- ------ ----- ------ ------
panacea 9 27000 2.70 0.23
gold 11 27500 22.00 0.02
----------- ------ ----- ------ ------
2 items 20 54500 24.70 0.25
</pre>
=={{header|Clojure}}==
<
(defn total [key items quantities]
Line 714 ⟶ 939:
(let [mcw (/ max-weight (:weight item))
mcv (/ max-volume (:volume item))]
(min mcw mcv)))</
We have an <tt>item</tt> struct to contain the data for both contents and the knapsack. The <tt>total</tt> function returns the sum of a particular attribute across all items times their quantities. Finally, the <tt>max-count</tt> function returns the most of that item that could fit given the constraints (used as the upper bound on the combination). Now the real work:
<
(let [pan (struct item 3000 0.3 0.025)
ich (struct item 1800 0.2 0.015)
Line 734 ⟶ 959:
i (iters ich)
g (iters gol)]
[p i g])))))</
The <tt>knapsacks</tt> function returns a lazy sequence of all valid knapsacks, with the particular content quantities as metadata. The work of realizing each knapsack is done in parallel via the <tt>pmap</tt> function. The following then finds the best by value, and prints the result.
<
(reduce #(if (> (:value %1) (:value %2)) %1 %2) ks))
Line 745 ⟶ 970:
(println "Total weight: " (float w))
(println "Total volume: " (float v))
(println "Containing: " p "Panacea," i "Ichor," g "Gold")))</
Calling <tt>(print-knapsack (best-by-value (knapsacks)))</tt> would result in something like:
<pre>Maximum value: 54500
Total weight: 24.7
Total volume: 0.247
Containing: 9 Panacea, 0 Ichor, 11 Gold</pre>
Further, we could find all "best" knapsacks rather simply (albeit at the cost of some efficiency):
<
(let [b (best-by-value ks)]
(filter #(= (:value b) (:value %)) ks)))
Line 758 ⟶ 984:
(doseq [k ks]
(print-knapsack k)
(println)))</
Calling <tt>(print-knapsacks (all-best-by-value (knapsacks)))</tt> would result in something like:
<pre>
Maximum value: 54500.0
Total weight: 25.0
Total volume: 0.247
Line 777 ⟶ 1,005:
Total weight: 24.7
Total volume: 0.247
Containing: 9 Panacea, 0 Ichor, 11 Gold
</pre>
=={{header|Common Lisp}}==
A dynamic programming <i>O(maxVolume × maxWeight × nItems)</i> solution, where volumes and weights are integral values.
<
"Items is a list of lists of the form (name value weight volume) where weight
and value are integers. max-volume and max-weight, also integers, are the
Line 823 ⟶ 1,053:
b-items (list* item o-items)))))))
(setf (aref maxes v w)
(list b-value b-items b-volume b-weight))))))))</
Use, having multiplied volumes and weights as to be integral:
Line 842 ⟶ 1,072:
250 ; total volume
247) ; total weight</pre>
=={{header|D}}==
{{trans|Python}}
<
import std.stdio, std.algorithm, std.typecons, std.conv;
Line 894 ⟶ 1,125:
writefln("The weight to carry is %4.1f and the volume used is %5.3f",
best.weight, best.volume);
}</
{{out}}
<pre>Maximum value achievable is 54500
This is achieved by carrying (one solution) 0 panacea, 15 ichor and 11 gold
The weight to carry is 25.0 and the volume used is 0.247</pre>
===Alternative Version===
The output is the same.
<
import std.stdio, std.algorithm, std.typecons, std.range, std.conv;
Line 926 ⟶ 1,158:
writefln("This is achieved by carrying (one solution) %d panacea, %d ichor and %d gold", best[1][]);
writefln("The weight to carry is %4.1f and the volume used is %5.3f", best[0][1..$]);
}</
=={{header|E}}==
This is a mostly brute-force general solution (the first author of this example does not know dynamic programming); the only optimization is that when considering the last (third) treasure type, it does not bother filling with anything but the maximum amount.
<
/** A data type representing a bunch of stuff (or empty space). */
Line 1,009 ⟶ 1,241:
:= makeQuantity( 0, 25, 0.250, [].asMap())
printBest(emptyKnapsack, [panacea, ichor, gold])</
=={{header|EchoLisp}}==
Use a cache, and multiply by 10^n to get an integer problem.
<
(require 'struct)
(require 'hash)
Line 1,082 ⟶ 1,315:
(length (hash-keys H)) ;; # entries in cache
→ 218
</syntaxhighlight>
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
class
KNAPSACK
Line 1,166 ⟶ 1,402:
end
end
</syntaxhighlight>
{{out}}
<pre>
Maximum value achievable is 54500.
This is achieved by carrying 0 panacea, 15 ichor and 11 gold.
The weight is 25 and the volume is 0.247.
</pre>
=={{header|Elixir}}==
Brute Force:
<
defstruct volume: 0.0, weight: 0.0, value: 0
def new(volume, weight, value) do
Line 1,224 ⟶ 1,463:
gold: Item.new(0.002, 2.0, 2500) }
maximum = Item.new(0.25, 25, 0)
Knapsack.solve_unbounded(items, maximum)</
{{out}}
<pre>
Maximum value achievable is 54500 volume weight value
[gold: 11, ichor: 0, panacea: 9] => 0.247, 24.7, 54500
[gold: 11, ichor: 5, panacea: 6] => 0.247, 24.8, 54500
Line 1,232 ⟶ 1,473:
[gold: 11, ichor: 15, panacea: 0] => 0.247, 25.0, 54500
</pre>
=={{header|Factor}}==
This is a brute force solution. It is general enough to be able to provide solutions for any number of different items.
<
math.vectors sequences sequences.product combinators.short-circuit ;
IN: knapsack
Line 1,275 ⟶ 1,516:
: best-bounty ( -- bounty )
find-max-amounts [ 1 + iota ] map <product-sequence>
[ <bounty> ] [ max ] map-reduce ;</
=={{header|Forth}}==
<
: weight cell+ ;
: volume 2 cells + ;
Line 1,336 ⟶ 1,578:
solve-ichor ;
solve-panacea .solution</
Or like this...
<
0 VALUE ampules
0 VALUE bars
Line 1,371 ⟶ 1,613:
LOOP
LOOP
.SOLUTION ;</
With the result...
Line 1,377 ⟶ 1,619:
The traveller's knapsack contains 0 vials of panacea, 15 ampules of ichor,
11 bars of gold, a total value of 54500. ok
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
A straight forward 'brute force' approach
<
IMPLICIT NONE
Line 1,427 ⟶ 1,670:
WRITE(*, "(A,F4.1,A,F5.3)") "The weight to carry is ", totalWeight, " and the volume used is ", totalVolume
END PROGRAM KNAPSACK</
Sample output
Maximum value achievable is 54500
This is achieved by carrying 0 panacea, 15 ichor and 11 gold items
The weight to carry is 25.0 and the volume used is 0.247
=={{header|FreeBASIC}}==
{{trans|PureBASIC}}
<syntaxhighlight lang="vb">#define min(a, b) iif((a) < (b), (a), (b))
Dim As Single totalPeso, totalVolumen
Dim As Integer maxPanacea, maxIchor, maxGold, maxValor
Dim As Integer i, j ,k
Dim As Integer n(2)
Type Bounty
articulo As String*7
valor As Integer
peso As Single
volumen As Single
End Type
Dim item(1 To 5) As Bounty => { _
("panacea", 3000, 0.3, 0.025), ("ichor", 1800, 0.2, 0.015), _
("gold", 2500, 2.0, 0.002), ("sack", 0, 25.0, 0.25 )}
maxPanacea = min(item(4).peso/item(1).peso, item(4).volumen/item(1).volumen)
maxIchor = min(item(4).peso/item(2).peso, item(4).volumen/item(2).volumen)
maxGold = min(item(4).peso/item(3).peso, item(4).volumen/item(3).volumen)
For i = 0 To maxPanacea
For j = 0 To maxIchor
For k = 0 To maxGold
item(0).valor = k*item(3).valor + j*item(2).valor + i*item(1).valor
item(0).peso = k*item(3).peso + j*item(2).peso + i*item(1).peso
item(0).volumen = k*item(3).volumen + j*item(2).volumen + i*item(1).volumen
If item(0).peso > item(4).peso Or item(0).volumen > item(4).volumen Then
Continue For
End If
If item(0).valor > maxValor Then
maxValor = item(0).valor
totalPeso = item(0).peso
totalVolumen = item(0).volumen
n(0) = i: n(1) = j: n(2) = k
End If
Next k
Next j
Next i
Print "Maximum valor achievable is "; Str(maxValor)
Print "This is achieved by carrying "; Str(n(0));
Print " panacea, "; Str(n(1)); " ichor and "; Str(n(2)); " gold items."
Print "The peso to carry is "; Str(totalPeso);
Print " and the volume used is "; Str(totalVolumen)
Sleep</syntaxhighlight>
{{out}}
<pre>Maximum valor achievable is 54500
This is achieved by carrying 0 panacea, 15 ichor and 11 gold items
The peso to carry is 25 and the volume used is 0.247</pre>
=={{header|Go}}==
Recursive brute-force.
<
import "fmt"
Line 1,499 ⟶ 1,798:
fmt.Printf("TOTAL (%3d items) Weight: %4.1f Volume: %5.3f Value: %6d\n",
sumCount, sumWeight, sumVolume, sumValue)
}</
Output:
<pre>
Panacea x 9 -> Weight: 2.7 Volume: 0.225 Value: 27000
Ichor x 0 -> Weight: 0.0 Volume: 0.000 Value: 0
Gold x 11 -> Weight: 22.0 Volume: 0.022 Value: 27500
TOTAL ( 20 items) Weight: 24.7 Volume: 0.247 Value: 54500
</pre>
=={{header|Groovy}}==
Solution: dynamic programming
<
def totalVolume = { list -> list.collect{ it.item.volume * it.count }.sum() }
def totalValue = { list -> list.collect{ it.item.value * it.count }.sum() }
Line 1,530 ⟶ 1,833:
}
m[n][wm][vm]
}</
Test:
<
items.eachPermutation { itemList ->
def start = System.currentTimeMillis()
Line 1,553 ⟶ 1,856:
it.item.name, it.count, it.item.weight * it.count, it.item.volume * it.count)
}
}</
Output:
<pre> Item Order: [panacea, ichor, gold]
Elapsed Time: 26.883 s
Line 1,583 ⟶ 1,888:
item: gold (bars) count:11 weight:22.0 Volume:0.022
item: panacea (vials of) count: 9 weight: 2.7 Volume:0.225</pre>
While this solver can only be used to detect two of the four possible solutions, the other two may be discovered by noting that 5 ampules of ichor and 3 vials of panacea have the same value and the same volume and only differ by 0.1 in weight. Thus the other two solutions can be derived by substitution as follows:
<pre>Total Weight: 24.9
Total Volume: 0.247
Total Value: 54500
Line 1,596 ⟶ 1,903:
item: ichor (ampules of) count: 5 weight: 1.0 Volume:0.075
item: panacea (vials of) count: 6 weight: 1.8 Volume:0.150</pre>
=={{header|Haskell}}==
This is a brute-force solution: it generates a list of every legal combination of items (<tt>options</tt>) and then finds the option of greatest value.
<
import Data.Ord (comparing)
Line 1,635 ⟶ 1,943:
main = putStr $ showOpt $ best options
where best = maximumBy $ comparing $ dotProduct vals</
Output:
<pre>panacea: 9
ichor: 0
gold: 11
Line 1,642 ⟶ 1,953:
total volume: 0.247
total value: 54500</pre>
=={{header|HicEst}}==
<
NN = ALIAS($Panacea, $Ichor, $Gold, wSack, wPanacea, wIchor, wGold, vSack, vPanacea, vIchor, vGold)
Line 1,670 ⟶ 1,982:
ENDDO
ENDDO
ENDDO</
<
value=54500; Panaceas=3; Ichors=10; Golds=11; weight=24.9; volume=0.247;
value=54500; Panaceas=6; Ichors=5; Golds=11; weight=24.8; volume=0.247;
value=54500; Panaceas=9; Ichors=0; Golds=11; weight=24.7; volume=0.247; </
=={{header|J}}==
Brute force solution.
<
prods=: <;. _1 ' panacea: ichor: gold:'
hdrs=: <;. _1 ' weight: volume: value:'
Line 1,694 ⟶ 2,007:
prtscr &.> hdrs ('total '&,@[,' ',":@])&.> mo ip"1 ws,vs,:vls
LF
)</
Example output:
<pre> KS''
panacea: 3
ichor: 10
Line 1,702 ⟶ 2,016:
total volume: 0.247
total value: 54500</pre>
=={{header|Java}}==
With recursion for more than 3 items.
<
import hu.pj.obj.Item;
Line 1,787 ⟶ 2,102:
} // main()
} // class</
<
public class Item {
Line 1,839 ⟶ 2,154:
}
} // class</
output:
<pre>Maximum value achievable is: 54500
This is achieved by carrying (one solution): 0 panacea, 15 ichor, 11 gold,
The weight to carry is: 25 and the volume used is: 0,247</pre>
=={{header|JavaScript}}==
Brute force.
<
panacea = { 'value': 3000, 'weight': 0.3, 'volume': 0.025 },
ichor = { 'value': 1800, 'weight': 0.2, 'volume': 0.015 },
Line 1,888 ⟶ 2,206:
item = solutions[i];
document.write("(gold: " + item[0] + ", panacea: " + item[1] + ", ichor: " + item[2] + ")<br>");
}
output:
<pre>maximum value: 54500
(gold: 11, panacea: 0, ichor: 15)
(gold: 11, panacea: 3, ichor: 10)
(gold: 11, panacea: 6, ichor: 5)
(gold: 11, panacea: 9, ichor: 0)</pre></syntaxhighlight>
=={{header|jq}}==
{{trans|Wren}}
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<syntaxhighlight lang="jq">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)</syntaxhighlight>
{{out}}
<pre>
Item Chosen Number Value Weight Volume
----------- ------ ------ ------ ------
panacea 9 27000 2.7 0.23
gold 11 27500 22 0.02
----------- ------ ------ ------ ------
2 20 54500 24.7 0.25
</pre>
=={{header|Julia}}==
{{libheader|JuMP}}<
using JuMP
using GLPKMathProgInterface
Line 1,918 ⟶ 2,334:
println("vials of panacea = ", getvalue(vials_of_panacea))
println("ampules of ichor = ", getvalue(ampules_of_ichor))
println("bars of gold = ", getvalue(bars_of_gold))</
{{output}}
<pre>
The optimization problem to be solved is:
Max 3000 vials_of_panacea + 1800 ampules_of_ichor + 2500 bars_of_gold
Subject to
Line 1,932 ⟶ 2,349:
vials of panacea = 9.0
ampules of ichor = 0.0
bars of gold = 11.0
</pre>
=={{header|Kotlin}}==
{{trans|C}}
Recursive brute force approach:
<
data class Item(val name: String, val value: Double, val weight: Double, val volume: Double)
Line 2,002 ⟶ 2,421:
print("${itemCount} items ${"%2d".format(sumNumber)} ${"%5.0f".format(bestValue)} ${"%4.1f".format(sumWeight)}")
println(" ${"%4.2f".format(sumVolume)}")
}</
{{out}}
<pre>
Item Chosen Number Value Weight Volume
----------- ------ ----- ------ ------
panacea 9 27000 2.7 0.23
gold 11 27500 22.0 0.02
----------- ------ ----- ------ ------
2 items 20 54500 24.7 0.25
</pre>
=={{header|Lua}}==
<syntaxhighlight lang="lua">items = { ["panaea"] = { ["value"] = 3000, ["weight"] = 0.3, ["volume"] = 0.025 },
["ichor"] = { ["value"] = 1800, ["weight"] = 0.2, ["volume"] = 0.015 },
["gold"] = { ["value"] = 2500, ["weight"] = 2.0, ["volume"] = 0.002 }
Line 2,085 ⟶ 2,469:
for k, v in pairs( best_amounts ) do
print( k, v )
end</
=={{header|MiniZinc}}==
<syntaxhighlight lang="minizinc">
%Knapsack problem/Unbounded. Nigel Galloway, August 13th., 2021
enum Items ={panacea,ichor,gold};
array[Items] of float: weight =[0.3,0.2,2.0]; constraint sum(n in Items)(take[n]*weight[n])<=25.0;
array[Items] of int: value =[3000,1800,2500];
array[Items] of float: volume =[0.025,0.015,0.002]; constraint sum(n in Items)(take[n]*volume[n])<=0.25;
array[Items] of var 0..floor(25.0/min(weight)): take;
solve maximize sum(n in Items)(value[n]*take[n]);
output(["Take "++show(take[panacea])++" vials of panacea\nTake "++show(take[ichor])++" ampules of ichor\nTake "++ show(take[gold])++" bars of gold\n"])
</syntaxhighlight>
{{out}}
<pre>
Take 0 vials of panacea
Take 15 ampules of ichor
Take 11 bars of gold
----------
==========
Finished in 159msec
</pre>
=={{header|M4}}==
A brute force solution:
<syntaxhighlight lang="m4">divert(-1)
define(`set2d',`define(`$1[$2][$3]',`$4')')
define(`get2d',`defn(`$1[$2][$3]')')
define(`for',
`ifelse($#,0,``$0'',
`ifelse(eval($2<=$3),1,
`pushdef(`$1',$2)$4`'popdef(`$1')$0(`$1',incr($2),$3,`$4')')')')
define(`min',
`define(`ma',eval($1))`'define(`mb',eval($2))`'ifelse(eval(ma<mb),1,ma,mb)')
define(`setv',
`set2d($1,$2,1,$3)`'set2d($1,$2,2,$4)`'set2d($1,$2,3,$5)`'set2d($1,$2,4,$6)')
dnl name,value (each),weight,volume
setv(a,0,`knapsack',0,250,250)
setv(a,1,`panacea',3000,3,25)
setv(a,2,`ichor',1800,2,15)
setv(a,3,`gold',2500,20,2)
define(`mv',0)
for(`x',0,min(get2d(a,0,3)/get2d(a,1,3),get2d(a,0,4)/get2d(a,1,4)),
`for(`y',0,min((get2d(a,0,3)-x*get2d(a,1,3))/get2d(a,2,3),
(get2d(a,0,4)-x*get2d(a,1,4))/get2d(a,2,4)),
`
define(`z',min((get2d(a,0,3)-x*get2d(a,1,3)-y*get2d(a,2,3))/get2d(a,3,3),
(get2d(a,0,4)-x*get2d(a,1,4)-y*get2d(a,2,4))/get2d(a,3,4)))
define(`cv',eval(x*get2d(a,1,2)+y*get2d(a,2,2)+z*get2d(a,3,2)))
ifelse(eval(cv>mv),1,
`define(`mv',cv)`'define(`best',(x,y,z))',
`ifelse(cv,mv,`define(`best',best (x,y,z))')')
')')
divert
mv best</syntaxhighlight>
Output:
<pre>54500 (0,15,11) (3,10,11) (6,5,11) (9,0,11)</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Brute force algorithm:
<
{iva,iwe,ivo}={1800,2/10,3/200};
{gva,gwe,gvo}={2500,2,2/1000};
Line 2,097 ⟶ 2,541:
data=Flatten[Table[{{p,i,g}.{pva,iva,gva},{p,i,g}.{pwe,iwe,gwe},{p,i,g}.{pvo,ivo,gvo},{p,i,g}},{p,0,pmax},{i,0,imax},{g,0,gmax}],2];
data=Select[data,#[[2]]<=25&&#[[3]]<=1/4&];
First[SplitBy[Sort[data,First[#1]>First[#2]&],First]]</
gives back an array of the best solution(s), with each element being value, weight, volume, {number of vials, number of ampules, number of bars}:
<
if we call the three items by their first letters the best packings are:
<
p:6 i:5 v:11
p:3 i:10 v:11
p:0 i:15 v:11</
The volume for all of those is the same, the 'best' solution would be the one that has the least weight: that would the first solution.
=={{header|Mathprog}}==
<
This model finds the integer optimal packing of a knapsack
Line 2,135 ⟶ 2,580:
;
end;</
The solution produced is at [[Knapsack problem/Unbounded/Mathprog]].
=={{header|Modula-3}}==
{{trans|Fortran}}
Note that unlike [[Fortran]] and [[C]], Modula-3 does not do any hidden casting, which is why <tt>FLOAT</tt> and <tt>FLOOR</tt> are used.
<
FROM IO IMPORT Put;
Line 2,186 ⟶ 2,632:
Put("This is achieved by carrying " & Int(n[1]) & " panacea, " & Int(n[2]) & " ichor and " & Int(n[3]) & " gold items\n");
Put("The weight of this carry is " & Real(totalWeight) & " and the volume used is " & Real(totalVolume) & "\n");
END Knapsack.</
Output:
<pre>Maximum value achievable is 54500
This is achieved by carrying 0 panacea, 15 ichor and 11 gold items
The weight of this carry is 25 and the volume used is 0.247</pre>
=={{header|Nim}}==
{{trans|Pascal}}
This is a brute-force solution translated from Pascal to Nim, which is straightforward.
<syntaxhighlight lang="nim"># Knapsack unbounded. Brute force solution.
import lenientops # Mixed float/int operators.
import strformat
type Bounty = tuple[value: int; weight, volume: float]
const
Panacea: Bounty = (value: 3000, weight: 0.3, volume: 0.025)
Ichor: Bounty = (value: 1800, weight: 0.2, volume: 0.015)
Gold: Bounty = (value: 2500, weight: 2.0, volume: 0.002)
Sack: Bounty = (value: 0, weight: 25.0, volume: 0.25)
MaxPanacea = min(Sack.weight / Panacea.weight, Sack.volume / Panacea.volume).toInt
MaxIchor = min(Sack.weight / Ichor.weight, Sack.volume / Ichor.volume).toInt
MaxGold = min(Sack.weight / Gold.weight, Sack.volume / Gold.volume).toInt
var
totalWeight, totalVolume: float
n: array[1..3, int] # Number of panacea, ichor and gold.
maxValue = 0
for i in 0..MaxPanacea:
for j in 0..MaxIchor:
for k in 0..MaxGold:
var current: Bounty
current.value = k * Gold.value + j * Ichor.value + i * Panacea.value
current.weight = k * Gold.weight + j * Ichor.weight + i * Panacea.weight
current.volume = k * Gold.volume + j * Ichor.volume + i * Panacea.volume
if current.value > maxValue and current.weight <= Sack.weight and current.volume <= Sack.volume:
maxvalue = current.value
totalweight = current.weight
totalvolume = current.volume
n = [i, j, k]
echo fmt"Maximum value achievable is {maxValue}."
echo fmt"This is achieved by carrying {n[1]} panacea, {n[2]} ichor and {n[3]} gold items."
echo fmt"The weight of this carry is {totalWeight:6.3f} and the volume used is {totalVolume:6.4f}."</syntaxhighlight>
{{out}}
<pre>
Maximum value achievable is 54500.
This is achieved by carrying 0 panacea, 15 ichor and 11 gold items.
The weight of this carry is 25.000 and the volume used is 0.2470.
</pre>
=={{header|OCaml}}==
This is a brute-force solution: it generates a list of every legal combination of items and then finds the best results:
<
let bounty n d w v = { name = n; value = d; weight = w; volume = v }
Line 2,267 ⟶ 2,764:
print_newline()
let () = List.iter print best_results</
outputs:
<pre>Maximum value: 54500
Total weight: 24.7
Total volume: 0.247
Line 2,287 ⟶ 2,786:
Total volume: 0.247
Containing: 0 panacea, 15 ichor, 11 gold</pre>
=={{header|OOCalc}}==
OpenOffice.org Calc has (several) linear solvers. To solve this task, first copy in the table from the task description, then add the extra columns:
Line 2,306 ⟶ 2,806:
to produce in seconds:
:[[File:Unbounded Knapsack problem result.PNG|center|Table solved]]
=={{header|Oz}}==
Using constraint propagation and branch and bound search:
<
proc {Knapsack Sol}
solution(panacea:P = {FD.decl}
Line 2,331 ⟶ 2,832:
{System.showInfo "\nResult:"}
{Show Best}
{System.showInfo "total value: "#{Value Best}}</
If you study the output, you see how the weight and volume equations automagically constrain the domain of the three variables.
Afterwards SearchBest only has to evaluate 38 different combinations to find an optimal solution
<pre>Search:
0#solution(gold:_{0#134217726} ichor:_{0#134217726} panacea:_{0#134217726})
1#solution(gold:_{0#12} ichor:_{0#125} panacea:_{0#83})
Line 2,379 ⟶ 2,882:
Result:
solution(gold:11 ichor:15 panacea:0)
total value: 54500
</pre>
=={{header|Pascal}}==
With ideas from C, Fortran and Modula-3.
<
uses
Line 2,435 ⟶ 2,940:
writeln ('This is achieved by carrying ', n[1], ' panacea, ', n[2], ' ichor and ', n[3], ' gold items');
writeln ('The weight of this carry is ', totalWeight:6:3, ' and the volume used is ', totalVolume:6:4);
end.</
Output:
<pre>:> ./Knapsack
Maximum value achievable is 54500
This is achieved by carrying 0 panacea, 15 ichor and 11 gold items
The weight of this carry is 25.000 and the volume used is 0.2470
</pre>
=={{header|Perl}}==
Dynamic programming solution. Before you ask, no, it's actually slower for the given data set. See the alternate data set.
<
if (1) { # change 1 to 0 for different data set
Line 2,512 ⟶ 3,020:
$wtot/$wsc, $vtot/$vsc, $x->[0];
print "\nCache hit: $hits\tmiss: $misses\n";</
Output:<pre>Max value 54500, with:
Item Qty Weight Vol Value
Line 2,523 ⟶ 3,032:
Cache hit: 0 miss: 218</pre>
Cache info is not pertinent to this task, just some info.
=={{header|Phix}}==
For each goodie, fill yer boots, then (except for the last) recursively try with fewer and fewer.<br>
Increase profit and decrease weight/volume to pick largest profit for least weight and space.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\knapsack.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">knapsack</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">goodies</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">profit</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">volume</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">at</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">={})</span>
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{?,</span><span style="color: #000000;">pitem</span><span style="color: #0000FF;">,</span><span style="color: #000000;">witem</span><span style="color: #0000FF;">,</span><span style="color: #000000;">vitem</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">goodies</span><span style="color: #0000FF;">[</span><span style="color: #000000;">at</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">/</span><span style="color: #000000;">witem</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">volume</span><span style="color: #0000FF;">/</span><span style="color: #000000;">vitem</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">chosen</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">n</span>
<span style="color: #000000;">profit</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">pitem</span> <span style="color: #000080;font-style:italic;">-- increase profit</span>
<span style="color: #000000;">weight</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">witem</span> <span style="color: #000080;font-style:italic;">-- decrease weight left</span>
<span style="color: #000000;">volume</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">vitem</span> <span style="color: #000080;font-style:italic;">-- decrease space left</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">at</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">goodies</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pwvc</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">profit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #000000;">volume</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #000000;">profit</span><span style="color: #0000FF;">></span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">pwvc</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">profit</span><span style="color: #0000FF;">=</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pwvc</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">else</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">knapsack</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">goodies</span><span style="color: #0000FF;">,</span><span style="color: #000000;">profit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #000000;">volume</span><span style="color: #0000FF;">,</span><span style="color: #000000;">at</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">chosen</span><span style="color: #0000FF;">[$]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
<span style="color: #000000;">profit</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">pitem</span>
<span style="color: #000000;">weight</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">witem</span>
<span style="color: #000000;">volume</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">vitem</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">goodies</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000080;font-style:italic;">-- item profit weight volume</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"ichor"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1800</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.015</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"panacea"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.025</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"shiney shiney"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2500</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.002</span><span style="color: #0000FF;">}},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">descs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">profits</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">vols</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">goodies</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--res is {{profit,(weight left),(space left),{counts}}}</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">knapsack</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">goodies</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">25</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0.25</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">profit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">counts</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">][</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">weight</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">counts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wts</span><span style="color: #0000FF;">)),</span> <span style="color: #000000;">volume</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">counts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">vols</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">what</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">,{{</span><span style="color: #008000;">"%2d %s"</span><span style="color: #0000FF;">},</span><span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({</span><span style="color: #000000;">counts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">descs</span><span style="color: #0000FF;">})}),</span><span style="color: #008000;">", "</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Profit %d: %s [weight:%.1f, volume:%g]\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">profit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">what</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #000000;">volume</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Profit 54500: 15 ichor, 0 panacea, 11 shiney shiney [weight:25.0, volume:0.247]
Profit 54500: 10 ichor, 3 panacea, 11 shiney shiney [weight:24.9, volume:0.247]
Profit 54500: 5 ichor, 6 panacea, 11 shiney shiney [weight:24.8, volume:0.247]
Profit 54500: 0 ichor, 9 panacea, 11 shiney shiney [weight:24.7, volume:0.247]
</pre>
=={{header|Picat}}==
This is a typical constraint modelling problem. We must use the MIP solver - using the mip module - for this problem since the data contains float values (which neither of the CP/SAT/SMT solvers support).
<syntaxhighlight lang="picat">import mip.
go =>
data(Items,Value,Weight,Volume,MaxWeight,MaxVolume),
knapsack_problem(Value,Weight,Volume,MaxWeight,MaxVolume, X,Z),
println(z=Z),
println(x=X),
N = Items.len,
foreach({Item,Num} in zip(Items,X), Num > 0)
printf("Take %d of %w\n", Num,Item)
end,
print("\nTotal volume: "),
println(sum([X[I]*Volume[I] : I in 1..N])),
print("Total weight: "),
println(sum([X[I]*Weight[I] : I in 1..N])),
print("Total cost: "),
println(sum([X[I]*Value[I] : I in 1..N])),
nl.
knapsack_problem(Value,Weight,Volume,MaxWeight,MaxVolume, X,Z) =>
println([max_weight=MaxWeight,max_volume=MaxVolume,z=Z]),
N = Value.length,
X = new_list(N),
X :: 0..1000,
Z #= sum([X[I]*Value[I] : I in 1..N]),
foreach(I in 1..N)
X[I] #>= 0
end,
limit(Weight, X, MaxWeight),
limit(Volume, X, MaxVolume),
if var(Z) then
println(maximize),
solve($[glpk,max(Z)], X)
else
solve($[glpk], X)
end.
limit(W, Take, WTMax) =>
sum([W[I]*Take[I] : I in 1..W.length]) #<= WTMax.
% data
data(Items,Value,Weight,Volume,MaxWeight,MaxVolume) =>
Items = ["panacea","ichor","gold"],
Value = [3000.0, 1800.0, 2500.0 ],
Weight = [ 0.3,
Volume = [ 0.025, 0.015, 0.002],
MaxWeight = 25.0,
MaxVolume = 0.25.</syntaxhighlight>
{{out}}
<pre>z = 54500
x = [9,0,11]
Take 9 of panacea
Take 11 of gold
Total volume: 0.247
Total weight: 24.699999999999999
Total cost: 54500.0</pre>
=={{header|PicoLisp}}==
Brute force solution
<
("panacea" 3 25 3000)
("ichor" 2 15 1800)
Line 2,656 ⟶ 3,187:
(inc 'N) )
(apply tab X (4 2 8 5 5 7) N "x") ) )
(tab (14 5 5 7) NIL (sum cadr K) (sum caddr K) (sum cadddr K)) )</
Output:
<pre> 15 x ichor 2 15 1800
11 x gold 20 2 2500
250 247 54500</pre>
=={{header|PowerShell}}==
{{works with|PowerShell|3.0}}
<
$Item = @(
[pscustomobject]@{ Name = 'panacea'; Unit = 'vials' ; value = 3000; Weight = 0.3; Volume = 0.025 }
Line 2,723 ⟶ 3,256:
# Show the results
$Solutions</
{{out}}
<pre>0 vials of panacea, 15 ampules of ichor, and 11 bars of gold worth a total of 54500.
Line 2,729 ⟶ 3,262:
6 vials of panacea, 5 ampules of ichor, and 11 bars of gold worth a total of 54500.
9 vials of panacea, 0 ampules of ichor, and 11 bars of gold worth a total of 54500.</pre>
=={{header|Prolog}}==
Works with SWI-Prolog and <b>library simplex</b> written by <b>Markus Triska</b>.
<
% tuples (name, Explantion, Value, weights, volume).
Line 2,816 ⟶ 3,350:
W2 is W1 + Wtemp,
Vo2 is Vo1 + Votemp ),
print_results(S, A0, A1, A2, A3, A4, T, TN, Va2, W2, Vo2).</
Output :
<pre> ?- knapsack.
% 145,319 inferences, 0.078 CPU in 0.079 seconds (99% CPU, 1860083 Lips)
Nb Items Value Weigth Volume
Line 2,824 ⟶ 3,359:
54500 25.00 0.247
true </pre>
=={{header|PureBasic}}==
{{trans|Fortran}}
<
Define.i maxPanacea, maxIchor, maxGold, maxValue
Define.i i, j ,k
Line 2,907 ⟶ 3,443:
Data.i 0
Data.f 25.0, 0.25
EndDataSection</
Outputs
Line 2,916 ⟶ 3,452:
Press Enter to quit</tt>
=={{header|Python}}==
See [[Knapsack Problem/Python]]
=={{header|R}}==
Brute force method
<
weights <- c(panacea=0.3, ichor=0.2, gold=2.0)
volumes <- c(panacea=0.025, ichor=0.015, gold=0.002)
Line 2,941 ⟶ 3,479:
# Find the solutions with the highest value
vals <- apply(knapok, 1, getTotalValue)
knapok[vals == max(vals),]</
panacea ichor gold
2067 9 0 11
Line 2,947 ⟶ 3,485:
2171 3 10 11
2223 0 15 11
Using Dynamic Programming
<syntaxhighlight lang="r">
Data_<-structure(list(item = c("Panacea", "Ichor", "Gold"), value = c(3000,
1800, 2500), weight = c(3, 2, 20), volume = c(25, 15, 2)), .Names = c("item",
"value", "weight", "volume"), row.names = c(NA, 3L), class = "data.frame")
Line 3,036 ⟶ 3,577:
}
main_knapsack(Data_, 250, 250)
</syntaxhighlight>
<syntaxhighlight lang="r">
Output:
The Total profit is: 54500
You must carry: Gold (x 11 )
You must carry: Panacea (x 9 )
</syntaxhighlight>
=={{header|Racket}}==
<syntaxhighlight lang="racket">
#lang racket
(struct item (name explanation value weight volume) #:prefab)
Line 3,082 ⟶ 3,627:
(call-with-values (λ() (fill-sack items 0.25 25 '() 0))
(λ(sacks total) (for ([s sacks]) (display-sack s total))))
</syntaxhighlight>
{{out}}
<pre>Take 11 gold (bars)
Line 3,103 ⟶ 3,650:
Take 9 panacea (vials of)
GRAND TOTAL: 54500</pre>
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2019.03.1}}
Brute force, looked a lot at the Ruby solution.
<syntaxhighlight lang="raku" line>class KnapsackItem {
has $.volume;
has $.weight;
has $.value;
has $.name;
method new($volume,$weight,$value,$name) {
self.bless(:$volume, :$weight, :$value, :$name)
}
};
my KnapsackItem $panacea .= new: 0.025, 0.3, 3000, "panacea";
my KnapsackItem $ichor .= new: 0.015, 0.2, 1800, "ichor";
my KnapsackItem $gold .= new: 0.002, 2.0, 2500, "gold";
my KnapsackItem $maximum .= new: 0.25, 25, 0 , "max";
my $max_val = 0;
my @solutions;
my %max_items;
for $panacea, $ichor, $gold -> $item {
%max_items{$item.name} = floor min
$maximum.volume / $item.volume,
$maximum.weight / $item.weight;
}
for 0..%max_items<panacea>
X 0..%max_items<ichor>
X 0..%max_items<gold>
-> ($p, $i, $g)
{
next if $panacea.volume * $p + $ichor.volume * $i + $gold.volume * $g > $maximum.volume;
next if $panacea.weight * $p + $ichor.weight * $i + $gold.weight * $g > $maximum.weight;
given $panacea.value * $p + $ichor.value * $i + $gold.value * $g {
if $_ > $max_val { $max_val = $_; @solutions = (); }
when $max_val { @solutions.push: $[$p,$i,$g] }
}
}
say "maximum value is $max_val\npossible solutions:";
say "panacea\tichor\tgold";
.join("\t").say for @solutions;</syntaxhighlight>
'''Output:'''
<pre>maximum value is 54500
possible solutions:
panacea ichor gold
0 15 11
3 10 11
6 5 11
9 0 11</pre>
=={{header|REXX}}==
{{trans|Fortran}}
===displays 1st solution===
<
maxPanacea= 0 /* ═══════ ══════ ══════ */
now. = 0; sack.$ = 0 ; sack.w = 25 ; sack.v = 0.25
maxPanacea= min(sack.w / panacea.w, sack.v / panacea.v)
Line 3,124 ⟶ 3,729:
now.w= g * gold.w + i * ichor.w + p * panacea.w
now.v= g * gold.v + i * ichor.v + p * panacea.v
if now.w > sack.w | now.v > sack.v then iterate
if now.$ > max$ then do; maxP= p; maxI= i; maxG= g
max$= now.$; maxW= now.w; maxV= now.v
end
end /*g (gold) */
Line 3,132 ⟶ 3,737:
end /*p (panacea)*/
Ctot = maxP + maxI + maxG; L = length(Ctot) + 1
say ' panacea in sack:' right(maxP, L)
say ' ichors in sack:' right(maxI, L)
say ' gold items in sack:' right(maxG, L)
say '════════════════════' copies("═", L)
say 'carrying a total of:' right(cTot, L)
say left('', 40) "total value: " max$ / 1
say left('', 40) "total weight: " maxW / 1
say left('', 40) "total volume: " maxV / 1
/*stick a fork in it, we're all done. */</
{{out|output|text= when using the internal default input:}}
<pre>
panacea in sack: 0
ichors in sack: 15
gold items in sack: 11
Line 3,149 ⟶ 3,756:
total value: 54500
total weight: 25
total volume: 0.247
</pre>
===displays all solutions===
<
maxPanacea= 0
maxIchor = 0; /* value weight volume */
maxGold = 0; /* ═══════ ══════ ══════ */
max$ = 0; panacea.$ = 3000 ; panacea.w = 0.3 ; panacea.v = 0.025
now. = 0; ichor.$ = 1800 ; ichor.w = 0.2 ; ichor.v = 0.015
# = 0; gold.$ = 2500 ; gold.w = 2 ; gold.v = 0.002
L = 0; sack.$ = 0 ; sack.w = 25 ; sack.v = 0.25
maxPanacea= min(sack.w / panacea.w, sack.v / panacea.v)
maxIchor = min(sack.w / ichor.w, sack.v / ichor.v)
Line 3,170 ⟶ 3,780:
now.w = g * gold.w + i * ichor.w + p * panacea.w
now.v = g * gold.v + i * ichor.v + p * panacea.v
if now.w > sack.w | now.v > sack.v then iterate i
if now.$ > max$ then do; #= 0; max$= now.$; end
if now.$ = max$ then do; #= # + 1;
max$.#= now.$; maxW.#= now.w; maxV.#= now.v
L= max(L, length(p + i + g) )
end
end /*g (gold) */
end /*i (ichor) */
end /*p (panacea)*/
L= L + 1
do j=1 for #; say; say copies('▒', 70) "solution" j
say ' panacea in sack:' right(maxP.j, L)
say ' ichors in sack:' right(maxI.j, L)
say ' gold items in sack:' right(maxG.j, L)
say '════════════════════' copies("═", L)
say 'carrying a total of:' right(maxP.j + maxI.j + maxG.j, L)
say left('', 40) "total value: " max$.j / 1
say left('', 40) "total weight: " maxW.j / 1
say left('', 40) "total volume: " maxV.j / 1
end /*j*/
/*stick a fork in it, we're all done. */</
{{out|output|text= when using the internal default input:}}
<pre>
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ solution 1
panacea in sack: 0
ichors in sack: 15
Line 3,229 ⟶ 3,841:
total value: 54500
total weight: 24.7
total volume: 0.247
</pre>
=={{header|Ruby}}==
Brute force method, {{trans|Tcl}}
<
panacea = KnapsackItem.new(0.025, 0.3, 3000)
ichor = KnapsackItem.new(0.015, 0.2, 1800)
Line 3,268 ⟶ 3,882:
i*ichor.weight + p*panacea.weight + g*gold.weight,
i*ichor.volume + p*panacea.volume + g*gold.volume
end</
{{out}}
<pre>
The maximal solution has value 54500
ichor= 0, panacea= 9, gold=11 -- weight:24.7, volume=0.247
ichor= 5, panacea= 6, gold=11 -- weight:24.8, volume=0.247
ichor=10, panacea= 3, gold=11 -- weight:24.9, volume=0.247
ichor=15, panacea= 0, gold=11 -- weight:25.0, volume=0.247</pre>
=={{header|SAS}}==
This is yet another brute force solution.
<
wtpanacea=0.3; wtichor=0.2; wtgold=2.0;
volpanacea=0.025; volichor=0.015; volgold=0.002;
Line 3,306 ⟶ 3,922:
proc print data=one (obs=4);
var panacea ichor gold vals;
run;</
Output:
<pre>
Obs panacea ichor gold vals
1 0 15 11 54500
2 3 10 11 54500
3 6 5 11 54500
4 9 0 11 54500
</pre>
Use SAS/OR:
<
data mydata;
input Item $1-19 Value weight Volume;
Line 3,353 ⟶ 3,973:
print TotalValue;
for {s in 1.._NSOL_} print {i in ITEMS} NumSelected[i].sol[s];
quit;</
MILP solver output:
<pre>TotalValue
54500
Line 3,360 ⟶ 3,982:
gold (bars) 11
ichor (ampules of) 0
panacea (vials of) 9
</pre>
CLP solver output:
<pre>
TotalValue
54500
Line 3,383 ⟶ 4,009:
ichor (ampules of) 0
panacea (vials of) 9 </pre>
=={{header|Scala}}==
===Functional approach (Tail recursive)===
<
object UnboundedKnapsack extends App {
private val (maxWeight, maxVolume) = (BigDecimal(25.0), BigDecimal(0.25))
private val items = Seq(Item("panacea", 3000, 0.3, 0.025), Item("ichor", 1800, 0.2, 0.015), Item("gold", 2500, 2.0, 0.002))
@tailrec
private def packer(notPacked: Seq[Knapsack], packed: Seq[Knapsack]): Seq[Knapsack] = {
def fill(knapsack: Knapsack): Seq[Knapsack] = items.map(i => Knapsack(i +: knapsack.bagged))
def stuffer(Seq: Seq[Knapsack]): Seq[Knapsack] = // Cause brute force
Seq.map(k => Knapsack(k.bagged.sortBy(_.name))).distinct
if (notPacked.isEmpty) packed.sortBy(-_.totValue).take(4)
else packer(stuffer(notPacked.flatMap(fill)).filter(_.isNotFull), notPacked ++ packed)
}
private case class Item(name: String, value: Int, weight: BigDecimal, volume: BigDecimal)
private case class Knapsack(bagged: Seq[Item]) {
def isNotFull: Boolean = totWeight <= maxWeight && totVolume <= maxVolume
override def toString = s"[${show(bagged)} | value: $totValue, weight: $totWeight, volume: $totVolume]"
def totValue: Int = bagged.map(_.value).sum
private def totVolume = bagged.map(_.volume).sum
private def totWeight = bagged.map(_.weight).sum
private def show(is: Seq[Item]) =
(items.map(_.name) zip items.map(i => is.count(_ == i)))
Line 3,420 ⟶ 4,047:
.mkString(", ")
}
packer(items.map(i => Knapsack(Seq(i))), Nil).foreach(println)
}</
{{out}}
<pre>
[panacea: 0, ichor: 15, gold: 11 | value: 54500, weight: 25.0, volume: 0.247]
[panacea: 3, ichor: 10, gold: 11 | value: 54500, weight: 24.9, volume: 0.247]
[panacea: 6, ichor: 5, gold: 11 | value: 54500, weight: 24.8, volume: 0.247]
[panacea: 9, ichor: 0, gold: 11 | value: 54500, weight: 24.7, volume: 0.247]
</pre>
{{Out}}See it in running in your browser by [https://scalafiddle.io/sf/1fRBQs5/2 ScalaFiddle (JavaScript)] or by [https://scastie.scala-lang.org/S4oGElcwQkCMesfuSRKfkw Scastie (JVM)].
=={{header|Seed7}}==
<
include "float.s7i";
Line 3,480 ⟶ 4,111:
writeln("This is achieved by carrying " <& bestAmounts[1] <& " panacea, " <& bestAmounts[2] <& " ichor and " <& bestAmounts[3] <& " gold items");
writeln("The weight of this carry is " <& best.weight <& " and the volume used is " <& best.volume digits 4);
end func;</
Output:
<pre>
Maximum value achievable is 54500
This is achieved by carrying 0 panacea, 15 ichor and 11 gold items
The weight of this carry is 25.0 and the volume used is 0.2470
</pre>
=={{header|Sidef}}==
{{trans|Perl}}
<
Number volume,
Number weight,
Line 3,550 ⟶ 4,186:
#{"-" * 50}
Total:\t #{"%8d%8g%8d" % (wtot/wsc, vtot/vsc, x[0])}
EOT</
{{out}}
<pre>
Max value 54500, with:
Item Qty Weight Vol Value
--------------------------------------------------
Line 3,558 ⟶ 4,195:
gold: 11 22 0.022 27500
--------------------------------------------------
Total: 24 0.247 54500
</pre>
=={{header|Tcl}}==
The following code uses brute force, but that's tolerable as long as it takes just a split second to find all 4 solutions. The use of arrays makes the
<
proc main argv {
array set value {panacea 3000 ichor 1800 gold 2500}
Line 3,591 ⟶ 4,230:
puts "maxval: $maxval, best: $best"
}
main $argv</
<pre>$ time tclsh85 /Tcl/knapsack.tcl
maxval: 54500, best: {i 0 p 9 g 11} {i 5 p 6 g 11} {i 10 p 3 g 11} {i 15 p 0 g 11}
Line 3,598 ⟶ 4,238:
user 0m0.015s
sys 0m0.015s</pre>
=={{header|Ursala}}==
The algorithm is to enumerate all packings with up to the maximum of each item,
filter them by the volume and weight restrictions, partition the remaining packings
by value, and search for the maximum value class.
<
#import flo
Line 3,615 ⟶ 4,256:
#cast %nmL
human_readable = ~&p/*<'panacea','ichor','gold'> solutions</
output:
<pre><
<'panacea': 0,'ichor': 15,'gold': 11>,
<'panacea': 3,'ichor': 10,'gold': 11>,
<'panacea': 6,'ichor': 5,'gold': 11>,
<'panacea': 9,'ichor': 0,'gold': 11>></pre>
=={{header|Visual Basic}}==
See: [[Knapsack Problem/Visual Basic]]
Line 3,627 ⟶ 4,270:
whilst the one below is focussing more on expressing/solving the problem
in less lines of code.
<
Sub Main()
Line 3,651 ⟶ 4,294:
If M(Value) = S(1)(Value) Then Debug.Print M(Value), M(Weight), M(Volume), M(PC), M(IC), M(GC)
Next
End Sub</
Output:<pre> Value Weight Volume PanaceaCount IchorCount GoldCount
54500 24.7 0.247 9 0 11
54500 24.8 0.247 6 5 11
54500 24.9 0.247 3 10 11
54500 25 0.247 0 15 11
</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
class Item {
construct new(name, value, weight, volume) {
_name = name
_value = value
_weight = weight
_volume = volume
}
name { _name }
value { _value }
weight { _weight }
volume { _volume }
}
var items = [
Item.new("panacea", 3000, 0.3, 0.025),
Item.new("ichor", 1800, 0.2, 0.015),
Item.new("gold", 2500, 2, 0.002)
]
var n = items.count
var count = List.filled(n, 0)
var best = List.filled(n, 0)
var bestValue = 0
var maxWeight = 25
var maxVolume = 0.25
var knapsack // recursive
knapsack = Fn.new { |i, value, weight, volume|
if (i == n) {
if (value > bestValue) {
bestValue = value
for (j in 0...n) best[j] = count[j]
}
return
}
var m1 = (weight / items[i].weight).floor
var m2 = (volume / items[i].volume).floor
count[i] = m1.min(m2)
while (count[i] >= 0) {
knapsack.call(
i + 1,
value + count[i] * items[i].value,
weight - count[i] * items[i].weight,
volume - count[i] * items[i].volume
)
count[i] = count[i] - 1
}
}
knapsack.call(0, 0, maxWeight, maxVolume)
System.print("Item Chosen Number Value Weight Volume")
System.print("----------- ------ ----- ------ ------")
var itemCount = 0
var sumNumber = 0
var sumWeight = 0
var sumVolume = 0
for (i in 0... n) {
if (best[i] != 0) {
itemCount = itemCount + 1
var name = items[i].name
var number = best[i]
var value = items[i].value * number
var weight = items[i].weight * number
var volume = items[i].volume * number
sumNumber = sumNumber + number
sumWeight = sumWeight + weight
sumVolume = sumVolume + volume
Fmt.write("$-11s $2d $5.0f $4.1f", name, number, value, weight)
Fmt.print(" $4.2f", volume)
}
}
System.print("----------- ------ ----- ------ ------")
Fmt.write("$d items $2d $5.0f $4.1f", itemCount, sumNumber, bestValue, sumWeight)
Fmt.print(" $4.2f", sumVolume)</syntaxhighlight>
{{out}}
<pre>
Item Chosen Number Value Weight Volume
----------- ------ ----- ------ ------
panacea 9 27000 2.7 0.23
gold 11 27500 22.0 0.02
----------- ------ ----- ------ ------
2 items 20 54500 24.7 0.25
</pre>
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">func Min(A, B);
real A, B;
return fix(if A < B then A else B);
int Panacea, Ichor, Gold, Panacea_, Ichor_, Gold_, Val, Max;
real Weight, Volume;
[Max:= 0;
for Panacea:= 0 to Min(25.0/0.3, 0.25/0.025) do
[for Ichor:= 0 to Min(25.0/0.2, 0.25/0.015) do
[for Gold:= 0 to Min(25.0/2.0, 0.25/0.002) do
[Val:= Panacea*3000 + Ichor*1800 + Gold*2500;
Weight:= float(Panacea)*0.3 + float(Ichor)*0.2 + float(Gold)*2.0;
Volume:= float(Panacea)*0.025 + float(Ichor)*0.015 + float(Gold)*0.002;
if Val>Max and Weight<=25.0 and Volume<= 0.25 then
[Max:= Val;
Panacea_:= Panacea; Ichor_:= Ichor; Gold_:= Gold;
];
];
];
];
Text(0, "The traveler carries ");
IntOut(0, Panacea_); Text(0, " vials of panacea, ");
IntOut(0, Ichor_); Text(0, " ampules of ichor, and ");
IntOut(0, Gold_); Text(0, " bars of gold"); CrLf(0);
Text(0, "for a maximum value of "); IntOut(0, Max); CrLf(0);
]</syntaxhighlight>
{{out}}
<pre>
The traveler carries 0 vials of panacea, 15 ampules of ichor, and 11 bars of gold
for a maximum value of 54500
</pre>
=={{header|zkl}}==
{{trans|D}}
<
ichor :=T(1800, 0.2, 0.015);
gold :=T(2500, 2.0, 0.002);
Line 3,679 ⟶ 4,448:
" %d panacea, %d ichor and %d gold").fmt(best[1].xplode()));
println("The weight to carry is %4.1f and the volume used is %5.3f"
.fmt(best[0][1,*].xplode()));</
cprod3 is the Cartesian product of three lists or iterators.
{{out}}
<pre>
Maximum value achievable is 54,500
This is achieved by carrying (one solution): 9 panacea, 0 ichor and 11 gold
The weight to carry is 24.7 and the volume used is 0.247
</pre>
[[Category:Puzzles]]
|