Knapsack problem/Continuous: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
|||
Line 166: | Line 166: | ||
2.40 of greaves |
2.40 of greaves |
||
3.50 of welt |
3.50 of welt |
||
</pre> |
|||
=={{header|GNU APL}}== |
|||
<lang APL>⍝ Data |
|||
Items←'beef' 'pork' 'ham' 'greaves' 'flitch' 'brawn' 'welt' 'salami' 'sausage' |
|||
Weights←3.8 5.4 3.6 2.4 4 2.5 3.7 3 5.9 |
|||
Prices←36 43 90 45 30 56 67 95 98 |
|||
⍝ Solution |
|||
Order←⍒Worth←Prices÷Weights ⍝ 'Worth' is each item value for 1 kg. |
|||
diff←{¯1↓(⍵,0)-0,⍵} ⍝ 'diff' between each item and the prev item (the inverse of '+\'). |
|||
Filter←×Selected←diff 15⌊+\Weights[Order] ⍝ 'Selected' weights totaling 15kg, others 0. |
|||
Table←⊃{⍺,⍪⍵}/Items Weights Selected[⍋Order] |
|||
Take←Filter[⍋Order]/[1]Table |
|||
TotalCost←+/Prices×Selected[⍋Order]÷Weights |
|||
⍝ Output |
|||
⎕←'ITEM' 'WEIGHT AVAILABLE' 'WEIGHT SELECTED' ⍪ Take |
|||
⎕←'' |
|||
⎕←'total cost:' TotalCost |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
ITEM WEIGHT AVAILABLE WEIGHT SELECTED |
|||
ham 3.6 3.6 |
|||
greaves 2.4 2.4 |
|||
brawn 2.5 2.5 |
|||
welt 3.7 3.5 |
|||
salami 3 3 |
|||
total cost: 349.3783784 |
|||
</pre> |
</pre> |
||
Line 436: | Line 405: | ||
</pre> |
</pre> |
||
=={{header|C#}}== |
=={{header|C sharp|C#}}== |
||
<lang csharp>using System; //4790@3.6 |
<lang csharp>using System; //4790@3.6 |
||
class Program |
class Program |
||
Line 505: | Line 474: | ||
"brawn","welt","salami","sausage"}; |
"brawn","welt","salami","sausage"}; |
||
}</lang> |
}</lang> |
||
=={{header|Clojure}}== |
|||
<lang Clojure> |
|||
; Solve Continuous Knapsack Problem |
|||
; Nicolas Modrzyk |
|||
; January 2015 |
|||
(def maxW 15.0) |
|||
(def items |
|||
{:beef [3.8 36] |
|||
:pork [5.4 43] |
|||
:ham [3.6 90] |
|||
:greaves [2.4 45] |
|||
:flitch [4.0 30] |
|||
:brawn [2.5 56] |
|||
:welt [3.7 67] |
|||
:salami [3.0 95] |
|||
:sausage [5.9 98]}) |
|||
(defn rob [items maxW] |
|||
(let[ |
|||
val-item |
|||
(fn[key] |
|||
(- (/ (second (items key)) (first (items key ))))) |
|||
compare-items |
|||
(fn[key1 key2] |
|||
(compare (val-item key1) (val-item key2))) |
|||
sorted (into (sorted-map-by compare-items) items)] |
|||
(loop [current (first sorted) |
|||
array (rest sorted) |
|||
value 0 |
|||
weight 0] |
|||
(let[new-weight (first (val current)) |
|||
new-value (second (val current))] |
|||
(if (> (- maxW weight new-weight) 0) |
|||
(do |
|||
(println "Take all " (key current)) |
|||
(recur |
|||
(first array) |
|||
(rest array) |
|||
(+ value new-value) |
|||
(+ weight new-weight))) |
|||
(let [t (- maxW weight)] ; else |
|||
(println |
|||
"Take " t " of " |
|||
(key current) "\n" |
|||
"Total Value is:" |
|||
(+ value (* t (/ new-value new-weight)))))))))) |
|||
(rob items maxW) |
|||
</lang> |
|||
Output<pre> |
|||
Take all :salami |
|||
Take all :ham |
|||
Take all :brawn |
|||
Take all :greaves |
|||
Take 3.5 of :welt |
|||
Total Value is: 349.3783783783784 |
|||
</pre> |
|||
===Alternate Version=== |
|||
<lang Clojure> |
|||
(def items |
|||
[{:name "beef" :weight 3.8 :price 36} |
|||
{:name "pork" :weight 5.4 :price 43} |
|||
{:name "ham" :weight 3.6 :price 90} |
|||
{:name "graves" :weight 2.4 :price 45} |
|||
{:name "flitch" :weight 4.0 :price 30} |
|||
{:name "brawn" :weight 2.5 :price 56} |
|||
{:name "welt" :weight 3.7 :price 67} |
|||
{:name "salami" :weight 3.0 :price 95} |
|||
{:name "sausage" :weight 5.9 :price 98}]) |
|||
(defn per-kg [item] (/ (:price item) (:weight item))) |
|||
(defn rob [items capacity] |
|||
(let [best-items (reverse (sort-by per-kg items))] |
|||
(loop [items best-items cap capacity total 0] |
|||
(let [item (first items)] |
|||
(if (< (:weight item) cap) |
|||
(do (println (str "Take all " (:name item))) |
|||
(recur (rest items) (- cap (:weight item)) (+ total (:price item)))) |
|||
(println (format "Take %.1f kg of %s\nTotal: %.2f monies" |
|||
cap (:name item) (+ total (* cap (per-kg item)))))))))) |
|||
(rob items 15) |
|||
</lang> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
Line 766: | Line 647: | ||
Take 3.5kg of welt |
Take 3.5kg of welt |
||
</pre> |
</pre> |
||
=={{header|Clojure}}== |
|||
<lang Clojure> |
|||
; Solve Continuous Knapsack Problem |
|||
; Nicolas Modrzyk |
|||
; January 2015 |
|||
(def maxW 15.0) |
|||
(def items |
|||
{:beef [3.8 36] |
|||
:pork [5.4 43] |
|||
:ham [3.6 90] |
|||
:greaves [2.4 45] |
|||
:flitch [4.0 30] |
|||
:brawn [2.5 56] |
|||
:welt [3.7 67] |
|||
:salami [3.0 95] |
|||
:sausage [5.9 98]}) |
|||
(defn rob [items maxW] |
|||
(let[ |
|||
val-item |
|||
(fn[key] |
|||
(- (/ (second (items key)) (first (items key ))))) |
|||
compare-items |
|||
(fn[key1 key2] |
|||
(compare (val-item key1) (val-item key2))) |
|||
sorted (into (sorted-map-by compare-items) items)] |
|||
(loop [current (first sorted) |
|||
array (rest sorted) |
|||
value 0 |
|||
weight 0] |
|||
(let[new-weight (first (val current)) |
|||
new-value (second (val current))] |
|||
(if (> (- maxW weight new-weight) 0) |
|||
(do |
|||
(println "Take all " (key current)) |
|||
(recur |
|||
(first array) |
|||
(rest array) |
|||
(+ value new-value) |
|||
(+ weight new-weight))) |
|||
(let [t (- maxW weight)] ; else |
|||
(println |
|||
"Take " t " of " |
|||
(key current) "\n" |
|||
"Total Value is:" |
|||
(+ value (* t (/ new-value new-weight)))))))))) |
|||
(rob items maxW) |
|||
</lang> |
|||
Output<pre> |
|||
Take all :salami |
|||
Take all :ham |
|||
Take all :brawn |
|||
Take all :greaves |
|||
Take 3.5 of :welt |
|||
Total Value is: 349.3783783783784 |
|||
</pre> |
|||
===Alternate Version=== |
|||
<lang Clojure> |
|||
(def items |
|||
[{:name "beef" :weight 3.8 :price 36} |
|||
{:name "pork" :weight 5.4 :price 43} |
|||
{:name "ham" :weight 3.6 :price 90} |
|||
{:name "graves" :weight 2.4 :price 45} |
|||
{:name "flitch" :weight 4.0 :price 30} |
|||
{:name "brawn" :weight 2.5 :price 56} |
|||
{:name "welt" :weight 3.7 :price 67} |
|||
{:name "salami" :weight 3.0 :price 95} |
|||
{:name "sausage" :weight 5.9 :price 98}]) |
|||
(defn per-kg [item] (/ (:price item) (:weight item))) |
|||
(defn rob [items capacity] |
|||
(let [best-items (reverse (sort-by per-kg items))] |
|||
(loop [items best-items cap capacity total 0] |
|||
(let [item (first items)] |
|||
(if (< (:weight item) cap) |
|||
(do (println (str "Take all " (:name item))) |
|||
(recur (rest items) (- cap (:weight item)) (+ total (:price item)))) |
|||
(println (format "Take %.1f kg of %s\nTotal: %.2f monies" |
|||
cap (:name item) (+ total (* cap (per-kg item)))))))))) |
|||
(rob items 15) |
|||
</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 1,166: | Line 1,135: | ||
3.00 of "salami" |
3.00 of "salami" |
||
</pre> |
</pre> |
||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
Line 1,314: | Line 1,282: | ||
end program KNAPSACK_CONTINUOUS</lang> |
end program KNAPSACK_CONTINUOUS</lang> |
||
=={{header|GNU APL}}== |
|||
<lang APL>⍝ Data |
|||
Items←'beef' 'pork' 'ham' 'greaves' 'flitch' 'brawn' 'welt' 'salami' 'sausage' |
|||
Weights←3.8 5.4 3.6 2.4 4 2.5 3.7 3 5.9 |
|||
Prices←36 43 90 45 30 56 67 95 98 |
|||
⍝ Solution |
|||
Order←⍒Worth←Prices÷Weights ⍝ 'Worth' is each item value for 1 kg. |
|||
diff←{¯1↓(⍵,0)-0,⍵} ⍝ 'diff' between each item and the prev item (the inverse of '+\'). |
|||
Filter←×Selected←diff 15⌊+\Weights[Order] ⍝ 'Selected' weights totaling 15kg, others 0. |
|||
Table←⊃{⍺,⍪⍵}/Items Weights Selected[⍋Order] |
|||
Take←Filter[⍋Order]/[1]Table |
|||
TotalCost←+/Prices×Selected[⍋Order]÷Weights |
|||
⍝ Output |
|||
⎕←'ITEM' 'WEIGHT AVAILABLE' 'WEIGHT SELECTED' ⍪ Take |
|||
⎕←'' |
|||
⎕←'total cost:' TotalCost |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
ITEM WEIGHT AVAILABLE WEIGHT SELECTED |
|||
ham 3.6 3.6 |
|||
greaves 2.4 2.4 |
|||
brawn 2.5 2.5 |
|||
welt 3.7 3.5 |
|||
salami 3 3 |
|||
total cost: 349.3783784 |
|||
</pre> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 1,567: | Line 1,566: | ||
Take (3.500000 kg) of the welt worth $63.378378 |
Take (3.500000 kg) of the welt worth $63.378378 |
||
Total value of a full knapsack is $349.378378</pre> |
Total value of a full knapsack is $349.378378</pre> |
||
=={{header|J}}== |
=={{header|J}}== |
||
Line 2,020: | Line 2,018: | ||
{{trans|Fortran}} |
{{trans|Fortran}} |
||
Using QuickSort (a generic form, non recursive) |
Using QuickSort (a generic form, non recursive) |
||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
<lang M2000 Interpreter> |
<lang M2000 Interpreter> |
||
Line 2,464: | Line 2,463: | ||
---------------------------------------- |
---------------------------------------- |
||
total value: 349.378378378378 |
total value: 349.378378378378 |
||
</pre> |
|||
=={{header|Perl 6}}== |
|||
{{works with|rakudo|2015-09-16}} |
|||
This Solutions sorts the item by WEIGHT/VALUE |
|||
<lang perl6>class KnapsackItem { |
|||
has $.name; |
|||
has $.weight is rw; |
|||
has $.price is rw; |
|||
has $.ppw; |
|||
method new (Str $n, Rat $w, Int $p) { |
|||
self.bless(:name($n), :weight($w), :price($p), :ppw($w/$p)) |
|||
} |
|||
method cut-maybe ($max-weight) { |
|||
return False if $max-weight > $.weight; |
|||
$.price = $max-weight / $.ppw; |
|||
$.weight = $.ppw * $.price; |
|||
return True; |
|||
} |
|||
method gist () { sprintf "%8s %1.2f %3.2f", |
|||
$.name, |
|||
$.weight, |
|||
$.price } |
|||
} |
|||
my $max-w = 15; |
|||
say "Item Portion Value"; |
|||
.say for gather |
|||
for < beef 3.8 36 |
|||
pork 5.4 43 |
|||
ham 3.6 90 |
|||
greaves 2.4 45 |
|||
flitch 4.0 30 |
|||
brawn 2.5 56 |
|||
welt 3.7 67 |
|||
salami 3.0 95 |
|||
sausage 5.9 98 > |
|||
==> map({ KnapsackItem.new($^a, $^b, $^c) }) |
|||
==> sort *.ppw |
|||
{ |
|||
my $last-one = .cut-maybe($max-w); |
|||
take $_; |
|||
$max-w -= .weight; |
|||
last if $last-one; |
|||
}</lang> |
|||
'''Output:''' |
|||
<pre> |
|||
%perl6 knapsack_continous.p6 |
|||
Item Portion Value |
|||
salami 3.00 95.00 |
|||
ham 3.60 90.00 |
|||
brawn 2.50 56.00 |
|||
greaves 2.40 45.00 |
|||
welt 3.50 63.38 |
|||
</pre> |
</pre> |
||
Line 3,033: | Line 2,974: | ||
Take 3.50 of the welt (for 63.38) |
Take 3.50 of the welt (for 63.38) |
||
For a grand total of: 349.38</pre> |
For a grand total of: 349.38</pre> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{works with|rakudo|2015-09-16}} |
|||
This Solutions sorts the item by WEIGHT/VALUE |
|||
<lang perl6>class KnapsackItem { |
|||
has $.name; |
|||
has $.weight is rw; |
|||
has $.price is rw; |
|||
has $.ppw; |
|||
method new (Str $n, Rat $w, Int $p) { |
|||
self.bless(:name($n), :weight($w), :price($p), :ppw($w/$p)) |
|||
} |
|||
method cut-maybe ($max-weight) { |
|||
return False if $max-weight > $.weight; |
|||
$.price = $max-weight / $.ppw; |
|||
$.weight = $.ppw * $.price; |
|||
return True; |
|||
} |
|||
method gist () { sprintf "%8s %1.2f %3.2f", |
|||
$.name, |
|||
$.weight, |
|||
$.price } |
|||
} |
|||
my $max-w = 15; |
|||
say "Item Portion Value"; |
|||
.say for gather |
|||
for < beef 3.8 36 |
|||
pork 5.4 43 |
|||
ham 3.6 90 |
|||
greaves 2.4 45 |
|||
flitch 4.0 30 |
|||
brawn 2.5 56 |
|||
welt 3.7 67 |
|||
salami 3.0 95 |
|||
sausage 5.9 98 > |
|||
==> map({ KnapsackItem.new($^a, $^b, $^c) }) |
|||
==> sort *.ppw |
|||
{ |
|||
my $last-one = .cut-maybe($max-w); |
|||
take $_; |
|||
$max-w -= .weight; |
|||
last if $last-one; |
|||
}</lang> |
|||
'''Output:''' |
|||
<pre> |
|||
%perl6 knapsack_continous.p6 |
|||
Item Portion Value |
|||
salami 3.00 95.00 |
|||
ham 3.60 90.00 |
|||
brawn 2.50 56.00 |
|||
greaves 2.40 45.00 |
|||
welt 3.50 63.38 |
|||
</pre> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 3,210: | Line 3,210: | ||
----------------------- |
----------------------- |
||
total 15.000 349.378</pre> |
total 15.000 349.378</pre> |
||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Line 3,403: | Line 3,402: | ||
salami 3.0 |
salami 3.0 |
||
welt 3.5 </pre> |
welt 3.5 </pre> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
===Functional approach (Tail recursive)=== |
===Functional approach (Tail recursive)=== |
||
Line 3,470: | Line 3,470: | ||
Totals: weight: 15.0, value: 349.38</pre> |
Totals: weight: 15.0, value: 349.38</pre> |
||
{{Out}}See it in running in your browser by [https://scalafiddle.io/sf/RHZQ4Xj/1 ScalaFiddle (JavaScript)] <!--or by [https://scastie.scala-lang.org/mDoBS77YSG2Z7w5xdAPzcw Scastie (JVM)]-->. |
{{Out}}See it in running in your browser by [https://scalafiddle.io/sf/RHZQ4Xj/1 ScalaFiddle (JavaScript)] <!--or by [https://scastie.scala-lang.org/mDoBS77YSG2Z7w5xdAPzcw Scastie (JVM)]-->. |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |