Knapsack problem/Continuous: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(102 intermediate revisions by 48 users not shown)
Line 1:
{{task|Classic CS problems and programs}}
 
<!-- a thief (or burglar) steals, a robber robs (confronts a person while stealing). Not exactly a perfect definition, but close enough. -- Gerard Schildberger. -->
See also: [[Knapsack problem]] and [[wp:Continuous_knapsack_problem|Wikipedia]].
 
A thief burgles a butcher's shop, where he can select from some items.
A robber burgles a butcher's shop, where he can select from some items. He knows the weights and prices of each items. Because he has a knapsack with 15 kg maximal capacity, he wants to select the items such that he would have his profit maximized. He may cut the items; the item has a reduced price after cutting that is proportional to the original price by the ratio of masses. That means: half of an item has half the price of the original.
 
The thief knows the weights and prices of each items. &nbsp; Because he has a knapsack with 15 kg maximal capacity, he wants to select the items such that he would have his profit maximized. &nbsp; He may cut the items; &nbsp; the item has a reduced price after cutting that is proportional to the original price by the ratio of masses. &nbsp; That means: &nbsp; half of an item has half the price of the original.
This is the item list in the butcher's:
 
 
{| style="text-align: left; width: 80%;" border="4" cellpadding="2" cellspacing="2"
This is the item list in the butcher's shop:
 
::::::{| style="text-align: left; width: 40%;" border="4" cellpadding="2" cellspacing="2"
|+ Table of potential knapsack items
|- style="background-color: rgb(255, 204, 255);"
Line 33 ⟶ 36:
|}
 
'''Which items does the robber carry in his knapsack so that their total weight does not exceed 15 kg, and their total value is maximised?'''
 
<br>
=={{header|Ada}}==
;Task:
Show which items the thief carries in his knapsack so that their total weight does not exceed 15 kg, and their total value is maximized.
 
<lang Ada>with Ada.Text_IO;
with Ada.Strings.Unbounded;
 
;Related tasks:
* &nbsp; [[Knapsack problem/Bounded]]
* &nbsp; [[Knapsack problem/Unbounded]]
* &nbsp; [[Knapsack problem/0-1]]
<br><br>
 
;See also:
* &nbsp; Wikipedia article: &nbsp; [[wp:Continuous_knapsack_problem|continuous knapsack]].
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V items = [(‘beef’, 3.8, 36.0),
(‘pork’, 5.4, 43.0),
(‘ham’, 3.6, 90.0),
(‘greaves’, 2.4, 45.0),
(‘flitch’, 4.0, 30.0),
(‘brawn’, 2.5, 56.0),
(‘welt’, 3.7, 67.0),
(‘salami’, 3.0, 95.0),
(‘sausage’, 5.9, 98.0)]
 
V MAXWT = 15.0
 
V sorted_items = sorted(items.map((name, amount, value) -> (value / amount, amount, name)), reverse' 1B)
V wt = 0.0
V val = 0.0
[(String, Float, Float)] bagged
 
L(unit_value, amount, name) sorted_items
V portion = min(MAXWT - wt, amount)
wt += portion
V addval = portion * unit_value
val += addval
bagged [+]= (name, portion, addval)
I wt >= MAXWT
L.break
 
print(‘ ITEM PORTION VALUE’)
print(bagged.map((n, p, a) -> ‘#10 #3.2 #3.2’.format(n, p, a)).join("\n"))
print("\nTOTAL WEIGHT: #2.2\nTOTAL VALUE: #2.2".format(wt, val))</syntaxhighlight>
 
{{out}}
<pre>
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
 
TOTAL WEIGHT: 15.00
TOTAL VALUE: 349.38
</pre>
 
=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_IO;
with Ada.Float_Text_IO;
with Ada.Strings.Unbounded;
procedure Knapsack_Continuous is
package US renames Ada.Strings.Unbounded;
 
type Item is record
Name : US.Unbounded_String;
Line 49 ⟶ 112:
Taken : Float;
end record;
 
function "<" (Left, Right : Item) return Boolean is
begin
Line 55 ⟶ 118:
Float (Right.Value) / Right.Weight;
end "<";
 
type Item_Array is array (Positive range <>) of Item;
 
function Total_Weight (Items : Item_Array) return Float is
Sum : Float := 0.0;
begin
for I in Items'Range loop
Sum := Sum + Items (I).Weight * Items (I).Taken;
end loop;
return Sum;
end Total_Weight;
 
function Total_Value (Items : Item_Array) return Float is
Sum : Float := 0.0;
begin
for I in Items'Range loop
Sum := Sum + Float (Items (I).Value) / Items(I).Weight * Items (I).Taken;
end loop;
return Sum;
end Total_Value;
 
procedure Solve_Knapsack_Continuous
(Items : in out Item_Array;
Line 110 ⟶ 173:
end;
end Solve_Knapsack_Continuous;
All_Items : Item_Array :=
 
All_Items : Item_Array :=
((US.To_Unbounded_String ("beef"), 3.8, 36, 0.0),
(US.To_Unbounded_String ("pork"), 5.4, 43, 0.0),
Line 121 ⟶ 183:
(US.To_Unbounded_String ("salami"), 3.0, 95, 0.0),
(US.To_Unbounded_String ("sausage"), 5.9, 98, 0.0));
 
begin
Solve_Knapsack_Continuous (All_Items, 15.0);
Ada.Text_IO.Put_LinePut ("Total Weight: ");
("Total Weight: " & Float'ImageAda.Float_Text_IO.Put (Total_Weight (All_Items)), 0, 2, 0);
Ada.Text_IO.Put_LineNew_Line;
Ada.Text_IO.Put ("Total Value: " & Float'Image (Total_Value (All_Items)));
Ada.Float_Text_IO.Put (Total_Value (All_Items), 0, 2, 0);
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("Items:");
for I in All_Items'Range loop
if All_Items (I).Taken > 0.0 then
Ada.Text_IO.Put_LinePut (" ");
Ada.Float_Text_IO.Put ("All_Items (I).Taken, 0, "2, &0);
Ada.Text_IO.Put_Line (" of Float'Image" & US.To_String (All_Items (I).TakenName) &);
" of " &
US.To_String (All_Items (I).Name));
end if;
end loop;
end Knapsack_Continuous;</lang>
</syntaxhighlight>
{{out}}
<pre>
Total Weight: 15.00
Total Value: 349.38
Items:
3.00 of salami
3.60 of ham
2.50 of brawn
2.40 of greaves
3.50 of welt
</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk"># syntax: GAWK -f KNAPSACK_PROBLEM_CONTINUOUS.AWK
BEGIN {
# arr["item,weight,price"]
arr["beef,3.8,36"]
arr["pork,5.4,43"]
arr["ham,3.6,90"]
arr["greaves,2.4,45"]
arr["flitch,4.0,30"]
arr["brawn,2.5,56"]
arr["welt,3.7,67"]
arr["salami,3.0,95"]
arr["sausage,5.9,98"]
for (i in arr) {
split(i,tmp,",")
arr[i] = tmp[3] / tmp[2] # $/unit
}
sack_size = 15 # kg
PROCINFO["sorted_in"] = "@val_num_desc"
print("item weight price $/unit")
for (i in arr) {
if (total_weight >= sack_size) {
break
}
split(i,tmp,",")
weight = tmp[2]
if (total_weight + weight <= sack_size) {
price = tmp[3]
msg = "all"
}
else {
weight = sack_size - total_weight
price = weight * arr[i]
msg = weight " of " tmp[2]
}
printf("%-7s %6.2f %6.2f %6.2f take %s\n",tmp[1],weight,tmp[3],arr[i],msg)
total_items++
total_price += price
total_weight += weight
}
printf("%7d %6.2f %6.2f total\n",total_items,total_weight,total_price)
exit(0)
}
</syntaxhighlight>
{{out}}
<pre>
item weight price $/unit
salami 3.00 95.00 31.67 take all
ham 3.60 90.00 25.00 take all
brawn 2.50 56.00 22.40 take all
greaves 2.40 45.00 18.75 take all
welt 3.50 67.00 18.11 take 3.5 of 3.7
5 15.00 349.38 total
</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> INSTALL @lib$+"SORTSALIB"
Sort% = FN_sortSAinit(1, 0) : REM Descending
Line 179 ⟶ 309:
PRINT '"Total weight = " ; TotalWeight " kg"
PRINT "Total price = " ; TotalPrice
END</langsyntaxhighlight>
Output:
<pre>Take all the salami
Take all the salami
Take all the ham
Take all the brawn
Line 191 ⟶ 320:
Total price = 349.378379
</pre>
 
=={{header|Befunge}}==
{{trans|XPL0}}
The table of weights and prices are stored as strings to make them easier to edit. Two characters for the weight (with the decimal point dropped), two characters for the price, and then the name of the item. The total numbers of items (9) is specified by the first value on the stack.
 
<syntaxhighlight lang="befunge">9:02p>:5+::::::0\g68*-55+*\1\g68*-+\0\pv>2gg!*::!2v
>\`!v|:-1p\3\0p\2\+-*86g\3\*+55-*86g\2<<1v*g21\*g2<
nib@_>0022p6>12p:212gg48*:**012gg/\-:0`3^+>,,55+%6v
#v0pg2231$$_^#`+5g20:+1g21$_+#!:#<0#<<p22<\v84,+*8<
*>22gg+::55*6*`\55*6*-*022gg\-:55+/68*+"."^>*"fo "v
^6*55:,+55$$_,#!1#`+#*:#82#42#:g<g22:4,,,,,,," kg"<
3836beef
5443pork
3690ham
2445greaves
4030flitch
2556brawn
3767welt
3095salami
5998sausage</syntaxhighlight>
 
{{out}}
<pre>3.0 kg of salami
3.6 kg of ham
2.5 kg of brawn
2.4 kg of greaves
3.5 kg of welt</pre>
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat">( ( fixed {function to convert a rational number to fixed point notation.
The second argument is the number of decimals. }
= value decimals powerOf10
Line 242 ⟶ 398:
| out$(fixed$(!totalPrice.2))
)
);</langsyntaxhighlight>
Output:<pre>3.5 kg of welt
<pre>3.5 kg of welt
2.4 kg of greaves
2.5 kg of brawn
Line 252 ⟶ 407:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 288 ⟶ 443:
 
return 0;
}</langsyntaxhighlight>output<pre>
take all salami
take all ham
Line 295 ⟶ 450:
take 3.5kg of 3.7 kg of welt
</pre>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System; //4790@3.6
class Program
{
static void Main()
{
Console.WriteLine(knapSack(15) + "\n");
var sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 1000; i > 0; i--) knapSack(15);
Console.Write(sw.Elapsed); Console.Read(); // 0.60 µs
}
 
static string knapSack(double w1)
{
int k = w.Length; var q = new double[k];
for (int i = 0; i < k; ) q[i] = v[i] / w[i++];
var c = new double[k];
Array.Copy(q, c, k); Array.Sort(c, w);
Array.Copy(q, c, k); Array.Sort(c, v);
Array.Sort(q, items);
string str = "";
for (k--; k >= 0; k--)
if (w1 - w[k] > 0) { w1 -= w[k]; str += items[k] + "\n"; }
else break;
return w1 > 0 && k >= 0 ? str + items[k] : str;
}
 
static double[] w = { 3.8, 5.4, 3.6, 2.4, 4.0, 2.5, 3.7, 3.0, 5.9 },
 
v = { 36, 43, 90, 45, 30, 56, 67, 95, 98 };
 
static string[] items = {"beef","pork","ham","greaves","flitch",
"brawn","welt","salami","sausage"};
}</syntaxhighlight>
Sorting three times is expensive,
an alternative is sorting once, with an indices array.
<syntaxhighlight lang="csharp">using System;
class Program
{
static void Main()
{
Console.WriteLine(knapSack(15) + "\n");
var sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 1000; i > 0; i--) knapSack(15);
Console.Write(sw.Elapsed); Console.Read(); // 0.37 µs
}
 
static string knapSack(double w1)
{
int i = 0, k = w.Length; var idx = new int[k];
{
var q = new double[k];
while (i < k) q[i] = v[i] / w[idx[i] = i++];
Array.Sort(q, idx);
}
string str = "";
for (k--; k >= 0; k--)
if (w1 > w[i = idx[k]]) { w1 -= w[i]; str += items[i] + "\n"; }
else break;
return w1 > 0 && k >= 0 ? str + items[idx[k]] : str;
}
 
static double[] w = { 3.8, 5.4, 3.6, 2.4, 4.0, 2.5, 3.7, 3.0, 5.9 },
 
v = { 36, 43, 90, 45, 30, 56, 67, 95, 98 };
 
static string[] items = {"beef","pork","ham","greaves","flitch",
"brawn","welt","salami","sausage"};
}</syntaxhighlight>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include<iostream>
<lang cpp>
#include<iostream>
#include<algorithm>
#include<string.h>
Line 392 ⟶ 616:
 
return 0;
}</syntaxhighlight>
}
 
{{out}}
</lang>
<pre>
Total Value = 349.378
Total Weight = 15
Items Used:
We took 3kg of "salami" and the value it brought is 95
We took 3.6kg of "ham" and the value it brought is 90
We took 2.5kg of "brawn" and the value it brought is 56
We took 2.4kg of "greaves" and the value it brought is 45
We took 3.5kg of "welt" and the value it brought is 63.3784
</pre>
 
===Alternate Version===
<syntaxhighlight lang="cpp">// C++11 version
<lang cpp>
// C++11 version
#include <iostream>
#include <vector>
Line 450 ⟶ 683:
space -= item.weight;
}
}</syntaxhighlight>
}
 
</lang>
{{out}}
<pre>
Take all salami
Take all ham
Take all brawn
Take all greaves
Take 3.5kg of welt
</pre>
 
=={{header|Clojure}}==
<syntaxhighlight 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)
</syntaxhighlight>
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===
<syntaxhighlight 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)
</syntaxhighlight>
 
=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">(defstruct item
(name nil :type string)
(weight nil :type real)
(price nil :type real))
 
(defun price-per-weight (item)
(/ (item-price item) (item-weight item)))
 
(defun knapsack (items total-weight)
(loop with sorted = (sort items #'> :key #'price-per-weight)
while (plusp total-weight)
for item in sorted
for amount = (min (item-weight item) total-weight)
collect (list (item-name item) amount)
do (decf total-weight amount)))
 
(defun main ()
(let ((items (list (make-item :name "beef" :weight 3.8 :price 36)
(make-item :name "pork" :weight 5.4 :price 43)
(make-item :name "ham" :weight 3.6 :price 90)
(make-item :name "greaves" :weight 2.4 :price 45)
(make-item :name "flitch" :weight 4.0 :price 30)
(make-item :name "brawn" :weight 2.5 :price 56)
(make-item :name "welt" :weight 3.7 :price 67)
(make-item :name "salami" :weight 3.0 :price 95)
(make-item :name "sausage" :weight 5.9 :price 98))))
(loop for (name amount) in (knapsack items 15)
do (format t "~8A: ~,2F kg~%" name amount))))</syntaxhighlight>
{{out}}
<pre>salami : 3.00 kg
ham : 3.60 kg
brawn : 2.50 kg
greaves : 2.40 kg
welt : 3.50 kg</pre>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.string;
 
struct Item {
Line 464 ⟶ 829:
}
 
string toString() const /*pure /*nothrow*/ @safe {
return format("%10s %7.2f %7.2f %7.2f",
name, amount, value, valuePerKG);
Line 470 ⟶ 835:
}
 
real sumBy(string field)(in Item[] items) @safe pure nothrow @nogc {
@safe pure nothrow @nogc {
//return reduce!(ctEval!("a + b." ~ field))(0.0L, items);
return reduce!("a + b." ~ field)(0.0L, items);
}
 
void main() /*@safe*/ {
const items = [Item("beef", 3.8, 36.0),
Item("pork", 5.4, 43.0),
Line 503 ⟶ 866:
writefln("%(%s\n%)", chosen);
Item("TOTAL", chosen.sumBy!"amount", chosen.sumBy!"value").writeln;
}</langsyntaxhighlight>
{{out}}
<pre> ITEM AMOUNT VALUE $/unit
Line 514 ⟶ 877:
 
===Alternative Version===
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.algorithm;
 
Line 539 ⟶ 902:
} else
return writefln("Take %.1fkg %s", left, it.item);
}</langsyntaxhighlight>
{{out}}
<pre>Take all the salami
Line 546 ⟶ 909:
Take all the greaves
Take 3.5kg welt</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
 
{Structure to hold the data}
 
type TButcherInfo = record
Name: string;
Weight,Cost,PerKG: double;
end;
type PButcherInfo = ^TButcherInfo;
 
{Array of actual data}
 
var Items: array [0..8] of TButcherInfo =(
(Name: 'beef'; Weight: 3.8; Cost: 36.0),
(Name: 'pork'; Weight: 5.4; Cost: 43.0),
(Name: 'ham'; Weight: 3.6; Cost: 90.0),
(Name: 'greaves'; Weight: 2.4; Cost: 45.0),
(Name: 'flitch'; Weight: 4.0; Cost: 30.0),
(Name: 'brawn'; Weight: 2.5; Cost: 56.0),
(Name: 'welt'; Weight: 3.7; Cost: 67.0),
(Name: 'salami'; Weight: 3.0; Cost: 95.0),
(Name: 'sausage'; Weight: 5.9; Cost: 98.0)
);
 
 
function CompareButcher(List: TStringList; Index1, Index2: Integer): Integer;
{Compare routine to sort by Per Kilograph cost}
var Info1,Info2: TButcherInfo;
begin
Info1:=PButcherInfo(List.Objects[Index1])^;
Info2:=PButcherInfo(List.Objects[Index2])^;
Result:=Trunc(Info2.PerKG * 100 - Info1.PerKG * 100);
end;
 
 
procedure KnapsackProblem(Memo: TMemo);
{Solve the knapsack problem}
var SL: TStringList;
var I,Inx: integer;
var Info: TButcherInfo;
var Weight,Cost,Diff: double;
const Limit = 15;
begin
SL:=TStringList.Create;
try
{Calculate the per Kilogram cost for each item}
for I:=0 to High(Items) do
begin
Items[I].PerKG:=Items[I].Cost/Items[I].Weight;
SL.AddObject(Items[I].Name,@Items[I]);
end;
{Sort most expensive items to top of list}
SL.CustomSort(CompareButcher);
 
{Take the most expensive items }
Weight:=0; Cost:=0;
for I:=0 to SL.Count-1 do
begin
Info:=PButcherInfo(SL.Objects[I])^;
{Item exceeds the weight limit? }
if (Weight+Info.Weight)>=Limit then
begin
{Calculate percent to fill gap}
Diff:=(Limit-Weight)/Info.Weight;
{Save index}
Inx:=I;
break;
end
else
begin
{Add up totals}
Weight:=Weight+Info.Weight;
Cost:=Cost+Info.Cost;
end;
end;
 
{Display all items}
Memo.Lines.Add('Item Portion Value');
Memo.Lines.Add('--------------------------');
for I:=0 to Inx-1 do
begin
Info:=PButcherInfo(SL.Objects[I])^;
Memo.Lines.Add(Format('%-8s %8.2f %8.2f',[Info.Name,Info.Weight,Info.Cost]));
end;
Info:=PButcherInfo(SL.Objects[Inx])^;
{Calculate cost and weight to fill gap}
weight:=Weight+Info.Weight*Diff;
Cost:=Cost+Info.Cost*Diff;
{Display gap filling item}
Memo.Lines.Add(Format('%-8s %8.2f %8.2f',[Info.Name,Info.Weight*Diff,Info.Cost*Diff]));
Memo.Lines.Add('--------------------------');
Memo.Lines.Add(Format('Totals %8.2f %8.2f',[Weight,Cost]));
finally SL.Free; end;
end;
 
 
 
 
</syntaxhighlight>
{{out}}
<pre>
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
--------------------------
Totals 15.00 349.38
 
Elapsed Time: 10.998 ms.
 
</pre>
 
 
=={{header|EchoLisp}}==
<syntaxhighlight lang="scheme">
(lib 'struct)
(lib 'sql) ;; for table
 
(define T (make-table (struct meal (name poids price))))
 
(define meals
'((🐂-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)))
 
(list->table meals T)
;; sort table according to best price/poids ratio
(define (price/poids a b )
(- (// (* (meal-price b) (meal-poids a)) (meal-price a) (meal-poids b)) 1))
(table-sort T price/poids)
 
(define-syntax-rule (name i) (table-xref T i 0))
(define-syntax-rule (poids i) (table-xref T i 1))
 
;; shop : add items in basket, in order, until W exhausted
(define (shop W )
(for/list ((i (table-count T)))
#:break (<= W 0)
(begin0
(cons (name i) (if (<= (poids i) W) 'all W))
(set! W (- W (poids i))))))
 
;; output
(shop 15)
→ ((🐃--salami . all) (🍗-ham . all) (brawn . all) (🐪-greaves . all) (welt . 3.5))
 
 
</syntaxhighlight>
 
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
class
CONTINUOUS_KNAPSACK
 
create
make
 
feature
 
make
local
tup: TUPLE [name: STRING; weight: REAL_64; price: REAL_64]
do
create tup
create items.make_filled (tup, 1, 9)
create sorted.make
sorted.extend (-36.0 / 3.8)
sorted.extend (-43.0 / 5.4)
sorted.extend (-90.0 / 3.6)
sorted.extend (-45.0 / 2.4)
sorted.extend (-30.0 / 4.0)
sorted.extend (-56.0 / 2.5)
sorted.extend (-67.0 / 3.7)
sorted.extend (-95.0 / 3.0)
sorted.extend (-98.0 / 5.9)
tup := ["beef", 3.8, 36.0]
items [sorted.index_of (- tup.price / tup.weight, 1)] := tup
tup := ["pork", 5.4, 43.0]
items [sorted.index_of (- tup.price / tup.weight, 1)] := tup
tup := ["ham", 3.6, 90.0]
items [sorted.index_of (- tup.price / tup.weight, 1)] := tup
tup := ["greaves", 2.4, 45.0]
items [sorted.index_of (- tup.price / tup.weight, 1)] := tup
tup := ["flitch", 4.0, 30.0]
items [sorted.index_of (- tup.price / tup.weight, 1)] := tup
tup := ["brawn", 2.5, 56.0]
items [sorted.index_of (- tup.price / tup.weight, 1)] := tup
tup := ["welt", 3.7, 67.0]
items [sorted.index_of (- tup.price / tup.weight, 1)] := tup
tup := ["salami", 3.0, 95.0]
items [sorted.index_of (- tup.price / tup.weight, 1)] := tup
tup := ["sausage", 5.9, 98.0]
items [sorted.index_of (- tup.price / tup.weight, 1)] := tup
find_solution
end
 
find_solution
-- Solution for the continuous Knapsack Problem.
local
maxW, value: REAL_64
do
maxW := 15
across
items as c
loop
if maxW - c.item.weight > 0 then
io.put_string ("Take all: " + c.item.name + ".%N")
value := value + c.item.price
maxW := maxW - c.item.weight
elseif maxW /= 0 then
io.put_string ("Take " + maxW.truncated_to_real.out + " kg off " + c.item.name + ".%N")
io.put_string ("The total value is " + (value + (c.item.price / c.item.weight) * maxW).truncated_to_real.out + ".")
maxW := 0
end
end
end
 
items: ARRAY [TUPLE [name: STRING; weight: REAL_64; price: REAL_64]]
 
sorted: SORTED_TWO_WAY_LIST [REAL_64]
 
end
</syntaxhighlight>
{{out}}
<pre>
Take all: salami.
Take all: ham.
Take all: brawn.
Take all: greaves.
Take 3.5kg off welt.
The total value is 349.378
</pre>
 
=={{header|Elixir}}==
{{trans|Erlang}}
<syntaxhighlight lang="elixir">defmodule KnapsackProblem do
def select( max_weight, items ) do
Enum.sort_by( items, fn {_name, weight, price} -> - price / weight end )
|> Enum.reduce( {max_weight, []}, &select_until/2 )
|> elem(1)
|> Enum.reverse
end
def task( items, max_weight ) do
IO.puts "The robber takes the following to maximize the value"
Enum.each( select( max_weight, items ), fn {name, weight} ->
:io.fwrite("~.2f of ~s~n", [weight, name])
end )
end
defp select_until( {name, weight, _price}, {remains, acc} ) when remains > 0 do
selected_weight = select_until_weight( weight, remains )
{remains - selected_weight, [{name, selected_weight} | acc]}
end
defp select_until( _item, acc ), do: acc
defp select_until_weight( weight, remains ) when weight < remains, do: weight
defp select_until_weight( _weight, remains ), do: remains
end
 
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} ]
 
KnapsackProblem.task( items, 15 )</syntaxhighlight>
 
{{out}}
<pre>
The robber takes the following to maximize the value
3.00 of salami
3.60 of ham
2.50 of brawn
2.40 of greaves
3.50 of welt
</pre>
 
===Alternate Version===
{{trans|Ruby}}
<syntaxhighlight lang="elixir">defmodule KnapsackProblem do
def continuous(items, max_weight) do
Enum.sort_by(items, fn {_item, {weight, price}} -> -price / weight end)
|> Enum.reduce_while({max_weight,0}, fn {item, {weight, price}}, {rest, value} ->
if rest > weight do
IO.puts "Take all #{item}"
{:cont, {rest - weight, value + price}}
else
:io.format "Take ~.3fkg of ~s~n~n", [rest, item]
:io.format "Total value of swag is ~.2f~n", [value + rest*price/weight]
{:halt, :ok}
end
end)
|> case do
{weight, value} ->
:io.format "Total: weight ~.3fkg, value ~p~n", [max_weight-weight, value]
x -> x
end
end
end
 
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} ]
 
KnapsackProblem.continuous( items, 15 )</syntaxhighlight>
 
{{out}}
<pre>
Take all salami
Take all ham
Take all brawn
Take all greaves
Take 3.500kg of welt
 
Total value of swag is 349.38
</pre>
 
=={{header|Erlang}}==
Note use of lists:foldr/2, since sort is ascending.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( knapsack_problem_continuous ).
 
Line 586 ⟶ 1,291:
select_until_weight( Weight, Remains ) when Weight < Remains -> Weight;
select_until_weight( _Weight, Remains ) -> Remains.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 598 ⟶ 1,303:
</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
//Fill a knapsack optimally - Nigel Galloway: February 1st., 2015
let 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)]
|> List.sortBy(fun(_,weight,value) -> float(-value)/weight)
 
 
let knap items maxW=
let rec take(n,g,a) =
match g with
| i::e -> let name, weight, value = i
let total = n + weight
if total <= maxW then
printfn "Take all %s" name
take(total, e, a+float(value))
else
printfn "Take %0.2f kg of %s\nTotal value of swag is %0.2f" (maxW - n) name (a + (float(value)/weight)*(maxW - n))
| [] -> printfn "Everything taken! Total value of swag is £%0.2f; Total weight of bag is %0.2fkg" a n
take(0.0, items, 0.0)
</syntaxhighlight>
{{out}}
<pre>
> knap items 15.0;;
Take all salami
Take all ham
Take all brawn
Take all greaves
Take 3.50kg of welt
Total value of swag is £349.38
</pre>
Should your burglar be greedy, he may bring a bigger bag.
<pre>
> knap items 100.0;;
Take all salami
Take all ham
Take all brawn
Take all greaves
Take all welt
Take all sausage
Take all beef
Take all pork
Take all flitch
Everything taken! Total value of swag is £560.00; Total weight of bag is 34.30kg
</pre>
 
=={{header|Forth}}==
{{trans|D}}
{{works with|4tH|3.62.0}}
<langsyntaxhighlight lang="forth">include lib/selcsort.4th \ use a tiny sorting algorithm
 
150 value left \ capacity in 1/10th kilo
Line 640 ⟶ 1,389:
;
 
knapsack</langsyntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
 
<langsyntaxhighlight lang="fortran">program KNAPSACK_CONTINUOUS
implicit none
Line 699 ⟶ 1,448:
write(*, "(f15.2, f8.2)") total_weight, total_value
end program KNAPSACK_CONTINUOUS</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">#define PesoMax 15.0
Type Knapsack
articulo As String*7
peso As Double
precio As Double
End Type
'build item list
Dim item(1 To 9) As Knapsack => { _
("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)}
 
Dim As Boolean Roba(Ubound(item))
Dim As Double PrecioXPeso(Ubound(item))
Dim As Integer i, MejorArticulo
Dim As Double Mejor, PesoArtic, TotalPeso = 0, TPeso = 0, TPrecio = 0, temp
 
For i = 1 To Ubound(item)
PrecioXPeso(i) = item(i).precio / item(i).peso
Roba(i) = False
Next i
 
Print "You can carry the following materials in the knapsack: "
Do
Mejor = 0
For i = 1 To Ubound(item)
If Not Roba(i) And PrecioXPeso(i) > Mejor Then
Mejor = PrecioXPeso(i)
MejorArticulo = i
End If
Next i
Roba(MejorArticulo) = True 'take item
PesoArtic = item(MejorArticulo).peso 'get its weight
TotalPeso += PesoArtic 'add to total weight
If TotalPeso > PesoMax Then 'if total is too much, reduce
PesoArtic -= TotalPeso - PesoMax 'item weight by amount it's over
End If
Print Using "##.# kg of "; PesoArtic; 'show weight and item
TPeso += PesoArtic
Print item(MejorArticulo).articulo;
temp = PesoArtic * item(MejorArticulo).precio / item(MejorArticulo).peso
TPrecio += temp
Print Chr(9); Using "(Value = ##.###)"; temp
Loop Until TotalPeso >= PesoMax 'all we can steal
 
Print !"\nMaximal weight:"; PesoMax; " kg"
Print Using "Total weight: ###.## kg"; TPeso
Print Using "Total value: ###.##"; TPrecio
Sleep</syntaxhighlight>
{{out}}
<pre>You can carry the following materials in the knapsack:
3.0 kg salami (Value = 95.000)
3.6 kg ham (Value = 90.000)
2.5 kg brawn (Value = 56.000)
2.4 kg greaves (Value = 45.000)
3.5 kg welt (Value = 63.378)
 
Maximal weight: 15 kg
Total weight: 15.00 kg
Total value: 349.38</pre>
 
=={{header|GNU APL}}==
<syntaxhighlight 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
</syntaxhighlight>
{{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}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 751 ⟶ 1,593:
}
}
}</langsyntaxhighlight>
Output:
<pre>
Line 763 ⟶ 1,605:
=={{header|Groovy}}==
Solution: obvious greedy algorithm
<langsyntaxhighlight lang="groovy">import static java.math.RoundingMode.*
 
def knapsackCont = { list, maxWeight = 15.0 ->
Line 781 ⟶ 1,623:
}
sack
}</langsyntaxhighlight>
 
Test:
<langsyntaxhighlight lang="groovy">def possibleItems = [
[name:'beef', weight:3.8, value:36],
[name:'pork', weight:5.4, value:43],
Line 800 ⟶ 1,642:
contents.each {
printf(" name: %-7s weight: ${it.weight} value: ${it.value}\n", it.name)
}</langsyntaxhighlight>
 
Output:
Line 814 ⟶ 1,656:
We use a greedy algorithm.
 
<langsyntaxhighlight lang="haskell">import ControlData.MonadList (sortBy)
import Data.List (sortBy)
import Data.Ord (comparing)
import Text.Printf (printf)
import Control.Monad (forM_)
import Data.Ratio (numerator, denominator)
import Text.Printf
 
maxWgt :: Rational
maxWgt = 15
 
data Bounty = Bounty
{ itemName :: String,
, itemVal, itemWgt :: Rational}
}
 
items =:: [Bounty]
items =
[Bounty "beef" 36 3.8,
[ Bounty "porkbeef" 36 43 53.4,8
, Bounty "hampork" 43 90 35.6,4
, Bounty "greavesham" 90 45 23.4,6
, Bounty "flitchgreaves" 45 30 2.4.0,
, Bounty "brawnflitch" 30 56 24.5,0
, Bounty "weltbrawn" 56 67 32.7,5
, Bounty "salamiwelt" 95 67 3.0,7
, Bounty "sausagesalami" 95 98 53.9]0
, Bounty "sausage" 98 5.9
]
 
solution :: [(Rational, Bounty)]
solution = g maxWgt $ sortBy (flip $ comparing f) items
where
where g room (b@(Bounty _ _ w) : bs) = if w < room
g thenroom (w, b)@(Bounty :_ g (room -_ w):bs) bs=
if w < else [(room, b)]
fthen (Bounty _ v w, b) =: vg /(room - w) bs
else [(room, b)]
f (Bounty _ v w) = v / w
 
main :: IO ()
main = do
forM_ solution $ \(w, b) -> printf "%s kg of %s\n" (mixedNum w) (itemName b)
(printf "%sTotal kg ofvalue: %s\n" (. mixedNum w. sum) (itemName$ b)f <$> solution
where
printf "Total value: %s\n" $ mixedNum $ sum $ map f solution
where f (w, Bounty _ v wtot) = v * (w / wtot)
mixedNum q = if b == 0
if b == then show a0
then show a
else printf "%d %d/%d" a (numerator b) (denominator b)
else printf where"%d %d/%d" a =(numerator b) floor(denominator qb)
where
b = q - toEnum a</lang>
a = floor q
b = q - toEnum a</syntaxhighlight>
{{Out}}
<pre>3 kg of salami
3 3/5 kg of ham
2 1/2 kg of brawn
2 2/5 kg of greaves
3 1/2 kg of welt
Total value: 349 14/37</pre>
 
Or similar to above (but more succinct):
<syntaxhighlight lang="haskell">import Data.List (sortBy)
<lang haskell>
import Data.List (sortBy)
import Data.Ord (comparing)
import Text.Printf (printf)
 
-- (name, (value, weight))
items = [("beef", (36, 3.8)),
[ ("porkbeef", (4336, 53.48)),
, ("hampork", (9043, 35.64)),
, ("greavesham", (4590, 23.46)),
, ("flitchgreaves", (3045, 2.4.0)),
, ("brawnflitch", (5630, 24.50)),
, ("weltbrawn", (6756, 32.75)),
, ("salamiwelt", (9567, 3.07)),
, ("sausagesalami", (9895, 53.90))]
, ("sausage", (98, 5.9))
]
 
unitWeight (_, (val, weight)) = (fromIntegral val) / weight
 
solution k = loop k . sortBy (flip $ comparing unitWeight)
where
where loop k ((name, (_, weight)):xs)
| weight <loop k = putStrLn ("Take all the " ++ (name), >>(_, loop (k-weight) ):xs)
| weight < k = putStrLn ("Take all | otherwise = printfthe "Take %.2f++ kgname) of>> the %s\n"loop (k ::- Floatweight) namexs
| otherwise = printf "Take %.2f kg of the %s\n" (k :: Float) name
 
main = solution 15 items</syntaxhighlight>
{{Out}}
</lang>
<pre>Take all the salami
Take all the ham
Take all the brawn
Take all the greaves
Take 3.50 kg of the welt</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
This implements the greedy algorithm. This also uses a Unicon extension to ''reverse'' which reverses a list. In Icon, an IPL procedure is available to do the same.
<langsyntaxhighlight Iconlang="icon">link printf
 
procedure main()
Line 919 ⟶ 1,784:
item("salami", 3.0, 95),
item("sausage", 5.9, 98) ]
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 930 ⟶ 1,795:
Take (3.500000 kg) of the welt worth $63.378378
Total value of a full knapsack is $349.378378</pre>
 
 
=={{header|J}}==
Line 936 ⟶ 1,800:
We take as much as we can of the most valuable items first, and continue until we run out of space. Only one item needs to be cut.
 
<langsyntaxhighlight Jlang="j">'names numbers'=:|:;:;._2]0 :0
beef 3.8 36
pork 5.4 43
Line 950 ⟶ 1,814:
order=: \:prices%weights
take=: 15&<.&.(+/\) order{weights
result=: (*take)#(order{names),.' ',.":,.take</langsyntaxhighlight>
 
This gives the result:
Line 960 ⟶ 1,824:
 
For a total value of:
<langsyntaxhighlight Jlang="j"> +/prices * (take/:order) % weights
349.378</langsyntaxhighlight>
 
See [[Knapsack_problem/Continuous/J]] for some comments on intermediate results...
 
=={{header|Java}}==
Greedy solution.
 
<langsyntaxhighlight lang="java">
package hu.pj.alg.test;
 
Line 1,039 ⟶ 1,905:
}
 
} // class</langsyntaxhighlight>
 
<langsyntaxhighlight lang="java">
package hu.pj.alg;
 
Line 1,117 ⟶ 1,983:
}
 
} // class</langsyntaxhighlight>
 
<langsyntaxhighlight lang="java">
package hu.pj.obj;
 
Line 1,178 ⟶ 2,044:
}
 
} // class</langsyntaxhighlight>
 
output:
Line 1,193 ⟶ 2,059:
3,5 kg welt (value = 63,378)</pre>
 
=={{header|Mathematicajq}}==
{{ works with|jq|1.4}}
 
<syntaxhighlight lang="jq"># continuous_knapsack(W) expects the input to be
# an array of objects {"name": _, "weight": _, "value": _}
# where "value" is the value of the given weight of the object.
 
def continuous_knapsack(W):
map( .price = (if .weight > 0 then (.value/.weight) else 0 end) )
| sort_by( .price )
| reverse
| reduce .[] as $item
# state: [array, capacity]
([[], W];
.[1] as $c
| if $c <= 0 then .
else ( [$item.weight, $c] | min) as $min
| [.[0] + [ $item | (.weight = $min) | .value = (.price * $min)],
($c - $min) ]
end)
| .[1] as $remainder
| .[0]
| (.[] | {name, weight}),
"Total value: \( map(.value) | add)",
"Total weight: \(W - $remainder)" ;</syntaxhighlight>
'''The task:'''
<syntaxhighlight lang="jq">def items: [
{ "name": "beef", "weight": 3.8, "value": 36},
{ "name": "pork", "weight": 5.4, "value": 43},
{ "name": "ham", "weight": 3.6, "value": 90},
{ "name": "greaves", "weight": 2.4, "value": 45},
{ "name": "flitch", "weight": 4.0, "value": 30},
{ "name": "brawn", "weight": 2.5, "value": 56},
{ "name": "welt", "weight": 3.7, "value": 67},
{ "name": "salami", "weight": 3.0, "value": 95},
{ "name": "sausage", "weight": 5.9, "value": 98} ];
 
items | continuous_knapsack(15)</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">$ jq -r -c -n -f knapsack_continuous.jq
{"name":"salami","weight":3}
{"name":"ham","weight":3.6}
{"name":"brawn","weight":2.5}
{"name":"greaves","weight":2.4}
{"name":"welt","weight":3.5000000000000004}
Total value: 349.3783783783784
Total weight: 15</syntaxhighlight>
 
=={{header|Julia}}==
This solution is built around the immutable type <code>KPCSupply</code>, which holds an item's data including its unit value (<code>uvalue</code>). When the store's inventory is kept in this way, the solution to the continuous knapsack problem (provided by <code>solve</code>), is straightforward. The thief should pack as much of the highest value items as are available until full capacity is reached, topping off with as much of the last item as the knapsack will hold. (If the store contains less than the thief's knapsack will hold, he'll take the store's entire inventory.)
 
An [http://docs.julialang.org/en/release-0.3/manual/constructors/#outer-constructor-methods outer constructor method] is used to create instances of <code>KPCSupply</code> when only the <code>item</code>, <code>weight</code> and <code>value</code> are supplied. The <code>isless</code> method is provided for <code>KPCSupply</code> objects so that items are transparently sorted by their unit value. <code>KPCSupply</code> supports any real type for <code>weight</code>, <code>value</code> and <code>uvalue</code> (though this simple implementation does not support mixed types or promotion). This solution uses [http://docs.julialang.org/en/release-0.3/manual/complex-and-rational-numbers/#rational-numbers Rational] numbers to avoid rounding errors until the results are printed.
 
'''Type and Functions''':
<syntaxhighlight lang="julia">using Printf
 
struct KPCSupply{T<:Real}
item::String
weight::T
value::T
uvalue::T
end
function KPCSupply(item::AbstractString, weight::Real, value::Real)
w, v = promote(weight, value)
KPCSupply(item, w, v, v / w)
end
 
Base.show(io::IO, s::KPCSupply) = print(io, s.item, @sprintf " (%.2f kg, %.2f €, %.2f €/kg)" s.weight s.value s.uvalue)
Base.isless(a::KPCSupply, b::KPCSupply) = a.uvalue < b.uvalue
 
function solve(store::Vector{KPCSupply{T}}, capacity::Real) where T<:Real
sack = similar(store, 0) # vector like store, but of length 0
kweight = zero(T)
for s in sort(store, rev = true)
if kweight + s.weight ≤ capacity
kweight += s.weight
push!(sack, s)
else
w = capacity - kweight
v = w * s.uvalue
push!(sack, KPCSupply(s.item, w, v, s.value))
break
end
end
return sack
end</syntaxhighlight>
 
'''Main''':
<syntaxhighlight lang="julia">store = [KPCSupply("beef", 38//10, 36),
KPCSupply("pork", 54//10, 43),
KPCSupply("ham", 36//10, 90),
KPCSupply("greaves", 24//10, 45),
KPCSupply("flitch", 4//1, 30),
KPCSupply("brawn", 25//10, 56),
KPCSupply("welt", 37//10, 67),
KPCSupply("salami", 3//1, 95),
KPCSupply("sausage", 59//10, 98)]
 
sack = solve(store, 15)
println("The store contains:\n - ", join(store, "\n - "))
println("\nThe thief should take::\n - ", join(sack, "\n - "))
@printf("\nTotal value in the sack: %.2f €\n", sum(getfield.(sack, :value)))</syntaxhighlight>
 
{{out}}
<pre>The store contains:
- beef (3.80 kg, 36.00 €, 9.47 €/kg)
- pork (5.40 kg, 43.00 €, 7.96 €/kg)
- ham (3.60 kg, 90.00 €, 25.00 €/kg)
- greaves (2.40 kg, 45.00 €, 18.75 €/kg)
- flitch (4.00 kg, 30.00 €, 7.50 €/kg)
- brawn (2.50 kg, 56.00 €, 22.40 €/kg)
- welt (3.70 kg, 67.00 €, 18.11 €/kg)
- salami (3.00 kg, 95.00 €, 31.67 €/kg)
- sausage (5.90 kg, 98.00 €, 16.61 €/kg)
 
The thief should take::
- salami (3.00 kg, 95.00 €, 31.67 €/kg)
- ham (3.60 kg, 90.00 €, 25.00 €/kg)
- brawn (2.50 kg, 56.00 €, 22.40 €/kg)
- greaves (2.40 kg, 45.00 €, 18.75 €/kg)
- welt (3.50 kg, 63.38 €, 67.00 €/kg)
 
Total value in the sack: 349.38 €</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.2
 
data class Item(val name: String, val weight: Double, val value: Double)
 
val items = mutableListOf(
Item("beef", 3.8, 36.0),
Item("pork", 5.4, 43.0),
Item("ham", 3.6, 90.0),
Item("greaves", 2.4, 45.0),
Item("flitch", 4.0, 30.0),
Item("brawn", 2.5, 56.0),
Item("welt", 3.7, 67.0),
Item("salami", 3.0, 95.0),
Item("sausage", 5.9, 98.0)
)
 
const val MAX_WEIGHT = 15.0
 
fun main(args: Array<String>) {
// sort items by value per unit weight in descending order
items.sortByDescending { it.value / it.weight }
println("Item Chosen Weight Value Percentage")
println("----------- ------ ------ ----------")
var w = MAX_WEIGHT
var itemCount = 0
var sumValue = 0.0
for (item in items) {
itemCount++
if (item.weight <= w) {
sumValue += item.value
print("${item.name.padEnd(11)} ${"%3.1f".format(item.weight)} ${"%5.2f".format(item.value)}")
println(" 100.00")
}
else {
val value = Math.round((w / item.weight * item.value * 100.0)) / 100.0
val percentage = Math.round((w / item.weight * 10000.0)) / 100.0
sumValue += value
print("${item.name.padEnd(11)} ${"%3.1f".format(w)} ${"%5.2f".format(value)}")
println(" $percentage")
break
}
w -= item.weight
if (w == 0.0) break
}
println("----------- ------ ------")
println("${itemCount} items 15.0 ${"%6.2f".format(sumValue)}")
}</syntaxhighlight>
 
{{out}}
<pre>
Item Chosen Weight Value Percentage
----------- ------ ------ ----------
salami 3.0 95.00 100.00
ham 3.6 90.00 100.00
brawn 2.5 56.00 100.00
greaves 2.4 45.00 100.00
welt 3.5 63.38 94.59
----------- ------ ------
5 items 15.0 349.38
</pre>
 
{{trans|Fortran}}
Using QuickSort (a generic form, non recursive)
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module Knapsack {
Form 60, 40
Cls 5, 0
Pen 14
Class Quick {
Private:
partition=lambda-> {
Read &A(), p, r : i = p-1 : x=A(r)
For j=p to r-1 {If .LE(A(j), x) Then i++:Swap A(i),A(j)
} : Swap A(i+1), A(r) : Push i+2, i
}
Public:
LE=Lambda->Number<=Number
\\ module for strings erased here
Function quicksort {
Read ref$
{
loop : If Stackitem() >= Stackitem(2) Then Drop 2 : if empty then {Break} else continue
over 2,2 : call .partition(ref$) :shift 3
}
}
}
Class Item {
name$, weight, aValue ' can't use Value has other meaning
class:
Module Item (.name$, .weight, .aValue) {}
}
Def Double max_weight=15, total_weight, total_value, frac
Def long I
Dim Items(1 to 9)
Flush ' empty stack
\\ now fill stack
Data "beef", 3.8, 36,"pork", 5.4, 43,"ham", 3.6, 90, "greaves", 2.4, 45, "flitch", 4, 30
Data "brawn", 2.5, 56, "welt", 3.7, 67, "salami", 3, 95, "sausage", 5.9, 98
For i=1 to 9 : Items(i)=Item(Letter$, Number, Number): Next i
\\ Setup QuickSort
Quick=Quick()
Quick.LE=lambda (b, a)-> {
=a.avalue/a.weight<=b.avalue/b.weight
}
Call Quick.QuickSort(&items(), 1, 9)
\\ So now we have a sorted array of objects
i=0
\\ Setup console to print
Dim Back(-1 to 0)
Back(-1)=#666666, #444444
Alter=True
\\ $("0.00", 20) Set number rounding for print, and 14 chars column width
\\ $(2) set center justify for non proportional print
\\ $(0) set default - strings justify left, numbers right
Print $("0.00", 20),$(2),"", "Knapsack"
Pen 0 {
Print @(pos, row,width,row+1, 7),"Item", "Weight (Kg)", "Price (value)", $(0)
}
While i<Len(Items()) and total_weight<max_weight {
i++
if total_weight+items(i).weight<max_weight Then {
total_weight+=items(i).weight
total_value+=items(i).avalue
WriteItem(i, 1)
} Else {
frac=(max_weight-total_weight)/items(i).weight
total_weight+=items(i).weight*frac
total_value+=items(i).avalue*frac
WriteItem(i, frac )
}
}
Print
Pen 0 {
Print @(pos+1, row,width,row+1, 7, 7), "Total Weight",total_weight
Print @(pos+1, row,width,row+1, 7, 7), "Total Value", total_value
}
End
Sub WriteItem(i, frac)
For Items(i) {
Print @(pos+1, row,width,row+1, back(alter), 14), .name$, .weight*frac, .avalue*frac
Alter~
}
End Sub
}
Knapsack
</syntaxhighlight>
Output the same as other examples, with some color.
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
 
The problem is solved by sorting the original table by price to weight ratio, finding the accumlated weight, and the index of the item which exedes the carrying capacity (overN)
The output is then all items prior to this one, along with that item corrected for it's excess weighter (overW)
 
<langsyntaxhighlight Mathematicalang="mathematica">Knapsack[shop_, capacity_] := Block[{sortedTable, overN, overW, output},
sortedTable = SortBy[{#1, #2, #3, #3/#2} & @@@ shop, -#[[4]] &];
overN = Position[Accumulate[sortedTable[[1 ;;, 2]]], a_ /; a > capacity, 1,1][[1, 1]];
Line 1,206 ⟶ 2,347:
output[[-1, 2]] = output[[-1, 2]] - overW;
output[[-1, 3]] = output[[-1, 2]] output[[-1, 4]];
Append[output[[1 ;;, 1 ;; 3]], {"Total",Sequence @@ Total[output[[1 ;;, 2 ;; 3]]]}]]</langsyntaxhighlight>
 
A test using the specified data:
<langsyntaxhighlight Mathematicalang="mathematica">weightPriceTable =
{{"beef", 3.8, 36}, {"pork", 5.4, 43}, {"ham", 3.6, 90}, {"greaves", 2.4, 45}, {"flitch", 4., 30},
{"brawn", 2.5, 56}, {"welt", 3.7, 67}, {"salami", 3., 95}, {"sausage", 5.9, 98}};
Line 1,221 ⟶ 2,362:
welt 3.5 63.3784
Total 15. 349.378
</syntaxhighlight>
</lang>
 
=={{header|Mathprog}}==
<syntaxhighlight lang="text">/*Knapsack
This model finds the optimal packing of a knapsack
Line 1,253 ⟶ 2,395:
sausage 5.9 98
;
end;</langsyntaxhighlight>
 
The solution is here at [[Knapsack problem/Continuous/Mathprog]].
 
=={{header|OCamlMiniZinc}}==
<syntaxhighlight lang="minizinc">
%Knapsack Continuous. Nigel Galloway: October 7th., 2020.
enum Items={beef,pork,ham,greaves,flitch,brawn,welt,salami,sausage};
array[Items] of float: weight=[3.8,5.4,3.6,2.4,4.0,2.5,3.7,3.0,5.9];
array[Items] of int: value =[36,43,90,45,30,56,67,95,9];
float: maxWeight=15.0;
var float: wTaken=sum(n in Items)(quantity[n]);
var float: wValue=sum(n in Items)(value[n]*quantity[n]/weight[n]);
array[Items] of var 0.0..(max(weight)): quantity; constraint forall(n in Items)(quantity[n]<=weight[n]);
constraint wTaken <= maxWeight;
solve maximize wValue;
output[concat([let {string: g=show(quantity[n])} in "Take "++(if g==show(weight[n]) then "all" else g endif)++" of \(n)\n" | n in Items where show(quantity[n])!="0.0"])++"\nTotal Weight=\(wTaken) Total Value="++show_float(4,2,wValue)]
</syntaxhighlight>
{{out}}
<pre>
Take all of ham
Take all of greaves
Take all of brawn
Take 3.5 of welt
Take all of salami
 
Total Weight=15.0 Total Value=349.38
<lang ocaml>let items =
</pre>
=={{header|Nim}}==
<syntaxhighlight lang="nim">import algorithm
import strformat
 
type Item = object
name: string
weight: float
price: float
unitPrice: float
 
var items = @[Item(name: "beef", weight: 3.8, price: 36.0),
Item(name: "pork", weight: 5.4, price: 43.0),
Item(name: "ham", weight: 3.6, price: 90.0),
Item(name: "greaves", weight: 2.4, price: 45.0),
Item(name: "flitch", weight: 4.0, price: 30.0),
Item(name: "brawn", weight: 2.5, price: 56.0),
Item(name: "welt", weight: 3.7, price: 67.0),
Item(name: "salami", weight: 3.0, price: 95.0),
Item(name: "sausage", weight: 5.9, price: 98.0)
]
]
# Compute unit prices and sort items by decreasing unit price.
for item in items.mitems:
item.unitPrice = item.price / item.weight
items.sort(proc (x, y: Item): int = cmp(x.unitPrice, y.unitPrice), Descending)
 
var remaining = 15.0
var value = 0.0
for item in items:
if item.weight <= remaining:
echo fmt"Take all {item.name}"
value += item.price
remaining -= item.weight
else:
echo fmt"Take {remaining} kg of {item.name}"
value += remaining * item.unitPrice
break
 
echo fmt"Total value: {value:.2f}"</syntaxhighlight>
 
{{out}}
<pre>
Take all salami
Take all ham
Take all brawn
Take all greaves
Take 3.5 kg of welt
Total value: 349.38
</pre>
 
=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">let items =
[ "beef", 3.8, 36;
"pork", 5.4, 43;
Line 1,292 ⟶ 2,507:
Printf.printf " %7s: %6.2f %6.2f\n" last rem_weight last_price;
Printf.printf " Total Price: %.3f\n" (float price +. last_price);
;;</langsyntaxhighlight>
 
{{out}}
Items Weight Price
greaves: 2.40 45
brawn: 2.50 56
ham: 3.60 90
salami: 3.00 95
welt: 3.50 63.38
Total Price: 349.378
 
=={{header|Oforth}}==
 
<syntaxhighlight lang="oforth">[
[ "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 ]
] const: Items
: rob
| item value |
0.0 ->value
15.0 #[ dup second swap third / ] Items sortBy forEach: item [
dup 0.0 == ifTrue: [ return ]
dup item second >= ifTrue: [
"Taking" . item first . " :" . item second dup .cr -
item third value + ->value continue
]
"And part of" . item first . " :" . dup .cr
item third * item second / value + "Total value :" . .cr break
] ;</syntaxhighlight>
 
{{out}}
<pre>
>rob
Taking salami : 3
Taking ham : 3.6
Taking brawn : 2.5
Taking greaves : 2.4
And part of welt : 3.5
Total value : 349.378378378378
ok
</pre>
 
=={{header|ooRexx}}==
===version 1===
<langsyntaxhighlight lang="oorexx">/*--------------------------------------------------------------------
* 20.09.2014 Walter Pachl translated from REXX version 2
* utilizing ooRexx features like objects, array(s) and sort
Line 1,370 ⟶ 2,628:
Otherwise res='-1'
End
Return res</langsyntaxhighlight>
{{out}}
<pre>
Line 1,393 ⟶ 2,651:
total 15.000 349.378</pre>
===version 2===
<langsyntaxhighlight lang="oorexx">/*--------------------------------------------------------------------
* 20.09.2014 Walter Pachl translated from REXX version 2
* utilizing ooRexx features like objects, array(s) and sort
Line 1,465 ⟶ 2,723:
Expose vpu
use Arg other
return -sign(vpu - other~vpu)</langsyntaxhighlight>
Output is the same as for version 1.
 
=={{header|Pascal}}==
{{works with|FPC}}
For a continuous version of the knapsack problem, the greedy approach provides an optimal solution.
<syntaxhighlight lang="pascal">
program Knapsack;
{$mode delphi}
uses
SysUtils, Math, Generics.Collections, Generics.Defaults;
 
type
TItem = record
Name: string;
Weight, Value, Price: Double;
constructor Make(const n: string; w, v: Double);
end;
 
constructor TItem.Make(const n: string; w, v: Double);
begin
Name := n;
Weight := w;
Value := v;
Price := v/w;
end;
 
function ItemCmp(constref L, R: TItem): Integer;
begin
Result := CompareValue(R.Price, L.Price);
end;
 
var
Items: array of TItem;
MaxWeight: Double;
I: Integer;
begin
Items := [
TItem.Make('beef', 3.8, 36),
TItem.Make('pork', 5.4, 43),
TItem.Make('ham', 3.6, 90),
TItem.Make('greaves', 2.4, 45),
TItem.Make('flitch', 4.0, 30),
TItem.Make('brawn', 2.5, 56),
TItem.Make('welt', 3.7, 67),
TItem.Make('salami', 3.0, 95),
TItem.Make('sausage', 5.9, 98)
];
TArrayHelper<TItem>.Sort(Items, TComparer<TItem>.Construct(ItemCmp));
MaxWeight := 15.0;
I := 0;
repeat
Items[I].Weight := Min(Items[I].Weight, MaxWeight);
MaxWeight := MaxWeight - Items[I].Weight;
WriteLn(Format('%-8s %.1f kg', [Items[I].Name, Items[I].Weight]));
Inc(I);
until (MaxWeight <= 0)or(I = Length(Items));
end.
</syntaxhighlight>
{{out}}
<pre>
salami 3.0 kg
ham 3.6 kg
brawn 2.5 kg
greaves 2.4 kg
welt 3.5 kg
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">my @items = sort { $b->[2]/$b->[1] <=> $a->[2]/$a->[1] }
(
[qw'beef 3.8 36'],
Line 1,499 ⟶ 2,822:
 
print "-" x 40, "\ntotal value: $value\n";
</syntaxhighlight>
</lang>
Output:<pre>item fraction weight value
salami all 3.0 95
Line 1,510 ⟶ 2,833:
</pre>
 
=={{header|Perl 6Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
This Solutions sorts the item by WEIGHT/VALUE
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<lang perl6>class KnapsackItem {
<span style="color: #008080;">constant</span> <span style="color: #000000;">meats</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span>
has $.name;
<span style="color: #000080;font-style:italic;">--Item Weight (kg) Price (Value)</span>
has $.weight is rw;
<span style="color: #0000FF;">{</span><span style="color: #008000;">"beef"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">36</span><span style="color: #0000FF;">},</span>
has $.price is rw;
<span style="color: #0000FF;">{</span><span style="color: #008000;">"pork"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">43</span><span style="color: #0000FF;">},</span>
has $.ppw;
<span style="color: #0000FF;">{</span><span style="color: #008000;">"ham"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">90</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"greaves"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">45</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"flitch"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">30</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"brawn"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">56</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"welt"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">67</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"salami"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">95</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"sausage"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">98</span><span style="color: #0000FF;">}}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">by_weighted_value</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{?,</span><span style="color: #000000;">weighti</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pricei</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">meats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
<span style="color: #0000FF;">{?,</span><span style="color: #000000;">weightj</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pricej</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">meats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pricej</span><span style="color: #0000FF;">/</span><span style="color: #000000;">weightj</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pricei</span><span style="color: #0000FF;">/</span><span style="color: #000000;">weighti</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">by_weighted_value</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">meats</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: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">worth</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</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;">tags</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wi</span><span style="color: #0000FF;">,</span><span style="color: #000000;">price</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">meats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">tags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">amt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">wi</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</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;">"%3.1fkg %s %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">amt</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">amt</span><span style="color: #0000FF;">=</span><span style="color: #000000;">wi</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"(all the)"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"of"</span><span style="color: #0000FF;">),</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">worth</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">amt</span><span style="color: #0000FF;">/</span><span style="color: #000000;">wi</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">price</span>
<span style="color: #000000;">weight</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">amt</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">weight</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</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;">"Total value: %f\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">worth</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
3.0kg (all the) salami
3.6kg (all the) ham
2.5kg (all the) brawn
2.4kg (all the) greaves
3.5kg of welt
Total value: 349.378378
</pre>
 
=={{header|PHP}}==
method new (Str $n, $w, $p) {
<syntaxhighlight lang="php">/* Added by @1x24. Translated from C++. Uses the PHP 7.x spaceship operator */
KnapsackItem.bless(*, :name($n), :weight($w), :price($p), :ppw($w/$p))
$data = }[
[
'name'=>'beef',
'weight'=>3.8,
'cost'=>36,
],
[
'name'=>'pork',
'weight'=>5.4,
'cost'=>43,
],
[
'name'=>'ham',
'weight'=>3.6,
'cost'=>90,
],
[
'name'=>'greaves',
'weight'=>2.4,
'cost'=>45,
],
[
'name'=>'flitch',
'weight'=>4.0,
'cost'=>30,
],
[
'name'=>'brawn',
'weight'=>2.5,
'cost'=>56,
],
[
'name'=>'welt',
'weight'=>3.7,
'cost'=>67,
],
[
'name'=>'salami',
'weight'=>3.0,
'cost'=>95,
],
[
'name'=>'sausage',
'weight'=>5.9,
'cost'=>98,
],
];
 
uasort($data, function($a, $b) {
method cut-maybe ($max-weight) {
return False if ($max-b['cost']/$b['weight']) <=> ($a['cost']/$.a['weight']);
});
$.price = $max-weight / $.ppw;
$.weight = $.ppw * $.price;
return True;
}
 
$limit = 15;
method Str () { sprintf "%8s %1.2f %3.2f",
$.name,
$.weight,
$.price }
}
 
foreach ($data as $item):
my $max-w = 15;
if ($limit >= $item['weight']):
say "Item Portion Value";
echo "Take all the {$item['name']}<br/>";
else:
echo "Take $limit kg of {$item['name']}<br/>";
break;
endif;
$limit -= $item['weight'];
endforeach;
</syntaxhighlight>
Output:
<pre>Take all the salami
Take all the ham
Take all the brawn
Take all the greaves
Take 3.5 kg of welt</pre>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">go =>
items(Items),
weights(Weights),
values(Values),
knapsack_max_weight(MaxWeight),
knapsack(Weights,Values,MaxWeight, X,TotalWeight,TotalValue),
nl,
printf("Total weight: %0.2f Total value: %0.2f\n", TotalWeight,TotalValue),
foreach(I in 1..Items.len)
if X[I] > 0.0 then
printf("%-8w: ",Items[I]),
if X[I] == Weights[I] then
printf("%0.2f (%w)", Weights[I], all)
else
printf("%-0.2f",X[I])
end,
nl
end
end,
nl.
 
knapsack(Weights,Values,MaxWeight, X,TotalWeight,TotalValue) =>
N = Weights.len,
 
X = new_list(N),
X :: 0.0..max(Weights),
 
TotalWeight #= sum(X),
TotalWeight #<= MaxWeight,
foreach(I in 1..N)
X[I] #<= Weights[I]
end,
 
WeightsInv = [1/Weights[I] : I in 1..N],
TotalValue #= sum([X[I]*Values[I]*WeightsInv[I] : I in 1..N]),
 
Vars = X ++ [TotalWeight],
solve($[glpk,max(TotalValue)],Vars).
 
% data
knapsack_max_weight(15.0).
items([beef,pork,ham,greaves,flitch,brawn,welt,salami,sausage]).
weights([3.8,5.4,3.6,2.4,4.0,2.5,3.7,3.0,5.9]).
values([36,43,90,45,30,56,67,95,98]).</syntaxhighlight>
 
{{out}}
<pre>otal weight: 15.00 Total value: 349.38
ham : 3.60 (all)
greaves : 2.40 (all)
brawn : 2.50 (all)
welt : 3.50
salami : 3.00</pre>
 
.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|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(scl 2)
 
(de *Items
Line 1,600 ⟶ 3,040:
NIL
(format (sum cadr K) *Scl)
(format (sum caddr K) *Scl) ) )</langsyntaxhighlight>
Output:
<pre> salami 3.00 95.00
Line 1,608 ⟶ 3,048:
welt 3.50 63.38
15.00 349.38</pre>
 
=={{header|PL/I}}==
<langsyntaxhighlight lang="pli">*process source xref attributes;
KNAPSACK_CONTINUOUS: Proc Options(main);
/*--------------------------------------------------------------------
Line 1,683 ⟶ 3,124:
item(i).value = value;
End;
End;</langsyntaxhighlight>
{{out}}
<pre>
Line 1,707 ⟶ 3,148:
=={{header|Prolog}}==
Works with SWI-Prolog and <b>library(simplex)</b> written by <b>Markus Triska</b>
<langsyntaxhighlight Prologlang="prolog">:- use_module(library(simplex)).
% tuples (name, weights, value).
knapsack :-
Line 1,773 ⟶ 3,214:
print_results(S, A1, A2, A3, T, TN, W2, V2).
 
</syntaxhighlight>
</lang>
Output :
<pre> ?- knapsack.
Line 1,786 ⟶ 3,227:
=={{header|PureBasic}}==
Using the greedy algorithm.
<langsyntaxhighlight PureBasiclang="purebasic">Structure item
name.s
weight.f ;units are kilograms (kg)
Line 1,857 ⟶ 3,298:
Input()
CloseConsole()
EndIf </langsyntaxhighlight>
Sample output:
<pre>Maximal weight = 15 kg
Line 1,872 ⟶ 3,313:
=={{header|Python}}==
I think this greedy algorithm of taking the largest amounts of items ordered by their value per unit weight is maximal:
<langsyntaxhighlight lang="python"># NAME, WEIGHT, VALUE (for this weight)
items = [("beef", 3.8, 36.0),
("pork", 5.4, 43.0),
Line 1,901 ⟶ 3,342:
print(" ITEM PORTION VALUE")
print("\n".join("%10s %6.2f %6.2f" % item for item in bagged))
print("\nTOTAL WEIGHT: %5.2f\nTOTAL VALUE: %5.2f" % (wt, val))</langsyntaxhighlight>
 
'''Sample Output'''
Line 1,913 ⟶ 3,354:
TOTAL WEIGHT: 15.00
TOTAL VALUE: 349.38</pre>
 
=={{header|R}}==
Translated into r-script by Shana White (vandersm@mail.uc.edu) from pseudocode found in 'Algorithms: Sequential Parallel and Distributed', by Kenneth A. Berman and Jerome L. Paul
<syntaxhighlight lang="r">
knapsack<- function(Value, Weight, Objects, Capacity){
Fraction = rep(0, length(Value))
Cost = Value/Weight
#print(Cost)
W = Weight[order(Cost, decreasing = TRUE)]
Obs = Objects[order(Cost, decreasing = TRUE)]
Val = Value[order(Cost, decreasing = TRUE)]
#print(W)
RemainCap = Capacity
i = 1
n = length(Cost)
if (W[1] <= Capacity){
Fits <- TRUE
}
else{
Fits <- FALSE
}
while (Fits && i <= n ){
Fraction[i] <- 1
RemainCap <- RemainCap - W[i]
i <- i+1
#print(RemainCap)
if (W[i] <= RemainCap){
Fits <- TRUE
}
else{
Fits <- FALSE
}
}
#print(RemainCap)
if (i <= n){
Fraction[i] <- RemainCap/W[i]
}
names(Fraction) = Obs
Quantity_to_take = W*Fraction
Total_Value = sum(Val*Fraction)
print("Fraction of available quantity to take:")
print(round(Fraction, 3))
print("KG of each to take:")
print(Quantity_to_take)
print("Total value of tasty meats:")
print(Total_Value)
}</syntaxhighlight>
 
'''Sample Input'''
<pre>o = c("beef", "pork", "ham", "greaves", "flitch", "brawn", "welt", "salami", "sausage")
w = c(3.8,5.4,3.6,2.4,4.0,2.5,3.7,3.0,5.9)
v = c(36,43,90,45,30,56,67,95,98)
knapsack(v, w, o, 15)</pre>
 
'''Sample Output'''
<pre>
[1] "Fraction of available quantity to take:"
salami ham brawn greaves welt sausage beef pork flitch
1.000 1.000 1.000 1.000 0.946 0.000 0.000 0.000 0.000
[1] "KG of each to take:"
salami ham brawn greaves welt sausage beef pork flitch
3.0 3.6 2.5 2.4 3.5 0.0 0.0 0.0 0.0
[1] "Total value of tasty meats:"
[1] 349.3784</pre>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">#lang racket
(define shop-inventory
'((beef 3.8 36)
Line 1,960 ⟶ 3,465:
 
(call-with-values (lambda () (continuous-knapsack shop-inventory null 15 0))
report-knapsack)</langsyntaxhighlight>
 
{{out}}
Line 1,970 ⟶ 3,475:
Take 3.50 of the welt (for 63.38)
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
<syntaxhighlight lang="raku" line>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;
}</syntaxhighlight>
'''Output:'''
<pre>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}}==
===version 1===
Originally used the Fortran program as a prototype.
<br>Some amount of code was added to makeformat the output prettybetter.
<langsyntaxhighlight lang="rexx">/*REXX programpgm solves the continuous burglar's knapsack problem; items (continuous)with weight problem.and value*/
@.= /*═══════ name weight value ══════*/
@.1 = 'flitch 4 30 '
@.2 = 'beef 3.8 36 '
@.3 = 'pork 5.4 43 '
@.4 = 'greaves 2.4 45 '
@.5 = 'brawn 2.5 56 '
@.6 = 'welt 3.7 67 '
@.7 = 'ham 3.6 90 '
@.8 = 'salami 3 95 '
@.9 = 'sausage 5.9 98 '
parse arg maxW ddigd . /*get possible argsarguments from the C.L. */
if maxW=='' | maxW=='",'" then maxW=15 /*the burglar's knapsack maxmaximum weight. */
if ddig d=='' | ddig d=='",'" then ddig d= 23 /*# of decimal digits inshown with FORMAT. */
wL=d+length(' weight '); nL=d+length('"total weight'"); vL=d+length(' value ') /*lengths*/
totW=0; totV=0 /* [↓] assign item to separate lists. */
totW=0; totV=0
do j#=1 while @.j#\==''; parse var @.j# n.j# w.j# v.j# .; end; #=#-1
call show 'unsorted item list' end /*j*/display the header and the @ /* [↑] assign to separate listslist.*/
items=j-1call sortD /*ITEMS:invoke thedescemdomg #sort offor: items inn. @w. listv.*/
call hdr "burglar's knapsack contents"
call show 'unsorted item list' /*display a header and the @ list*/
do j=1 for # while totW<maxW; f=1 /*process [↓]the sort is OK foritems. short lists*/
do sorts=2 to items if totW+w.j>=maxW then f=(maxW-totW)/w.j /*sort: descending value/unit*calculate wtfraction. */
totW=totW+w.j*f; totV=totV+v.j*f /*add it ───► totals. */
_n=n.sorts; _w=w.sorts; _v=v.sorts /*calc. placeholders for DO loop.*/
do k=sorts-1 by -1 to 1call syf while left(word('{all}',1+(f\==1)),5) v.k/w.k < _v/_wn.j, /w.j*orderf, it v.j*/f
kp=k+1; n.kp=n.k;end /*j*/ w.kp=w.k; v.kp=v.k /*shuffle. [↑] display item, maybe with {all} */
call sep; say /* [↓] $ suppresses trailing zeroes.*/
end /*k*/
call sy left('total weight', nL, "─"), $(format(totW,,d))
kp=k+1; n.kp=_n; w.kp=_w; v.kp=_v
call sy left('total value', nL, "─"), , $(format(totV,,d))
end /*sorts*/
exit /*stick a fork in it, we're all done. */
 
/*──────────────────────────────────────────────────────────────────────────────────────*/
call hdr "burglar's knapsack contents"
sortD: do s=2 to #; a=n.s; !=w.s; u=v.s /* [↓] this is a descending sort. do j=1 for items while totW < maxW; f=1*/
do k=s-1 by -1 to 1 while v.k/w.k<u/!; ?=k+1; n.?=n.k; if totW+w.j>?=maxWw.k; then fv.?=(maxW-totW)/wv.jk; end
?=k+1; n.?=a; totW=totW+w.j*f?=!; totV=totV+v.j*f?=u
end /*s*/; return call syf n.j, w.j /*f, ↑↑↑ algorithm is OK for small v.jarrays*f/
/*──────────────────────────────────────────────────────────────────────────────────────*/
end /*j*/
hdr: say; say; say center(arg(1),50,'─'); say; call title; call sep; return
call sep
sep: call sy copies('═', nL), copies("═", wL), copies('═', vL); return
call sy left('total weight',nL,'─'), format(totW,,ddig)
show: call syhdr leftarg('total1); value',nL,'─'), do j=1 for #; call syf n.j, format(totVw.j,,ddig) v.j; end; return
sy: say left('',9) left(arg(1),nL) right(arg(2),wL) right(arg(3),vL); return
exit /*stick a fork in it, we're done.*/
syf: call sy arg(1), $(format(arg(2), , d)), $(format(arg(3), , d)); return
/*──────────────────────────────────one─liner subroutines────────────────────*/
hdrtitle: call say; saysy center(arg(1),50,'item',nL);, center("weight", say;wL), center('value', call titlevL); call sep; return
$: parse arg x;if pos(.,x)>1 then x=left(strip(strip(x,'T',0),,.),length(x)); return x</syntaxhighlight>
sep: call sy copies('═',nL), copies("═",wL), copies('═',vL); return
'''output''' &nbsp; using the default inputs of: &nbsp; <tt> 15 &nbsp; 3 </tt>
show: call hdr arg(1); do j=1 for items; call syf n.j,w.j,v.j;end; say; return
<pre>
sy: say left('',9) left(arg(1),nL) right(arg(2),wL) right(arg(3),vL); return
syf: call sy arg(1), format(arg(2),,ddig), format(arg(3),,ddig); return
title: call sy center('item',nL),center("weight",wL),center('value',vL); return</lang>
'''output''' using the default inputs of: &nbsp; <tt> 15 2 </tt>
<pre style="height:50ex">
────────────────unsorted item list────────────────
 
item weight value
═══════════════ ═════════ ════════
════════════ ════════ ═══════
flitch 4.00 30.00
beef 3.808 36.00
pork 5.404 43.00
greaves 2.404 45.00
brawn 2.505 56.00
welt 3.707 67.00
ham 3.606 90.00
salami 3.00 95.00
sausage 5.909 98.00
 
 
───────────burglar's knapsack contents────────────
 
item weight value
═══════════════ ═════════ ════════
════════════ ════════ ═══════
{all} salami 3 3.00 95.00
{all} ham 3.6 3.60 90.00
{all} brawn 2.5 2.50 56.00
{all} greaves 2.4 2.40 45.00
welt welt 3.505 63.38378
═══════════════ ═════════ ════════
════════════ ════════ ═══════
 
total weight 15.00
total weight─── value 349.3815
total value─── 349.378
</pre>
 
===version 2===
<langsyntaxhighlight lang="rexx"> /*--------------------------------------------------------------------
* 19.09.2014 Walter Pachl translated from FORTRAN
* While this program works with all REXX interpreters,
Line 2,129 ⟶ 3,687:
input.i=name'*'weight'*'value
input.0=i
Return</langsyntaxhighlight>
{{out}}
<pre># vpu name weight value
Line 2,150 ⟶ 3,708:
-----------------------
total 15.000 349.378</pre>
 
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">items = [ [:beef , 3.8, 36],
<lang ruby>
[:pork , 5.4, 43],
# Solve Continuous Knapsdack Problem
[:ham , 3.6, 90],
#
[:greaves, 2.4, 45],
# Nigel_Galloway
[:flitch , 4.0, 30],
# September 8th., 2014.
[:brawn , 2.5, 56],
maxW, value = 15, 0
{:beef => [:welt , 3.87,36 67],
:pork => [5:salami , 3.40,43 95],
[:sausage, 5.9, 98] ].sort_by{|item, weight, price| -price / weight}
:ham => [3.6,90],
maxW, value = 15.0, 0
:greaves => [2.4,45],
items.each do |item, weight, price|
:flitch => [4.0,30],
if (maxW -= weight) > 0
:brawn => [2.5,56],
puts "Take all #{item}"
:welt => [3.7,67],
value += price
:salami => [3.0,95],
:sausage => [5.9,98]}.sort_by{|n,g| -1*g[1]/g[0]}.each{|n,g|
if (maxW-=g[0]) > 0
puts "Take all #{n}"
value += g[1]
else
puts "Take #{t=g[0]+maxW}kg #{n}\n\nTotal value%gkg of swag%s" is% #{value[t=weight+(g[1maxW, item]/g[0])*t}, "",
"Total value of swag is %g" % (value+(price/weight)*t)
break
end
end</syntaxhighlight>
}
</lang>
{{out}}
<pre>
Line 2,183 ⟶ 3,736:
Take all brawn
Take all greaves
Take 3.5kg of welt
 
Total value of swag is 349.378378378378378
</pre>
 
=={{header|Run BASIC}}==
{{incorrect|Run BASIC}}
<lang runbasic>dim name$(9)
<syntaxhighlight lang="runbasic">dim name$(9)
dim wgt(9)
dim price(9)
Line 2,245 ⟶ 3,799:
print "-------- Total ";using("###.#",totTake);chr$(9);"Weight: ";totWgt
end if
next i</langsyntaxhighlight>Output:
<pre>Best 2 Options
 
Line 2,254 ⟶ 3,808:
salami Value: 475.0 Weight: 15.0
-------- Total 475.0 Weight: 15.0</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn main() {
let items: [(&str, f32, u8); 9] = [
("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),
];
let mut weight: f32 = 15.0;
let mut values: Vec<(&str, f32, f32)> = Vec::new();
for item in &items {
values.push((item.0, f32::from(item.2) / item.1, item.1));
}
 
values.sort_by(|a, b| (a.1).partial_cmp(&b.1).unwrap());
values.reverse();
 
for choice in values {
if choice.2 <= weight {
println!("Grab {:.1} kgs of {}", choice.2, choice.0);
weight -= choice.2;
if (choice.2 - weight).abs() < std::f32::EPSILON {
return;
}
} else {
println!("Grab {:.1} kgs of {}", weight, choice.0);
return;
}
}
}</syntaxhighlight> Output:<pre>
Grab 3.0 kgs of salami
Grab 3.6 kgs of ham
Grab 2.5 kgs of brawn
Grab 2.4 kgs of greaves
Grab 3.5 kgs of welt
</pre>
 
=={{header|SAS}}==
Use LP solver in SAS/OR:
<syntaxhighlight lang="sas">/* create SAS data set */
data mydata;
input item $ weight value;
datalines;
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
;
 
/* call OPTMODEL procedure in SAS/OR */
proc optmodel;
/* declare sets and parameters, and read input data */
set <str> ITEMS;
num weight {ITEMS};
num value {ITEMS};
read data mydata into ITEMS=[item] weight value;
 
/* declare variables, objective, and constraints */
var WeightSelected {i in ITEMS} >= 0 <= weight[i];
max TotalValue = sum {i in ITEMS} (value[i]/weight[i]) * WeightSelected[i];
con WeightCon:
sum {i in ITEMS} WeightSelected[i] <= 15;
 
/* call linear programming (LP) solver */
solve;
 
/* print optimal solution */
print TotalValue;
print {i in ITEMS: WeightSelected[i].sol > 1e-3} WeightSelected;
quit;</syntaxhighlight>
 
Output:
<pre>TotalValue
349.38
 
[1] WeightSelected
brawn 2.5
greaves 2.4
ham 3.6
salami 3.0
welt 3.5 </pre>
 
=={{header|Scala}}==
===Functional approach (Tail recursive)===
<syntaxhighlight lang="scala">import scala.annotation.tailrec
 
object ContinousKnapsackForRobber extends App {
val MaxWeight = 15.0
val items = Seq(
Item("Beef", 3.8, 3600),
Item("Pork", 5.4, 4300),
Item("Ham", 3.6, 9000),
Item("Greaves", 2.4, 4500),
Item("Flitch", 4.0, 3000),
Item("Brawn", 2.5, 5600),
Item("Welt", 3.7, 6700),
Item("Salami", 3.0, 9500),
Item("Sausage", 5.9, 9800))
 
// sort items by value per unit weight in descending order
def sortedItems = items.sortBy(it => -it.value / it.weight)
 
@tailrec
def packer(notPacked: Seq[Item], packed: Lootsack): Lootsack = {
 
if (!packed.isNotFull || notPacked.isEmpty) packed
else {
val try2fit = packed.copy(bagged = notPacked.head +: packed.bagged)
if (try2fit.isNotFull) packer(notPacked.tail, try2fit)
else {
try2fit.copy(lastPiece = packed.weightLeft / notPacked.head.weight)
}
}
}
 
case class Item(name: String, weight: Double, value: Int)
 
case class Lootsack(bagged: Seq[Item], lastPiece: Double = 1.0) {
private val totWeight = if (bagged.isEmpty) 0.0
else bagged.tail.map(_.weight).sum + bagged.head.weight * lastPiece
 
def isNotFull: Boolean = weightLeft > 0
 
def weightLeft: Double = MaxWeight - totWeight
 
override def toString = f"${show(bagged, lastPiece)}Totals: weight: $totWeight%4.1f, value: $totValue%6.2f"
 
private def totValue: BigDecimal = if (bagged.isEmpty) 0.0
else (bagged.tail.map(_.value).sum + bagged.head.value * lastPiece) / 100
 
private def show(is: Seq[Item], percentage: Double) = {
def toStr(is: Seq[Item], percentage: Double = 1): String =
is.map(it => f"${percentage * 100}%6.2f%% ${it.name}%-7s ${
it.weight * percentage}%4.1f ${it.value * percentage / 100}%6.2f\n").mkString
 
toStr(is.tail.reverse) + toStr(Seq(is.head), percentage)
}
}
 
println(packer(sortedItems, Lootsack(Nil)))
}</syntaxhighlight>
{{Out}}
<pre>100.00% Salami 3.0 95.00
100.00% Ham 3.6 90.00
100.00% Brawn 2.5 56.00
100.00% Greaves 2.4 45.00
94.59% Welt 3.5 63.38
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)]-->.
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">var 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],
].sort {|a,b| b[2]/b[1] <=> a[2]/a[1] }
 
var (limit, value) = (15, 0);
print "Item Fraction Weight Value\n";
 
items.each { |item|
var ratio = (item[1] > limit ? limit/item[1] : 1);
value += item[2]*ratio;
limit -= item[1];
if (ratio == 1) {
printf("%-8s %4s %7.2f %6.2f\n", item[0], 'all', item[1], item[2]);
}
else {
printf("%-8s %-4.2f %7.2f %6.2f\n", item[0], ratio, item[1]*ratio, item[2]*ratio);
break;
}
}
 
say "#{'-'*28}\ntotal value: #{'%.14g' % value }"</syntaxhighlight>
{{out}}
<pre>
Item Fraction Weight Value
salami   all  3.00  95.00
ham   all  3.60  90.00
brawn   all  2.50  56.00
greaves   all  2.40  45.00
welt  0.95  3.50  63.38
----------------------------
total value: 349.37837837838
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# Uses the trivial greedy algorithm
Line 2,292 ⟶ 4,050:
# We return the total value too, purely for convenience
return [list $result $totalValue]
}</langsyntaxhighlight>
Driver for this particular problem:
<langsyntaxhighlight lang="tcl">set items {
{beef 3.8 36}
{pork 5.4 43}
Line 2,312 ⟶ 4,070:
lassign $item name mass value
puts [format "\t%.1fkg of %s, value %.2f" $mass $name $value]
}</langsyntaxhighlight>
Output:
<pre>
Line 2,329 ⟶ 4,087:
[http://www.gnu.org/software/glpk/glpk.html glpk] depending on the
[http://www.basis.netii.net/avram run-time system] configuration).
<langsyntaxhighlight Ursalalang="ursala">#import flo
#import lin
 
Line 2,355 ⟶ 4,113:
#cast %em
 
main = solution system items</langsyntaxhighlight>
output:
<pre><
Line 2,363 ⟶ 4,121:
'salami ': 3.000000e+00,
'welt ': 3.500000e+00></pre>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="v (vlang)">struct Item {
item string
weight f64
price f64
}
 
fn main(){
mut left := 15.0
mut items := [
Item{'beef', 3.8, 36},
Item{'pork', 5.4, 43},
Item{'ham', 3.6, 90},
Item{'greaves', 2.4, 45},
Item{'flitch', 4.0, 30},
Item{'brawn', 2.5, 56},
Item{'welt', 3.7, 67},
Item{'salami', 3.0, 95},
Item{'sausage', 5.9, 98}
]
items.sort_with_compare(fn (a &Item, b &Item) int {
if a.weight/a.price < b.weight/b.price {
return -1
} else if a.weight/a.price > b.weight/b.price {
return 1
} else {
return 0
}
})
for item in items {
if item.weight <= left {
println('Take all the $item.item')
if item.weight == left {
return
}
left -= item.weight
} else {
println('Take ${left:.1}kg $item.item')
return
}
}
//println(items)
}</syntaxhighlight>
{{out}}
<pre>
take all the salami
take all the ham
take all the brawn
take all the greaves
take 3.5kg welt
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
{{libheader|Wren-math}}
{{libheader|Wren-sort}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
import "./math" for Math
import "./sort" for Sort
 
class Item {
construct new(name, weight, value) {
_name = name
_weight = weight
_value = value
}
 
name { _name }
weight { _weight }
value { _value }
}
 
var items = [
Item.new("beef", 3.8, 36),
Item.new("pork", 5.4, 43),
Item.new("ham", 3.6, 90),
Item.new("greaves", 2.4, 45),
Item.new("flitch", 4, 30),
Item.new("brawn", 2.5, 56),
Item.new("welt", 3.7, 67),
Item.new("salami", 3.0, 95),
Item.new("sausage", 5.9, 98)
]
 
var maxWeight = 15
// sort items by value per unit weight in descending order
var cmp = Fn.new { |i, j| (j.value/j.weight - i.value/i.weight).sign }
Sort.insertion(items, cmp)
System.print("Item Chosen Weight Value Percentage")
System.print("----------- ------ ------ ----------")
var w = maxWeight
var itemCount = 0
var sumValue = 0
for (item in items) {
itemCount = itemCount + 1
if (item.weight <= w) {
sumValue = sumValue + item.value
Fmt.print("$-11s $3.1f $5.2f 100.00", item.name, item.weight, item.value)
} else {
var value = Math.toPlaces(w / item.weight * item.value, 2)
var percentage = Math.toPlaces(w / item.weight * 100, 2)
sumValue = sumValue + value
Fmt.print("$-11s $3.1f $5.2f $6.2f", item.name, w, value, percentage)
break
}
w = w - item.weight
if (w == 0) break
}
System.print("----------- ------ ------")
Fmt.print("$d items 15.0 $6.2f", itemCount, sumValue)</syntaxhighlight>
 
{{out}}
<pre>
Item Chosen Weight Value Percentage
----------- ------ ------ ----------
salami 3.0 95.00 100.00
ham 3.6 90.00 100.00
brawn 2.5 56.00 100.00
greaves 2.4 45.00 100.00
welt 3.5 63.38 94.59
----------- ------ ------
5 items 15.0 349.38
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">int Name, Price, I, BestItem;
real Weight, Best, ItemWt, TotalWt;
def Items = 9;
Line 2,394 ⟶ 4,277:
Text(0, Name(BestItem)); CrLf(0);
until TotalWt >= 15.0; \all we can steal
]</langsyntaxhighlight>
 
Output:
Line 2,404 ⟶ 4,287:
3.5 kg of welt
</pre>
 
=={{header|zkl}}==
{{trans|C}}
<syntaxhighlight lang="zkl">items:=List( T(3.8, 36.0, "beef"), T(5.4, 43.0, "pork"), // weight, value, name
T(3.6, 90.0, "ham"), T(2.4, 45.0, "greaves"),
T(4.0, 30.0, "flitch"),T(2.5, 56.0, "brawn"),
T(3.7, 67.0, "welt"), T(3.0, 95.0, "salami"),
T(5.9, 98.0, "sausage"),
);
fcn item_cmp(a,b){ a[1]/a[0] > b[1]/b[0] }
items.sort(item_cmp);
space := 15.0;
foreach it in (items){ w,_,nm:=it;
if (space >= w){ println("take all ",nm); space-=w }
else{ println("take %gkg of %gkg of %s".fmt(space,w,nm)); break }
}</syntaxhighlight>
{{out}}
<pre>
take all salami
take all ham
take all brawn
take all greaves
take 3.5kg of 3.7kg of welt
</pre>
 
 
[[Category:Puzzles]]
9,476

edits