Knapsack problem/Unbounded: Difference between revisions
Content added Content deleted
m (→{{header|Picat}}: Added {{out}} and fixed a grammar thingy.) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 81: | Line 81: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">T Bounty |
||
Int value |
Int value |
||
Float weight, volume |
Float weight, volume |
||
Line 113: | Line 113: | ||
print(‘Maximum value achievable is ’best.value) |
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(‘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))</ |
print(‘The weight to carry is #2.1 and the volume used is #.3’.format(best.weight, best.volume))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 125: | Line 125: | ||
{{trans|Visual Basic}} |
{{trans|Visual Basic}} |
||
The program uses two ASSIST macros (XDECO,XPRNT) to keep the code as short as possible. |
The program uses two ASSIST macros (XDECO,XPRNT) to keep the code as short as possible. |
||
< |
<syntaxhighlight lang="360asm">* Knapsack problem/Unbounded 04/02/2017 |
||
KNAPSACK CSECT |
KNAPSACK CSECT |
||
USING KNAPSACK,R13 base register |
USING KNAPSACK,R13 base register |
||
Line 321: | Line 321: | ||
PG DS CL72 |
PG DS CL72 |
||
YREGS |
YREGS |
||
END KNAPSACK</ |
END KNAPSACK</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 333: | Line 333: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; |
||
procedure Knapsack_Unbounded is |
procedure Knapsack_Unbounded is |
||
Line 397: | Line 397: | ||
Ada.Text_IO.Put_Line ("Ichor: " & Natural'Image (Best_Amounts (2))); |
Ada.Text_IO.Put_Line ("Ichor: " & Natural'Image (Best_Amounts (2))); |
||
Ada.Text_IO.Put_Line ("Gold: " & Natural'Image (Best_Amounts (3))); |
Ada.Text_IO.Put_Line ("Gold: " & Natural'Image (Best_Amounts (3))); |
||
end Knapsack_Unbounded;</ |
end Knapsack_Unbounded;</syntaxhighlight> |
||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
{{trans|Python}}< |
{{trans|Python}}<syntaxhighlight lang="algol68">MODE BOUNTY = STRUCT(STRING name, INT value, weight, volume); |
||
[]BOUNTY items = ( |
[]BOUNTY items = ( |
||
Line 509: | Line 509: | ||
name OF items, max items)); |
name OF items, max items)); |
||
printf(($" The weight to carry is "f(d)", and the volume used is "f(d)l$, |
printf(($" The weight to carry is "f(d)", and the volume used is "f(d)l$, |
||
weight OF max, volume OF max))</ |
weight OF max, volume OF max))</syntaxhighlight>Output: |
||
<pre>The maximum value achievable (by dynamic programming) is +54500 |
<pre>The maximum value achievable (by dynamic programming) is +54500 |
||
The number of (panacea, ichor, gold) items to achieve this is: ( 9, 0, 11) respectively |
The number of (panacea, ichor, gold) items to achieve this is: ( 9, 0, 11) respectively |
||
Line 516: | Line 516: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
Brute Force. |
Brute Force. |
||
< |
<syntaxhighlight lang="autohotkey">Item = Panacea,Ichor,Gold |
||
Value = 3000,1800,2500 |
Value = 3000,1800,2500 |
||
Weight= 3,2,20 ; *10 |
Weight= 3,2,20 ; *10 |
||
Line 540: | Line 540: | ||
} |
} |
||
} |
} |
||
MsgBox Value = %$%`n`nPanacea`tIchor`tGold`tWeight`tVolume`n%t%</ |
MsgBox Value = %$%`n`nPanacea`tIchor`tGold`tWeight`tVolume`n%t%</syntaxhighlight> |
||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
< |
<syntaxhighlight lang="bracmat">(knapsack= |
||
( things |
( things |
||
= (panacea.3000.3/10.25/1000) |
= (panacea.3000.3/10.25/1000) |
||
Line 613: | Line 613: | ||
!knapsack; |
!knapsack; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre>Take 15 items of ichor. |
<pre>Take 15 items of ichor. |
||
Line 623: | Line 623: | ||
figures out the best (highest value) set by brute forcing every possible subset. |
figures out the best (highest value) set by brute forcing every possible subset. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 681: | Line 681: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{output}}<pre>9 panacea |
{{output}}<pre>9 panacea |
||
Line 690: | Line 690: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">/* Items Value Weight Volume |
||
a 30 3 25 |
a 30 3 25 |
||
b 18 2 15 |
b 18 2 15 |
||
Line 735: | Line 735: | ||
return new uint[] { a0, b0, c0 }; |
return new uint[] { a0, b0, c0 }; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C_sharp|C#}}== |
=={{header|C_sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">/*Knapsack |
||
This model finds the integer optimal packing of a knapsack |
This model finds the integer optimal packing of a knapsack |
||
Line 792: | Line 792: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Produces: |
Produces: |
||
<pre> |
<pre> |
||
Line 833: | Line 833: | ||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
< |
<syntaxhighlight lang="lisp">(defstruct item :value :weight :volume) |
||
(defn total [key items quantities] |
(defn total [key items quantities] |
||
Line 841: | Line 841: | ||
(let [mcw (/ max-weight (:weight item)) |
(let [mcw (/ max-weight (:weight item)) |
||
mcv (/ max-volume (:volume item))] |
mcv (/ max-volume (:volume item))] |
||
(min mcw mcv)))</ |
(min mcw mcv)))</syntaxhighlight> |
||
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: |
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: |
||
< |
<syntaxhighlight lang="lisp">(defn knapsacks [] |
||
(let [pan (struct item 3000 0.3 0.025) |
(let [pan (struct item 3000 0.3 0.025) |
||
ich (struct item 1800 0.2 0.015) |
ich (struct item 1800 0.2 0.015) |
||
Line 861: | Line 861: | ||
i (iters ich) |
i (iters ich) |
||
g (iters gol)] |
g (iters gol)] |
||
[p i g])))))</ |
[p i g])))))</syntaxhighlight> |
||
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. |
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. |
||
< |
<syntaxhighlight lang="lisp">(defn best-by-value [ks] |
||
(reduce #(if (> (:value %1) (:value %2)) %1 %2) ks)) |
(reduce #(if (> (:value %1) (:value %2)) %1 %2) ks)) |
||
Line 872: | Line 872: | ||
(println "Total weight: " (float w)) |
(println "Total weight: " (float w)) |
||
(println "Total volume: " (float v)) |
(println "Total volume: " (float v)) |
||
(println "Containing: " p "Panacea," i "Ichor," g "Gold")))</ |
(println "Containing: " p "Panacea," i "Ichor," g "Gold")))</syntaxhighlight> |
||
Calling <tt>(print-knapsack (best-by-value (knapsacks)))</tt> would result in something like: |
Calling <tt>(print-knapsack (best-by-value (knapsacks)))</tt> would result in something like: |
||
<pre>Maximum value: 54500 |
<pre>Maximum value: 54500 |
||
Line 879: | Line 879: | ||
Containing: 9 Panacea, 0 Ichor, 11 Gold</pre> |
Containing: 9 Panacea, 0 Ichor, 11 Gold</pre> |
||
Further, we could find all "best" knapsacks rather simply (albeit at the cost of some efficiency): |
Further, we could find all "best" knapsacks rather simply (albeit at the cost of some efficiency): |
||
< |
<syntaxhighlight lang="lisp">(defn all-best-by-value [ks] |
||
(let [b (best-by-value ks)] |
(let [b (best-by-value ks)] |
||
(filter #(= (:value b) (:value %)) ks))) |
(filter #(= (:value b) (:value %)) ks))) |
||
Line 886: | Line 886: | ||
(doseq [k ks] |
(doseq [k ks] |
||
(print-knapsack k) |
(print-knapsack k) |
||
(println)))</ |
(println)))</syntaxhighlight> |
||
Calling <tt>(print-knapsacks (all-best-by-value (knapsacks)))</tt> would result in something like: |
Calling <tt>(print-knapsacks (all-best-by-value (knapsacks)))</tt> would result in something like: |
||
<pre> |
<pre> |
||
Line 912: | Line 912: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
A dynamic programming <i>O(maxVolume × maxWeight × nItems)</i> solution, where volumes and weights are integral values. |
A dynamic programming <i>O(maxVolume × maxWeight × nItems)</i> solution, where volumes and weights are integral values. |
||
< |
<syntaxhighlight lang="lisp">(defun fill-knapsack (items max-volume max-weight) |
||
"Items is a list of lists of the form (name value weight volume) where weight |
"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 |
and value are integers. max-volume and max-weight, also integers, are the |
||
Line 955: | Line 955: | ||
b-items (list* item o-items))))))) |
b-items (list* item o-items))))))) |
||
(setf (aref maxes v w) |
(setf (aref maxes v w) |
||
(list b-value b-items b-volume b-weight))))))))</ |
(list b-value b-items b-volume b-weight))))))))</syntaxhighlight> |
||
Use, having multiplied volumes and weights as to be integral: |
Use, having multiplied volumes and weights as to be integral: |
||
Line 977: | Line 977: | ||
=={{header|D}}== |
=={{header|D}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="d">void main() @safe /*@nogc*/ { |
||
import std.stdio, std.algorithm, std.typecons, std.conv; |
import std.stdio, std.algorithm, std.typecons, std.conv; |
||
Line 1,027: | Line 1,027: | ||
writefln("The weight to carry is %4.1f and the volume used is %5.3f", |
writefln("The weight to carry is %4.1f and the volume used is %5.3f", |
||
best.weight, best.volume); |
best.weight, best.volume); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Maximum value achievable is 54500 |
<pre>Maximum value achievable is 54500 |
||
Line 1,035: | Line 1,035: | ||
===Alternative Version=== |
===Alternative Version=== |
||
The output is the same. |
The output is the same. |
||
< |
<syntaxhighlight lang="d">void main() { |
||
import std.stdio, std.algorithm, std.typecons, std.range, std.conv; |
import std.stdio, std.algorithm, std.typecons, std.range, std.conv; |
||
Line 1,060: | Line 1,060: | ||
writefln("This is achieved by carrying (one solution) %d panacea, %d ichor and %d gold", best[1][]); |
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..$]); |
writefln("The weight to carry is %4.1f and the volume used is %5.3f", best[0][1..$]); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|E}}== |
=={{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. |
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. |
||
< |
<syntaxhighlight lang="e">pragma.enable("accumulator") |
||
/** A data type representing a bunch of stuff (or empty space). */ |
/** A data type representing a bunch of stuff (or empty space). */ |
||
Line 1,143: | Line 1,143: | ||
:= makeQuantity( 0, 25, 0.250, [].asMap()) |
:= makeQuantity( 0, 25, 0.250, [].asMap()) |
||
printBest(emptyKnapsack, [panacea, ichor, gold])</ |
printBest(emptyKnapsack, [panacea, ichor, gold])</syntaxhighlight> |
||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
Use a cache, and multiply by 10^n to get an integer problem. |
Use a cache, and multiply by 10^n to get an integer problem. |
||
< |
<syntaxhighlight lang="scheme"> |
||
(require 'struct) |
(require 'struct) |
||
(require 'hash) |
(require 'hash) |
||
Line 1,219: | Line 1,219: | ||
→ 218 |
→ 218 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Eiffel}}== |
=={{header|Eiffel}}== |
||
<syntaxhighlight lang="eiffel"> |
|||
<lang Eiffel> |
|||
class |
class |
||
KNAPSACK |
KNAPSACK |
||
Line 1,305: | Line 1,305: | ||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,315: | Line 1,315: | ||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
Brute Force: |
Brute Force: |
||
< |
<syntaxhighlight lang="elixir">defmodule Item do |
||
defstruct volume: 0.0, weight: 0.0, value: 0 |
defstruct volume: 0.0, weight: 0.0, value: 0 |
||
def new(volume, weight, value) do |
def new(volume, weight, value) do |
||
Line 1,365: | Line 1,365: | ||
gold: Item.new(0.002, 2.0, 2500) } |
gold: Item.new(0.002, 2.0, 2500) } |
||
maximum = Item.new(0.25, 25, 0) |
maximum = Item.new(0.25, 25, 0) |
||
Knapsack.solve_unbounded(items, maximum)</ |
Knapsack.solve_unbounded(items, maximum)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,378: | Line 1,378: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
This is a brute force solution. It is general enough to be able to provide solutions for any number of different items. |
This is a brute force solution. It is general enough to be able to provide solutions for any number of different items. |
||
< |
<syntaxhighlight lang="factor">USING: accessors combinators kernel locals math math.order |
||
math.vectors sequences sequences.product combinators.short-circuit ; |
math.vectors sequences sequences.product combinators.short-circuit ; |
||
IN: knapsack |
IN: knapsack |
||
Line 1,418: | Line 1,418: | ||
: best-bounty ( -- bounty ) |
: best-bounty ( -- bounty ) |
||
find-max-amounts [ 1 + iota ] map <product-sequence> |
find-max-amounts [ 1 + iota ] map <product-sequence> |
||
[ <bounty> ] [ max ] map-reduce ;</ |
[ <bounty> ] [ max ] map-reduce ;</syntaxhighlight> |
||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
< |
<syntaxhighlight lang="forth">\ : value ; immediate |
||
: weight cell+ ; |
: weight cell+ ; |
||
: volume 2 cells + ; |
: volume 2 cells + ; |
||
Line 1,480: | Line 1,480: | ||
solve-ichor ; |
solve-ichor ; |
||
solve-panacea .solution</ |
solve-panacea .solution</syntaxhighlight> |
||
Or like this... |
Or like this... |
||
< |
<syntaxhighlight lang="forth">0 VALUE vials |
||
0 VALUE ampules |
0 VALUE ampules |
||
0 VALUE bars |
0 VALUE bars |
||
Line 1,515: | Line 1,515: | ||
LOOP |
LOOP |
||
LOOP |
LOOP |
||
.SOLUTION ;</ |
.SOLUTION ;</syntaxhighlight> |
||
With the result... |
With the result... |
||
Line 1,525: | Line 1,525: | ||
{{works with|Fortran|90 and later}} |
{{works with|Fortran|90 and later}} |
||
A straight forward 'brute force' approach |
A straight forward 'brute force' approach |
||
< |
<syntaxhighlight lang="fortran">PROGRAM KNAPSACK |
||
IMPLICIT NONE |
IMPLICIT NONE |
||
Line 1,572: | Line 1,572: | ||
WRITE(*, "(A,F4.1,A,F5.3)") "The weight to carry is ", totalWeight, " and the volume used is ", totalVolume |
WRITE(*, "(A,F4.1,A,F5.3)") "The weight to carry is ", totalWeight, " and the volume used is ", totalVolume |
||
END PROGRAM KNAPSACK</ |
END PROGRAM KNAPSACK</syntaxhighlight> |
||
Sample output |
Sample output |
||
Maximum value achievable is 54500 |
Maximum value achievable is 54500 |
||
Line 1,580: | Line 1,580: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Recursive brute-force. |
Recursive brute-force. |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 1,645: | Line 1,645: | ||
fmt.Printf("TOTAL (%3d items) Weight: %4.1f Volume: %5.3f Value: %6d\n", |
fmt.Printf("TOTAL (%3d items) Weight: %4.1f Volume: %5.3f Value: %6d\n", |
||
sumCount, sumWeight, sumVolume, sumValue) |
sumCount, sumWeight, sumVolume, sumValue) |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
Line 1,657: | Line 1,657: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
Solution: dynamic programming |
Solution: dynamic programming |
||
< |
<syntaxhighlight lang="groovy">def totalWeight = { list -> list.collect{ it.item.weight * it.count }.sum() } |
||
def totalVolume = { list -> list.collect{ it.item.volume * it.count }.sum() } |
def totalVolume = { list -> list.collect{ it.item.volume * it.count }.sum() } |
||
def totalValue = { list -> list.collect{ it.item.value * it.count }.sum() } |
def totalValue = { list -> list.collect{ it.item.value * it.count }.sum() } |
||
Line 1,680: | Line 1,680: | ||
} |
} |
||
m[n][wm][vm] |
m[n][wm][vm] |
||
}</ |
}</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="groovy">Set solutions = [] |
||
items.eachPermutation { itemList -> |
items.eachPermutation { itemList -> |
||
def start = System.currentTimeMillis() |
def start = System.currentTimeMillis() |
||
Line 1,703: | Line 1,703: | ||
it.item.name, it.count, it.item.weight * it.count, it.item.volume * it.count) |
it.item.name, it.count, it.item.weight * it.count, it.item.volume * it.count) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
Line 1,753: | Line 1,753: | ||
=={{header|Haskell}}== |
=={{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. |
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. |
||
< |
<syntaxhighlight lang="haskell">import Data.List (maximumBy) |
||
import Data.Ord (comparing) |
import Data.Ord (comparing) |
||
Line 1,790: | Line 1,790: | ||
main = putStr $ showOpt $ best options |
main = putStr $ showOpt $ best options |
||
where best = maximumBy $ comparing $ dotProduct vals</ |
where best = maximumBy $ comparing $ dotProduct vals</syntaxhighlight> |
||
Output: |
Output: |
||
Line 1,802: | Line 1,802: | ||
=={{header|HicEst}}== |
=={{header|HicEst}}== |
||
< |
<syntaxhighlight lang="hicest">CHARACTER list*1000 |
||
NN = ALIAS($Panacea, $Ichor, $Gold, wSack, wPanacea, wIchor, wGold, vSack, vPanacea, vIchor, vGold) |
NN = ALIAS($Panacea, $Ichor, $Gold, wSack, wPanacea, wIchor, wGold, vSack, vPanacea, vIchor, vGold) |
||
Line 1,829: | Line 1,829: | ||
ENDDO |
ENDDO |
||
ENDDO |
ENDDO |
||
ENDDO</ |
ENDDO</syntaxhighlight> |
||
< |
<syntaxhighlight lang="hicest">value=54500; Panaceas=0; Ichors=15; Golds=11; weight=25; volume=0.247; |
||
value=54500; Panaceas=3; Ichors=10; Golds=11; weight=24.9; volume=0.247; |
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=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; </ |
value=54500; Panaceas=9; Ichors=0; Golds=11; weight=24.7; volume=0.247; </syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
Brute force solution. |
Brute force solution. |
||
< |
<syntaxhighlight lang="j">mwv=: 25 0.25 |
||
prods=: <;. _1 ' panacea: ichor: gold:' |
prods=: <;. _1 ' panacea: ichor: gold:' |
||
hdrs=: <;. _1 ' weight: volume: value:' |
hdrs=: <;. _1 ' weight: volume: value:' |
||
Line 1,854: | Line 1,854: | ||
prtscr &.> hdrs ('total '&,@[,' ',":@])&.> mo ip"1 ws,vs,:vls |
prtscr &.> hdrs ('total '&,@[,' ',":@])&.> mo ip"1 ws,vs,:vls |
||
LF |
LF |
||
)</ |
)</syntaxhighlight> |
||
Example output: |
Example output: |
||
<pre> KS'' |
<pre> KS'' |
||
Line 1,866: | Line 1,866: | ||
=={{header|Java}}== |
=={{header|Java}}== |
||
With recursion for more than 3 items. |
With recursion for more than 3 items. |
||
< |
<syntaxhighlight lang="java">package hu.pj.alg; |
||
import hu.pj.obj.Item; |
import hu.pj.obj.Item; |
||
Line 1,949: | Line 1,949: | ||
} // main() |
} // main() |
||
} // class</ |
} // class</syntaxhighlight> |
||
< |
<syntaxhighlight lang="java">package hu.pj.obj; |
||
public class Item { |
public class Item { |
||
Line 2,001: | Line 2,001: | ||
} |
} |
||
} // class</ |
} // class</syntaxhighlight> |
||
output: |
output: |
||
Line 2,010: | Line 2,010: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
Brute force. |
Brute force. |
||
< |
<syntaxhighlight lang="javascript">var gold = { 'value': 2500, 'weight': 2.0, 'volume': 0.002 }, |
||
panacea = { 'value': 3000, 'weight': 0.3, 'volume': 0.025 }, |
panacea = { 'value': 3000, 'weight': 0.3, 'volume': 0.025 }, |
||
ichor = { 'value': 1800, 'weight': 0.2, 'volume': 0.015 }, |
ichor = { 'value': 1800, 'weight': 0.2, 'volume': 0.015 }, |
||
Line 2,060: | Line 2,060: | ||
(gold: 11, panacea: 3, ichor: 10) |
(gold: 11, panacea: 3, ichor: 10) |
||
(gold: 11, panacea: 6, ichor: 5) |
(gold: 11, panacea: 6, ichor: 5) |
||
(gold: 11, panacea: 9, ichor: 0)</pre></ |
(gold: 11, panacea: 9, ichor: 0)</pre></syntaxhighlight> |
||
=={{header|jq}}== |
=={{header|jq}}== |
||
Line 2,067: | Line 2,067: | ||
'''Works with gojq, the Go implementation of jq''' |
'''Works with gojq, the Go implementation of jq''' |
||
< |
<syntaxhighlight lang="jq">def Item($name; $value; $weight; $volume): |
||
{$name, $value, $weight, $volume}; |
{$name, $value, $weight, $volume}; |
||
Line 2,145: | Line 2,145: | ||
f(.itemCount; .sumNumber; .bestValue; .sumWeight; .sumVolume) ); |
f(.itemCount; .sumNumber; .bestValue; .sumWeight; .sumVolume) ); |
||
solve(25; 0.25)</ |
solve(25; 0.25)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,158: | Line 2,158: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
{{libheader|JuMP}}< |
{{libheader|JuMP}}<syntaxhighlight lang="julia"> |
||
using JuMP |
using JuMP |
||
using GLPKMathProgInterface |
using GLPKMathProgInterface |
||
Line 2,181: | Line 2,181: | ||
println("vials of panacea = ", getvalue(vials_of_panacea)) |
println("vials of panacea = ", getvalue(vials_of_panacea)) |
||
println("ampules of ichor = ", getvalue(ampules_of_ichor)) |
println("ampules of ichor = ", getvalue(ampules_of_ichor)) |
||
println("bars of gold = ", getvalue(bars_of_gold))</ |
println("bars of gold = ", getvalue(bars_of_gold))</syntaxhighlight> |
||
{{output}} |
{{output}} |
||
<pre> |
<pre> |
||
Line 2,202: | Line 2,202: | ||
{{trans|C}} |
{{trans|C}} |
||
Recursive brute force approach: |
Recursive brute force approach: |
||
< |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
data class Item(val name: String, val value: Double, val weight: Double, val volume: Double) |
data class Item(val name: String, val value: Double, val weight: Double, val volume: Double) |
||
Line 2,268: | Line 2,268: | ||
print("${itemCount} items ${"%2d".format(sumNumber)} ${"%5.0f".format(bestValue)} ${"%4.1f".format(sumWeight)}") |
print("${itemCount} items ${"%2d".format(sumNumber)} ${"%5.0f".format(bestValue)} ${"%4.1f".format(sumWeight)}") |
||
println(" ${"%4.2f".format(sumVolume)}") |
println(" ${"%4.2f".format(sumVolume)}") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,281: | Line 2,281: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="lua">items = { ["panaea"] = { ["value"] = 3000, ["weight"] = 0.3, ["volume"] = 0.025 }, |
||
["ichor"] = { ["value"] = 1800, ["weight"] = 0.2, ["volume"] = 0.015 }, |
["ichor"] = { ["value"] = 1800, ["weight"] = 0.2, ["volume"] = 0.015 }, |
||
["gold"] = { ["value"] = 2500, ["weight"] = 2.0, ["volume"] = 0.002 } |
["gold"] = { ["value"] = 2500, ["weight"] = 2.0, ["volume"] = 0.002 } |
||
Line 2,316: | Line 2,316: | ||
for k, v in pairs( best_amounts ) do |
for k, v in pairs( best_amounts ) do |
||
print( k, v ) |
print( k, v ) |
||
end</ |
end</syntaxhighlight> |
||
=={{header|MiniZinc}}== |
=={{header|MiniZinc}}== |
||
<syntaxhighlight lang="minizinc"> |
|||
<lang MiniZinc> |
|||
%Knapsack problem/Unbounded. Nigel Galloway, August 13th., 2021 |
%Knapsack problem/Unbounded. Nigel Galloway, August 13th., 2021 |
||
enum Items ={panacea,ichor,gold}; |
enum Items ={panacea,ichor,gold}; |
||
Line 2,328: | Line 2,328: | ||
solve maximize sum(n in Items)(value[n]*take[n]); |
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"]) |
output(["Take "++show(take[panacea])++" vials of panacea\nTake "++show(take[ichor])++" ampules of ichor\nTake "++ show(take[gold])++" bars of gold\n"]) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,340: | Line 2,340: | ||
=={{header|M4}}== |
=={{header|M4}}== |
||
A brute force solution: |
A brute force solution: |
||
< |
<syntaxhighlight lang="m4">divert(-1) |
||
define(`set2d',`define(`$1[$2][$3]',`$4')') |
define(`set2d',`define(`$1[$2][$3]',`$4')') |
||
define(`get2d',`defn(`$1[$2][$3]')') |
define(`get2d',`defn(`$1[$2][$3]')') |
||
Line 2,373: | Line 2,373: | ||
')') |
')') |
||
divert |
divert |
||
mv best</ |
mv best</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>54500 (0,15,11) (3,10,11) (6,5,11) (9,0,11)</pre> |
<pre>54500 (0,15,11) (3,10,11) (6,5,11) (9,0,11)</pre> |
||
Line 2,379: | Line 2,379: | ||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
Brute force algorithm: |
Brute force algorithm: |
||
< |
<syntaxhighlight lang="mathematica">{pva,pwe,pvo}={3000,3/10,1/40}; |
||
{iva,iwe,ivo}={1800,2/10,3/200}; |
{iva,iwe,ivo}={1800,2/10,3/200}; |
||
{gva,gwe,gvo}={2500,2,2/1000}; |
{gva,gwe,gvo}={2500,2,2/1000}; |
||
Line 2,388: | Line 2,388: | ||
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=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&]; |
data=Select[data,#[[2]]<=25&&#[[3]]<=1/4&]; |
||
First[SplitBy[Sort[data,First[#1]>First[#2]&],First]]</ |
First[SplitBy[Sort[data,First[#1]>First[#2]&],First]]</syntaxhighlight> |
||
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}: |
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}: |
||
< |
<syntaxhighlight lang="mathematica">{{54500,247/10,247/1000,{9,0,11}},{54500,124/5,247/1000,{6,5,11}},{54500,249/10,247/1000,{3,10,11}},{54500,25,247/1000,{0,15,11}}}</syntaxhighlight> |
||
if we call the three items by their first letters the best packings are: |
if we call the three items by their first letters the best packings are: |
||
< |
<syntaxhighlight lang="mathematica">p:9 i:0 v:11 |
||
p:6 i:5 v:11 |
p:6 i:5 v:11 |
||
p:3 i:10 v:11 |
p:3 i:10 v:11 |
||
p:0 i:15 v:11</ |
p:0 i:15 v:11</syntaxhighlight> |
||
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. |
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}}== |
=={{header|Mathprog}}== |
||
< |
<syntaxhighlight lang="mathprog">/*Knapsack |
||
This model finds the integer optimal packing of a knapsack |
This model finds the integer optimal packing of a knapsack |
||
Line 2,427: | Line 2,427: | ||
; |
; |
||
end;</ |
end;</syntaxhighlight> |
||
The solution produced is at [[Knapsack problem/Unbounded/Mathprog]]. |
The solution produced is at [[Knapsack problem/Unbounded/Mathprog]]. |
||
Line 2,433: | Line 2,433: | ||
{{trans|Fortran}} |
{{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. |
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. |
||
< |
<syntaxhighlight lang="modula3">MODULE Knapsack EXPORTS Main; |
||
FROM IO IMPORT Put; |
FROM IO IMPORT Put; |
||
Line 2,479: | Line 2,479: | ||
Put("This is achieved by carrying " & Int(n[1]) & " panacea, " & Int(n[2]) & " ichor and " & Int(n[3]) & " gold items\n"); |
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"); |
Put("The weight of this carry is " & Real(totalWeight) & " and the volume used is " & Real(totalVolume) & "\n"); |
||
END Knapsack.</ |
END Knapsack.</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>Maximum value achievable is 54500 |
<pre>Maximum value achievable is 54500 |
||
Line 2,488: | Line 2,488: | ||
{{trans|Pascal}} |
{{trans|Pascal}} |
||
This is a brute-force solution translated from Pascal to Nim, which is straightforward. |
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 lenientops # Mixed float/int operators. |
||
Line 2,525: | Line 2,525: | ||
echo fmt"Maximum value achievable is {maxValue}." |
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"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}."</ |
echo fmt"The weight of this carry is {totalWeight:6.3f} and the volume used is {totalVolume:6.4f}."</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,536: | Line 2,536: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
This is a brute-force solution: it generates a list of every legal combination of items and then finds the best results: |
This is a brute-force solution: it generates a list of every legal combination of items and then finds the best results: |
||
< |
<syntaxhighlight lang="ocaml">type bounty = { name:string; value:int; weight:float; volume:float } |
||
let bounty n d w v = { name = n; value = d; weight = w; volume = v } |
let bounty n d w v = { name = n; value = d; weight = w; volume = v } |
||
Line 2,611: | Line 2,611: | ||
print_newline() |
print_newline() |
||
let () = List.iter print best_results</ |
let () = List.iter print best_results</syntaxhighlight> |
||
outputs: |
outputs: |
||
Line 2,656: | Line 2,656: | ||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
Using constraint propagation and branch and bound search: |
Using constraint propagation and branch and bound search: |
||
< |
<syntaxhighlight lang="oz">declare |
||
proc {Knapsack Sol} |
proc {Knapsack Sol} |
||
solution(panacea:P = {FD.decl} |
solution(panacea:P = {FD.decl} |
||
Line 2,679: | Line 2,679: | ||
{System.showInfo "\nResult:"} |
{System.showInfo "\nResult:"} |
||
{Show Best} |
{Show Best} |
||
{System.showInfo "total value: "#{Value Best}}</ |
{System.showInfo "total value: "#{Value Best}}</syntaxhighlight> |
||
If you study the output, you see how the weight and volume equations automagically constrain the domain of the three variables. |
If you study the output, you see how the weight and volume equations automagically constrain the domain of the three variables. |
||
Line 2,734: | Line 2,734: | ||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
With ideas from C, Fortran and Modula-3. |
With ideas from C, Fortran and Modula-3. |
||
< |
<syntaxhighlight lang="pascal">Program Knapsack(output); |
||
uses |
uses |
||
Line 2,787: | Line 2,787: | ||
writeln ('This is achieved by carrying ', n[1], ' panacea, ', n[2], ' ichor and ', n[3], ' gold items'); |
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); |
writeln ('The weight of this carry is ', totalWeight:6:3, ' and the volume used is ', totalVolume:6:4); |
||
end.</ |
end.</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>:> ./Knapsack |
<pre>:> ./Knapsack |
||
Line 2,797: | Line 2,797: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Dynamic programming solution. Before you ask, no, it's actually slower for the given data set. See the alternate data set. |
Dynamic programming solution. Before you ask, no, it's actually slower for the given data set. See the alternate data set. |
||
< |
<syntaxhighlight lang="perl">my (@names, @val, @weight, @vol, $max_vol, $max_weight, $vsc, $wsc); |
||
if (1) { # change 1 to 0 for different data set |
if (1) { # change 1 to 0 for different data set |
||
Line 2,867: | Line 2,867: | ||
$wtot/$wsc, $vtot/$vsc, $x->[0]; |
$wtot/$wsc, $vtot/$vsc, $x->[0]; |
||
print "\nCache hit: $hits\tmiss: $misses\n";</ |
print "\nCache hit: $hits\tmiss: $misses\n";</syntaxhighlight> |
||
Output:<pre>Max value 54500, with: |
Output:<pre>Max value 54500, with: |
||
Line 2,883: | Line 2,883: | ||
For each goodie, fill yer boots, then (except for the last) recursively try with fewer and fewer.<br> |
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. |
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: #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;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
Line 2,928: | Line 2,928: | ||
<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: #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> |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,939: | Line 2,939: | ||
=={{header|Picat}}== |
=={{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). |
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 => |
go => |
||
Line 2,997: | Line 2,997: | ||
Volume = [ 0.025, 0.015, 0.002], |
Volume = [ 0.025, 0.015, 0.002], |
||
MaxWeight = 25.0, |
MaxWeight = 25.0, |
||
MaxVolume = 0.25.</ |
MaxVolume = 0.25.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,011: | Line 3,011: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Brute force solution |
Brute force solution |
||
< |
<syntaxhighlight lang="picolisp">(de *Items |
||
("panacea" 3 25 3000) |
("panacea" 3 25 3000) |
||
("ichor" 2 15 1800) |
("ichor" 2 15 1800) |
||
Line 3,034: | Line 3,034: | ||
(inc 'N) ) |
(inc 'N) ) |
||
(apply tab X (4 2 8 5 5 7) N "x") ) ) |
(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)) )</ |
(tab (14 5 5 7) NIL (sum cadr K) (sum caddr K) (sum cadddr K)) )</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> 15 x ichor 2 15 1800 |
<pre> 15 x ichor 2 15 1800 |
||
Line 3,042: | Line 3,042: | ||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
{{works with|PowerShell|3.0}} |
{{works with|PowerShell|3.0}} |
||
< |
<syntaxhighlight lang="powershell"># Define the items to pack |
||
$Item = @( |
$Item = @( |
||
[pscustomobject]@{ Name = 'panacea'; Unit = 'vials' ; value = 3000; Weight = 0.3; Volume = 0.025 } |
[pscustomobject]@{ Name = 'panacea'; Unit = 'vials' ; value = 3000; Weight = 0.3; Volume = 0.025 } |
||
Line 3,103: | Line 3,103: | ||
# Show the results |
# Show the results |
||
$Solutions</ |
$Solutions</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>0 vials of panacea, 15 ampules of ichor, and 11 bars of gold worth a total of 54500. |
<pre>0 vials of panacea, 15 ampules of ichor, and 11 bars of gold worth a total of 54500. |
||
Line 3,112: | Line 3,112: | ||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
Works with SWI-Prolog and <b>library simplex</b> written by <b>Markus Triska</b>. |
Works with SWI-Prolog and <b>library simplex</b> written by <b>Markus Triska</b>. |
||
< |
<syntaxhighlight lang="prolog">:- use_module(library(simplex)). |
||
% tuples (name, Explantion, Value, weights, volume). |
% tuples (name, Explantion, Value, weights, volume). |
||
Line 3,197: | Line 3,197: | ||
W2 is W1 + Wtemp, |
W2 is W1 + Wtemp, |
||
Vo2 is Vo1 + Votemp ), |
Vo2 is Vo1 + Votemp ), |
||
print_results(S, A0, A1, A2, A3, A4, T, TN, Va2, W2, Vo2).</ |
print_results(S, A0, A1, A2, A3, A4, T, TN, Va2, W2, Vo2).</syntaxhighlight> |
||
Output : |
Output : |
||
<pre> ?- knapsack. |
<pre> ?- knapsack. |
||
Line 3,209: | Line 3,209: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
{{trans|Fortran}} |
{{trans|Fortran}} |
||
< |
<syntaxhighlight lang="purebasic">Define.f TotalWeight, TotalVolyme |
||
Define.i maxPanacea, maxIchor, maxGold, maxValue |
Define.i maxPanacea, maxIchor, maxGold, maxValue |
||
Define.i i, j ,k |
Define.i i, j ,k |
||
Line 3,290: | Line 3,290: | ||
Data.i 0 |
Data.i 0 |
||
Data.f 25.0, 0.25 |
Data.f 25.0, 0.25 |
||
EndDataSection</ |
EndDataSection</syntaxhighlight> |
||
Outputs |
Outputs |
||
Line 3,305: | Line 3,305: | ||
=={{header|R}}== |
=={{header|R}}== |
||
Brute force method |
Brute force method |
||
< |
<syntaxhighlight lang="r"># Define consts |
||
weights <- c(panacea=0.3, ichor=0.2, gold=2.0) |
weights <- c(panacea=0.3, ichor=0.2, gold=2.0) |
||
volumes <- c(panacea=0.025, ichor=0.015, gold=0.002) |
volumes <- c(panacea=0.025, ichor=0.015, gold=0.002) |
||
Line 3,326: | Line 3,326: | ||
# Find the solutions with the highest value |
# Find the solutions with the highest value |
||
vals <- apply(knapok, 1, getTotalValue) |
vals <- apply(knapok, 1, getTotalValue) |
||
knapok[vals == max(vals),]</ |
knapok[vals == max(vals),]</syntaxhighlight> |
||
panacea ichor gold |
panacea ichor gold |
||
2067 9 0 11 |
2067 9 0 11 |
||
Line 3,336: | Line 3,336: | ||
Using Dynamic Programming |
Using Dynamic Programming |
||
<syntaxhighlight lang="r"> |
|||
<lang r> |
|||
Data_<-structure(list(item = c("Panacea", "Ichor", "Gold"), value = c(3000, |
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", |
1800, 2500), weight = c(3, 2, 20), volume = c(25, 15, 2)), .Names = c("item", |
||
Line 3,425: | Line 3,425: | ||
main_knapsack(Data_, 250, 250) |
main_knapsack(Data_, 250, 250) |
||
</syntaxhighlight> |
|||
</lang> |
|||
<syntaxhighlight lang="r"> |
|||
<lang r> |
|||
Output: |
Output: |
||
The Total profit is: 54500 |
The Total profit is: 54500 |
||
You must carry: Gold (x 11 ) |
You must carry: Gold (x 11 ) |
||
You must carry: Panacea (x 9 ) |
You must carry: Panacea (x 9 ) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
Line 3,475: | Line 3,475: | ||
(call-with-values (λ() (fill-sack items 0.25 25 '() 0)) |
(call-with-values (λ() (fill-sack items 0.25 25 '() 0)) |
||
(λ(sacks total) (for ([s sacks]) (display-sack s total)))) |
(λ(sacks total) (for ([s sacks]) (display-sack s total)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 3,503: | Line 3,503: | ||
Brute force, looked a lot at the Ruby solution. |
Brute force, looked a lot at the Ruby solution. |
||
<lang |
<syntaxhighlight lang="raku" line>class KnapsackItem { |
||
has $.volume; |
has $.volume; |
||
has $.weight; |
has $.weight; |
||
Line 3,544: | Line 3,544: | ||
say "maximum value is $max_val\npossible solutions:"; |
say "maximum value is $max_val\npossible solutions:"; |
||
say "panacea\tichor\tgold"; |
say "panacea\tichor\tgold"; |
||
.join("\t").say for @solutions;</ |
.join("\t").say for @solutions;</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre>maximum value is 54500 |
<pre>maximum value is 54500 |
||
Line 3,557: | Line 3,557: | ||
{{trans|Fortran}} |
{{trans|Fortran}} |
||
===displays 1st solution=== |
===displays 1st solution=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program solves the knapsack/unbounded problem: highest value, weight, and volume.*/ |
||
/* value weight volume */ |
/* value weight volume */ |
||
Line 3,593: | Line 3,593: | ||
say left('', 40) "total weight: " maxW / 1 |
say left('', 40) "total weight: " maxW / 1 |
||
say left('', 40) "total volume: " maxV / 1 |
say left('', 40) "total volume: " maxV / 1 |
||
/*stick a fork in it, we're all done. */</ |
/*stick a fork in it, we're all done. */</syntaxhighlight> |
||
{{out|output|text= when using the internal default input:}} |
{{out|output|text= when using the internal default input:}} |
||
<pre> |
<pre> |
||
Line 3,607: | Line 3,607: | ||
===displays all solutions=== |
===displays all solutions=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program solves the knapsack/unbounded problem: highest value, weight, and volume.*/ |
||
maxPanacea= 0 |
maxPanacea= 0 |
||
Line 3,647: | Line 3,647: | ||
say left('', 40) "total volume: " maxV.j / 1 |
say left('', 40) "total volume: " maxV.j / 1 |
||
end /*j*/ |
end /*j*/ |
||
/*stick a fork in it, we're all done. */</ |
/*stick a fork in it, we're all done. */</syntaxhighlight> |
||
{{out|output|text= when using the internal default input:}} |
{{out|output|text= when using the internal default input:}} |
||
<pre> |
<pre> |
||
Line 3,693: | Line 3,693: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Brute force method, {{trans|Tcl}} |
Brute force method, {{trans|Tcl}} |
||
< |
<syntaxhighlight lang="ruby">KnapsackItem = Struct.new(:volume, :weight, :value) |
||
panacea = KnapsackItem.new(0.025, 0.3, 3000) |
panacea = KnapsackItem.new(0.025, 0.3, 3000) |
||
ichor = KnapsackItem.new(0.015, 0.2, 1800) |
ichor = KnapsackItem.new(0.015, 0.2, 1800) |
||
Line 3,729: | Line 3,729: | ||
i*ichor.weight + p*panacea.weight + g*gold.weight, |
i*ichor.weight + p*panacea.weight + g*gold.weight, |
||
i*ichor.volume + p*panacea.volume + g*gold.volume |
i*ichor.volume + p*panacea.volume + g*gold.volume |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,740: | Line 3,740: | ||
=={{header|SAS}}== |
=={{header|SAS}}== |
||
This is yet another brute force solution. |
This is yet another brute force solution. |
||
< |
<syntaxhighlight lang="sas">data one; |
||
wtpanacea=0.3; wtichor=0.2; wtgold=2.0; |
wtpanacea=0.3; wtichor=0.2; wtgold=2.0; |
||
volpanacea=0.025; volichor=0.015; volgold=0.002; |
volpanacea=0.025; volichor=0.015; volgold=0.002; |
||
Line 3,769: | Line 3,769: | ||
proc print data=one (obs=4); |
proc print data=one (obs=4); |
||
var panacea ichor gold vals; |
var panacea ichor gold vals; |
||
run;</ |
run;</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 3,781: | Line 3,781: | ||
Use SAS/OR: |
Use SAS/OR: |
||
< |
<syntaxhighlight lang="sas">/* create SAS data set */ |
||
data mydata; |
data mydata; |
||
input Item $1-19 Value weight Volume; |
input Item $1-19 Value weight Volume; |
||
Line 3,820: | Line 3,820: | ||
print TotalValue; |
print TotalValue; |
||
for {s in 1.._NSOL_} print {i in ITEMS} NumSelected[i].sol[s]; |
for {s in 1.._NSOL_} print {i in ITEMS} NumSelected[i].sol[s]; |
||
quit;</ |
quit;</syntaxhighlight> |
||
MILP solver output: |
MILP solver output: |
||
Line 3,859: | Line 3,859: | ||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
===Functional approach (Tail recursive)=== |
===Functional approach (Tail recursive)=== |
||
< |
<syntaxhighlight lang="scala">import scala.annotation.tailrec |
||
object UnboundedKnapsack extends App { |
object UnboundedKnapsack extends App { |
||
Line 3,896: | Line 3,896: | ||
packer(items.map(i => Knapsack(Seq(i))), Nil).foreach(println) |
packer(items.map(i => Knapsack(Seq(i))), Nil).foreach(println) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,908: | Line 3,908: | ||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
< |
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i"; |
||
include "float.s7i"; |
include "float.s7i"; |
||
Line 3,958: | Line 3,958: | ||
writeln("This is achieved by carrying " <& bestAmounts[1] <& " panacea, " <& bestAmounts[2] <& " ichor and " <& bestAmounts[3] <& " gold items"); |
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); |
writeln("The weight of this carry is " <& best.weight <& " and the volume used is " <& best.volume digits 4); |
||
end func;</ |
end func;</syntaxhighlight> |
||
Output: |
Output: |
||
Line 3,969: | Line 3,969: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
< |
<syntaxhighlight lang="ruby">struct KnapsackItem { |
||
Number volume, |
Number volume, |
||
Number weight, |
Number weight, |
||
Line 4,033: | Line 4,033: | ||
#{"-" * 50} |
#{"-" * 50} |
||
Total:\t #{"%8d%8g%8d" % (wtot/wsc, vtot/vsc, x[0])} |
Total:\t #{"%8d%8g%8d" % (wtot/wsc, vtot/vsc, x[0])} |
||
EOT</ |
EOT</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,047: | Line 4,047: | ||
=={{header|Tcl}}== |
=={{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 code quite legible: |
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 code quite legible: |
||
< |
<syntaxhighlight lang="tcl">#!/usr/bin/env tclsh |
||
proc main argv { |
proc main argv { |
||
array set value {panacea 3000 ichor 1800 gold 2500} |
array set value {panacea 3000 ichor 1800 gold 2500} |
||
Line 4,077: | Line 4,077: | ||
puts "maxval: $maxval, best: $best" |
puts "maxval: $maxval, best: $best" |
||
} |
} |
||
main $argv</ |
main $argv</syntaxhighlight> |
||
<pre>$ time tclsh85 /Tcl/knapsack.tcl |
<pre>$ time tclsh85 /Tcl/knapsack.tcl |
||
Line 4,090: | Line 4,090: | ||
filter them by the volume and weight restrictions, partition the remaining packings |
filter them by the volume and weight restrictions, partition the remaining packings |
||
by value, and search for the maximum value class. |
by value, and search for the maximum value class. |
||
< |
<syntaxhighlight lang="ursala">#import nat |
||
#import flo |
#import flo |
||
Line 4,103: | Line 4,103: | ||
#cast %nmL |
#cast %nmL |
||
human_readable = ~&p/*<'panacea','ichor','gold'> solutions</ |
human_readable = ~&p/*<'panacea','ichor','gold'> solutions</syntaxhighlight> |
||
output: |
output: |
||
<pre>< |
<pre>< |
||
Line 4,117: | Line 4,117: | ||
whilst the one below is focussing more on expressing/solving the problem |
whilst the one below is focussing more on expressing/solving the problem |
||
in less lines of code. |
in less lines of code. |
||
< |
<syntaxhighlight lang="vb">Function Min(E1, E2): Min = IIf(E1 < E2, E1, E2): End Function 'small Helper-Function |
||
Sub Main() |
Sub Main() |
||
Line 4,141: | Line 4,141: | ||
If M(Value) = S(1)(Value) Then Debug.Print M(Value), M(Weight), M(Volume), M(PC), M(IC), M(GC) |
If M(Value) = S(1)(Value) Then Debug.Print M(Value), M(Weight), M(Volume), M(PC), M(IC), M(GC) |
||
Next |
Next |
||
End Sub</ |
End Sub</syntaxhighlight> |
||
Output:<pre> Value Weight Volume PanaceaCount IchorCount GoldCount |
Output:<pre> Value Weight Volume PanaceaCount IchorCount GoldCount |
||
54500 24.7 0.247 9 0 11 |
54500 24.7 0.247 9 0 11 |
||
Line 4,152: | Line 4,152: | ||
{{trans|Kotlin}} |
{{trans|Kotlin}} |
||
{{libheader|Wren-fmt}} |
{{libheader|Wren-fmt}} |
||
< |
<syntaxhighlight lang="ecmascript">import "/fmt" for Fmt |
||
class Item { |
class Item { |
||
Line 4,228: | Line 4,228: | ||
System.print("----------- ------ ----- ------ ------") |
System.print("----------- ------ ----- ------ ------") |
||
Fmt.write("$d items $2d $5.0f $4.1f", itemCount, sumNumber, bestValue, sumWeight) |
Fmt.write("$d items $2d $5.0f $4.1f", itemCount, sumNumber, bestValue, sumWeight) |
||
Fmt.print(" $4.2f", sumVolume)</ |
Fmt.print(" $4.2f", sumVolume)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,242: | Line 4,242: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="zkl">panacea:=T(3000, 0.3, 0.025); // (value,weight,volume) |
||
ichor :=T(1800, 0.2, 0.015); |
ichor :=T(1800, 0.2, 0.015); |
||
gold :=T(2500, 2.0, 0.002); |
gold :=T(2500, 2.0, 0.002); |
||
Line 4,262: | Line 4,262: | ||
" %d panacea, %d ichor and %d gold").fmt(best[1].xplode())); |
" %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" |
println("The weight to carry is %4.1f and the volume used is %5.3f" |
||
.fmt(best[0][1,*].xplode()));</ |
.fmt(best[0][1,*].xplode()));</syntaxhighlight> |
||
cprod3 is the Cartesian product of three lists or iterators. |
cprod3 is the Cartesian product of three lists or iterators. |
||
{{out}} |
{{out}} |