Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Knapsack_problem/Continuous
note: Classic CS problems and programs

View file

@ -0,0 +1,49 @@
A thief burgles a butcher's shop, where he can select from some items.
The thief 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.
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);"
! Item !! Weight (kg) !! Price (Value)
|-
| 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
|- style="background-color: rgb(255, 204, 255);"
| Knapsack || <=15 kg || ?
|}
<br>
;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.
;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>

View file

@ -0,0 +1,29 @@
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))

View file

@ -0,0 +1,42 @@
# 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)
}

View file

@ -0,0 +1,102 @@
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;
Weight : Float;
Value : Positive;
Taken : Float;
end record;
function "<" (Left, Right : Item) return Boolean is
begin
return Float (Left.Value) / Left.Weight <
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).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;
Weight_Limit : Float)
is
begin
-- order items by value per weight unit
Sorting : declare
An_Item : Item;
J : Natural;
begin
for I in Items'First + 1 .. Items'Last loop
An_Item := Items (I);
J := I - 1;
while J in Items'Range and then Items (J) < An_Item loop
Items (J + 1) := Items (J);
J := J - 1;
end loop;
Items (J + 1) := An_Item;
end loop;
end Sorting;
declare
Rest : Float := Weight_Limit;
begin
for I in Items'Range loop
if Items (I).Weight <= Rest then
Items (I).Taken := Items (I).Weight;
else
Items (I).Taken := Rest;
end if;
Rest := Rest - Items (I).Taken;
exit when Rest <= 0.0;
end loop;
end;
end Solve_Knapsack_Continuous;
All_Items : Item_Array :=
((US.To_Unbounded_String ("beef"), 3.8, 36, 0.0),
(US.To_Unbounded_String ("pork"), 5.4, 43, 0.0),
(US.To_Unbounded_String ("ham"), 3.6, 90, 0.0),
(US.To_Unbounded_String ("greaves"), 2.4, 45, 0.0),
(US.To_Unbounded_String ("flitch"), 4.0, 30, 0.0),
(US.To_Unbounded_String ("brawn"), 2.5, 56, 0.0),
(US.To_Unbounded_String ("welt"), 3.7, 67, 0.0),
(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 ("Total Weight: ");
Ada.Float_Text_IO.Put (Total_Weight (All_Items), 0, 2, 0);
Ada.Text_IO.New_Line;
Ada.Text_IO.Put ("Total Value: ");
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 (" ");
Ada.Float_Text_IO.Put (All_Items (I).Taken, 0, 2, 0);
Ada.Text_IO.Put_Line (" of " & US.To_String (All_Items (I).Name));
end if;
end loop;
end Knapsack_Continuous;

View file

@ -0,0 +1,39 @@
INSTALL @lib$+"SORTSALIB"
Sort% = FN_sortSAinit(1, 0) : REM Descending
nItems% = 9
maxWeight = 15.0
DIM items{(nItems%-1) name$, weight, price, worth}
FOR item% = 0 TO nItems%-1
READ items{(item%)}.name$, items{(item%)}.weight, items{(item%)}.price
items{(item%)}.worth = items{(item%)}.price / items{(item%)}.weight
NEXT
DATA "beef", 3.8, 36, "pork", 5.4, 43, "ham", 3.6, 90
DATA "greaves", 2.4, 45, "flitch", 4.0, 30, "brawn", 2.5, 56
DATA "welt", 3.7, 67, "salami", 3.0, 95, "sausage", 5.9, 98
C% = nItems% : D% = 0
CALL Sort%, items{()}, items{(0)}.worth
TotalWeight = 0
TotalPrice = 0
FOR i% = 0 TO nItems%-1
IF TotalWeight + items{(i%)}.weight < maxWeight THEN
TotalWeight += items{(i%)}.weight
TotalPrice += items{(i%)}.price
PRINT "Take all the " items{(i%)}.name$
ELSE
weight = maxWeight - TotalWeight
price = weight * items{(i%)}.worth
TotalWeight += weight
TotalPrice += price
PRINT "Take "; weight " kg of " items{(i%)}.name$
EXIT FOR
ENDIF
NEXT
PRINT '"Total weight = " ; TotalWeight " kg"
PRINT "Total price = " ; TotalPrice
END

View file

@ -0,0 +1,15 @@
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

View file

@ -0,0 +1,50 @@
( ( fixed {function to convert a rational number to fixed point notation.
The second argument is the number of decimals. }
= value decimals powerOf10
. !arg:(?value.?decimals)
& 10^!decimals:?powerOf10
& str
$ ( div$(!value.1)
"."
mod
$ (div$(!value+1/2*!powerOf10^-1.!powerOf10^-1).!powerOf10)
)
)
& (beef.38/10.36)
(pork.54/10.43)
(ham.36/10.90)
(greaves.24/10.45)
(flitch.40/10.30)
(brawn.25/10.56)
(welt.37/10.67)
(salami.30/10.95)
(sausage.59/10.98)
: ?items
& 0:?sorteditems
& whl
' ( !items:(?name.?mass.?price) ?items
& (!mass*!price^-1.!mass.!name)+!sorteditems:?sorteditems
)
& 0:?totalMass
& :?stolenItems
& whl
' ( !sorteditems:(?massPerPriceunit.?mass.?name)+?sorteditems
& (!mass.!massPerPriceunit.!name) !stolenItems
: ?stolenItems
& !mass+!totalMass:?totalMass:~>15
)
& !stolenItems:(?mass.?massPerPriceunit.?name) ?stolenItems
& 15+!mass+-1*!totalMass:?mass
& (!mass.!massPerPriceunit.!name) !stolenItems:?stolenItems
& 0:?totalPrice
& ( !stolenItems
: ?
( (?mass.?massPerPriceunit.?name)
& out$(fixed$(!mass.1) "kg of" !name)
& !mass*!massPerPriceunit^-1+!totalPrice:?totalPrice
& ~
)
?
| out$(fixed$(!totalPrice.2))
)
);

View file

@ -0,0 +1,95 @@
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
double result;
double capacity = 15;
int NumberOfItems;
int number;
struct items
{
char name[32];
double weight;
double price;
double m;
} item[256];
bool cmp(items a,items b)
{
return a.price/a.weight > b.price/b.weight; // the compare function for the sorting algorithm
}
int main()
{
NumberOfItems=9;
strcpy(item[1].name,"beef");
item[1].weight=3.8;
item[1].price=36;
strcpy(item[2].name,"pork");
item[2].weight=5.4;
item[2].price=43;
strcpy(item[3].name,"ham");
item[3].weight=3.6;
item[3].price=90;
strcpy(item[4].name,"greaves");
item[4].weight=2.4;
item[4].price=45;
strcpy(item[5].name,"flitch");
item[5].weight=4.0;
item[5].price=30;
strcpy(item[6].name,"brawn");
item[6].weight=2.5;
item[6].price=56;
strcpy(item[7].name,"welt");
item[7].weight=3.7;
item[7].price=67;
strcpy(item[8].name,"salami");
item[8].weight=3.0;
item[8].price=95;
strcpy(item[9].name,"sausage");
item[9].weight=5.9;
item[9].price=98;
sort(item+1,item+NumberOfItems+1,cmp); // We'll sort using Introsort from STL
number = 1;
while(capacity>0&&number<=NumberOfItems)
{
if(item[number].weight<=capacity)
{
result+=item[number].price;
capacity-=item[number].weight;
item[number].m=1;
}
else
{
result+=(item[number].price)*(capacity/item[number].weight);
item[number].m=(capacity/item[number].weight);
capacity=0;
}
++number;
}
cout<<"Total Value = "<<result<<'\n';
cout<<"Total Weight = "<<(double)15-capacity<<'\n';
cout<<"Items Used:\n";
for(int i=1;i<=NumberOfItems;++i)
if(item[i].m)
{
cout<<"We took "<<item[i].m*item[i].weight<<"kg of \""<<item[i].name<<"\" and the value it brought is "<<item[i].price*item[i].m<<"\n";
}
return 0;
}

View file

@ -0,0 +1,53 @@
// C++11 version
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
struct item_type
{
double weight, value;
string name;
};
vector< item_type > items =
{
{ 3.8, 36, "beef" },
{ 5.4, 43, "pork" },
{ 3.6, 90, "ham" },
{ 2.4, 45, "greaves" },
{ 4.0, 30, "flitch" },
{ 2.5, 56, "brawn" },
{ 3.7, 67, "welt" },
{ 3.0, 95, "salami" },
{ 5.9, 98, "sausage" }
};
int main()
{
sort
(
begin( items ), end( items ),
[] (const item_type& a, const item_type& b)
{
return a.value / a.weight > b.value / b.weight;
}
);
double space = 15;
for ( const auto& item : items )
{
if ( space >= item.weight )
cout << "Take all " << item.name << endl;
else
{
cout << "Take " << space << "kg of " << item.name << endl;
break;
}
space -= item.weight;
}
}

View file

@ -0,0 +1,33 @@
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"};
}

View file

@ -0,0 +1,33 @@
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"};
}

View file

@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
struct item { double w, v; const char *name; } items[] = {
{ 3.8, 36, "beef" },
{ 5.4, 43, "pork" },
{ 3.6, 90, "ham" },
{ 2.4, 45, "greaves" },
{ 4.0, 30, "flitch" },
{ 2.5, 56, "brawn" },
{ 3.7, 67, "welt" },
{ 3.0, 95, "salami" },
{ 5.9, 98, "sausage" },
};
int item_cmp(const void *aa, const void *bb)
{
const struct item *a = aa, *b = bb;
double ua = a->v / a->w, ub = b->v / b->w;
return ua < ub ? -1 : ua > ub;
}
int main()
{
struct item *it;
double space = 15;
qsort(items, 9, sizeof(struct item), item_cmp);
for (it = items + 9; it---items && space > 0; space -= it->w)
if (space >= it->w)
printf("take all %s\n", it->name);
else
printf("take %gkg of %g kg of %s\n",
space, it->w, it->name);
return 0;
}

View file

@ -0,0 +1,48 @@
; 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)

View file

@ -0,0 +1,24 @@
(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)

View file

@ -0,0 +1,28 @@
(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))))

View file

@ -0,0 +1,48 @@
import std.stdio, std.algorithm, std.string;
struct Item {
string name;
real amount, value;
@property real valuePerKG() @safe const pure nothrow @nogc {
return value / amount;
}
string toString() const pure /*nothrow*/ @safe {
return format("%10s %7.2f %7.2f %7.2f",
name, amount, value, valuePerKG);
}
}
real sumBy(string field)(in Item[] items) @safe pure nothrow @nogc {
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),
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)]
.schwartzSort!(it => -it.valuePerKG)
.release;
immutable(Item)[] chosen;
real space = 15.0;
foreach (const item; items)
if (item.amount < space) {
chosen ~= item;
space -= item.amount;
} else {
chosen ~= Item(item.name, space, item.valuePerKG * space);
break;
}
writefln("%10s %7s %7s %7s", "ITEM", "AMOUNT", "VALUE", "$/unit");
writefln("%(%s\n%)", chosen);
Item("TOTAL", chosen.sumBy!"amount", chosen.sumBy!"value").writeln;
}

View file

@ -0,0 +1,26 @@
void main() {
import std.stdio, std.algorithm;
static struct T { string item; double weight, price; }
auto items = [T("beef", 3.8, 36.0),
T("pork", 5.4, 43.0),
T("ham", 3.6, 90.0),
T("greaves", 2.4, 45.0),
T("flitch", 4.0, 30.0),
T("brawn", 2.5, 56.0),
T("welt", 3.7, 67.0),
T("salami", 3.0, 95.0),
T("sausage", 5.9, 98.0)]
.schwartzSort!q{ -a.price / a.weight };
auto left = 15.0;
foreach (it; items)
if (it.weight <= left) {
writeln("Take all the ", it.item);
if (it.weight == left)
return;
left -= it.weight;
} else
return writefln("Take %.1fkg %s", left, it.item);
}

View file

@ -0,0 +1,92 @@
{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;

View file

@ -0,0 +1,36 @@
(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))

View file

@ -0,0 +1,71 @@
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

View file

@ -0,0 +1,36 @@
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 )

View file

@ -0,0 +1,32 @@
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 )

View file

@ -0,0 +1,36 @@
-module( knapsack_problem_continuous ).
-export( [price_per_weight/1, select/2, task/0] ).
price_per_weight( Items ) -> [{Name, Weight, Price / Weight} || {Name, Weight, Price} <-Items].
select( Max_weight, Items ) ->
{_Remains, Selected_items} = lists:foldr( fun select_until/2, {Max_weight, []}, lists:keysort(3, Items) ),
Selected_items.
task() ->
Items = items(),
io:fwrite( "The robber takes the following to maximize the value~n" ),
[io:fwrite("~.2f of ~p~n", [Weight, Name]) || {Name, Weight} <- select( 15, price_per_weight(Items) )].
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}
].
select_until( {Name, Weight, _Price}, {Remains, Acc} ) when Remains > 0 ->
Selected_weight = select_until_weight( Weight, Remains ),
{Remains - Selected_weight, [{Name, Selected_weight} | Acc]};
select_until( _Item, Acc ) -> Acc.
select_until_weight( Weight, Remains ) when Weight < Remains -> Weight;
select_until_weight( _Weight, Remains ) -> Remains.

View file

@ -0,0 +1,17 @@
//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)

View file

@ -0,0 +1,39 @@
include lib/selcsort.4th \ use a tiny sorting algorithm
150 value left \ capacity in 1/10th kilo
create items \ list of items
," beef" 38 , 3600 , \ description, weight, price (cents)
," pork" 54 , 4300 , \ weight in 1/10 kilo
," ham" 36 , 9000 ,
," greaves" 24 , 4500 ,
," flitch" 40 , 3000 ,
," brawn" 25 , 5600 ,
," welt" 37 , 6700 ,
," salami" 30 , 9500 ,
," sausage" 59 , 9800 ,
here items - 3 / constant #items \ total number of items
:redo items swap 3 cells * + ; \ calculate address of record
#items array (items) \ array for sorting
( a -- n)
: price/weight dup 2 cells + @c swap cell+ @c / ;
: weight@ @ cell+ @c ; ( a -- n)
: .item @ @c count type cr ; ( a --)
\ how to sort: on price/weight
:noname >r price/weight r> price/weight > ; is precedes
: knapsack ( --)
(items) dup #items dup 0 ?do i items (items) i th ! loop sort
begin \ use the sorted array
dup weight@ left <= \ still room in the knapsack?
while
." Take all of the " dup .item \ take all of the item
left over weight@ - to left cell+ \ adjust knapsack, increment item
repeat left 100 * dup \ so how much is left?
\ if room, take as much as possible
if ." Take " . ." grams of the " .item else drop drop then
;
knapsack

View file

@ -0,0 +1,55 @@
program KNAPSACK_CONTINUOUS
implicit none
real, parameter :: maxweight = 15.0
real :: total_weight = 0, total_value = 0, frac
integer :: i, j
type Item
character(7) :: name
real :: weight
real :: value
end type Item
type(Item) :: items(9), temp
items(1) = Item("beef", 3.8, 36.0)
items(2) = Item("pork", 5.4, 43.0)
items(3) = Item("ham", 3.6, 90.0)
items(4) = Item("greaves", 2.4, 45.0)
items(5) = Item("flitch", 4.0, 30.0)
items(6) = Item("brawn", 2.5, 56.0)
items(7) = Item("welt", 3.7, 67.0)
items(8) = Item("salami", 3.0, 95.0)
items(9) = Item("sausage", 5.9, 98.0)
! sort items in descending order of their value per unit weight
do i = 2, size(items)
j = i - 1
temp = items(i)
do while (j>=1 .and. items(j)%value / items(j)%weight < temp%value / temp%weight)
items(j+1) = items(j)
j = j - 1
end do
items(j+1) = temp
end do
i = 0
write(*, "(a4, a13, a6)") "Item", "Weight", "Value"
do while(i < size(items) .and. total_weight < maxweight)
i = i + 1
if(total_weight+items(i)%weight < maxweight) then
total_weight = total_weight + items(i)%weight
total_value = total_value + items(i)%value
write(*, "(a7, 2f8.2)") items(i)
else
frac = (maxweight-total_weight) / items(i)%weight
total_weight = total_weight + items(i)%weight * frac
total_value = total_value + items(i)%value * frac
write(*, "(a7, 2f8.2)") items(i)%name, items(i)%weight * frac, items(i)%value * frac
end if
end do
write(*, "(f15.2, f8.2)") total_weight, total_value
end program KNAPSACK_CONTINUOUS

View file

@ -0,0 +1,49 @@
#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

View file

@ -0,0 +1,50 @@
package main
import (
"fmt"
"sort"
)
type item struct {
item string
weight float64
price float64
}
type items []item
var all = 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},
}
// satisfy sort interface
func (z items) Len() int { return len(z) }
func (z items) Swap(i, j int) { z[i], z[j] = z[j], z[i] }
func (z items) Less(i, j int) bool {
return z[i].price/z[i].weight > z[j].price/z[j].weight
}
func main() {
left := 15.
sort.Sort(all)
for _, i := range all {
if i.weight <= left {
fmt.Println("take all the", i.item)
if i.weight == left {
return
}
left -= i.weight
} else {
fmt.Printf("take %.1fkg %s\n", left, i.item)
return
}
}
}

View file

@ -0,0 +1,19 @@
import static java.math.RoundingMode.*
def knapsackCont = { list, maxWeight = 15.0 ->
list.sort{ it.weight / it.value }
def remainder = maxWeight
List sack = []
for (item in list) {
if (item.weight < remainder) {
sack << [name: item.name, weight: item.weight,
value: (item.value as BigDecimal).setScale(2, HALF_UP)]
} else {
sack << [name: item.name, weight: remainder,
value: (item.value * remainder / item.weight).setScale(2, HALF_UP)]
break
}
remainder -= item.weight
}
sack
}

View file

@ -0,0 +1,17 @@
def possibleItems = [
[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],
]
def contents = knapsackCont(possibleItems)
println "Total Value: ${contents*.value.sum()}"
contents.each {
printf(" name: %-7s weight: ${it.weight} value: ${it.value}\n", it.name)
}

View file

@ -0,0 +1,49 @@
import Data.List (sortBy)
import Data.Ord (comparing)
import Text.Printf (printf)
import Control.Monad (forM_)
import Data.Ratio (numerator, denominator)
maxWgt :: Rational
maxWgt = 15
data Bounty = Bounty
{ itemName :: String
, itemVal, itemWgt :: Rational
}
items :: [Bounty]
items =
[ Bounty "beef" 36 3.8
, Bounty "pork" 43 5.4
, Bounty "ham" 90 3.6
, Bounty "greaves" 45 2.4
, Bounty "flitch" 30 4.0
, Bounty "brawn" 56 2.5
, Bounty "welt" 67 3.7
, Bounty "salami" 95 3.0
, Bounty "sausage" 98 5.9
]
solution :: [(Rational, Bounty)]
solution = g maxWgt $ sortBy (flip $ comparing f) items
where
g room (b@(Bounty _ _ w):bs) =
if w < room
then (w, b) : g (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 "Total value: %s\n" . mixedNum . sum) $ f <$> solution
where
f (w, Bounty _ v wtot) = v * (w / wtot)
mixedNum q =
if b == 0
then show a
else printf "%d %d/%d" a (numerator b) (denominator b)
where
a = floor q
b = q - toEnum a

View file

@ -0,0 +1,26 @@
import Data.List (sortBy)
import Data.Ord (comparing)
import Text.Printf (printf)
-- (name, (value, weight))
items =
[ ("beef", (36, 3.8))
, ("pork", (43, 5.4))
, ("ham", (90, 3.6))
, ("greaves", (45, 2.4))
, ("flitch", (30, 4.0))
, ("brawn", (56, 2.5))
, ("welt", (67, 3.7))
, ("salami", (95, 3.0))
, ("sausage", (98, 5.9))
]
unitWeight (_, (val, weight)) = fromIntegral val / weight
solution k = loop k . sortBy (flip $ comparing unitWeight)
where
loop k ((name, (_, weight)):xs)
| weight < k = putStrLn ("Take all the " ++ name) >> loop (k - weight) xs
| otherwise = printf "Take %.2f kg of the %s\n" (k :: Float) name
main = solution 15 items

View file

@ -0,0 +1,36 @@
link printf
procedure main()
room := 15
every (x := !(choices := get_items())).uprice := x.price / x.weight
choices := reverse(sortf(choices,4))
every (value := 0, x := !choices) do {
if x.weight <= room then {
printf("Take all of the %s (%r kg) worth $%r\n",x.name,x.weight,x.price)
value +:= x.price
room -:= x.weight
}
else {
fvalue := x.uprice * room
printf("Take (%r kg) of the %s worth $%r\n",room,x.name,fvalue)
value +:= fvalue
break
}
}
printf("Total value of a full knapsack is $%r\n",value)
end
record item(name,weight,price,uprice)
procedure get_items()
return [ 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) ]
end

View file

@ -0,0 +1,15 @@
'names numbers'=:|:;:;._2]0 :0
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
)
'weights prices'=:|:".numbers
order=: \:prices%weights
take=: 15&<.&.(+/\) order{weights
result=: (*take)#(order{names),.' ',.":,.take

View file

@ -0,0 +1,2 @@
+/prices * (take/:order) % weights
349.378

View file

@ -0,0 +1,73 @@
package hu.pj.alg.test;
import hu.pj.alg.ContinuousKnapsack;
import hu.pj.obj.Item;
import java.util.*;
import java.text.*;
public class ContinousKnapsackForRobber {
final private double tolerance = 0.0005;
public ContinousKnapsackForRobber() {
ContinuousKnapsack cok = new ContinuousKnapsack(15); // 15 kg
// making the list of items that you want to bring
cok.add("beef", 3.8, 36); // marhahús
cok.add("pork", 5.4, 43); // disznóhús
cok.add("ham", 3.6, 90); // sonka
cok.add("greaves", 2.4, 45); // tepertő
cok.add("flitch", 4.0, 30); // oldalas
cok.add("brawn", 2.5, 56); // disznósajt
cok.add("welt", 3.7, 67); // hurka
cok.add("salami", 3.0, 95); // szalámi
cok.add("sausage", 5.9, 98); // kolbász
// calculate the solution:
List<Item> itemList = cok.calcSolution();
// write out the solution in the standard output
if (cok.isCalculated()) {
NumberFormat nf = NumberFormat.getInstance();
System.out.println(
"Maximal weight = " +
nf.format(cok.getMaxWeight()) + " kg"
);
System.out.println(
"Total weight of solution = " +
nf.format(cok.getSolutionWeight()) + " kg"
);
System.out.println(
"Total value (profit) = " +
nf.format(cok.getProfit())
);
System.out.println();
System.out.println(
"You can carry the following materials " +
"in the knapsack:"
);
for (Item item : itemList) {
if (item.getInKnapsack() > tolerance) {
System.out.format(
"%1$-10s %2$-15s %3$-15s \n",
nf.format(item.getInKnapsack()) + " kg ",
item.getName(),
"(value = " + nf.format(item.getInKnapsack() *
(item.getValue() / item.getWeight())) + ")"
);
}
}
} else {
System.out.println(
"The problem is not solved. " +
"Maybe you gave wrong data."
);
}
}
public static void main(String[] args) {
new ContinousKnapsackForRobber();
}
} // class

View file

@ -0,0 +1,76 @@
package hu.pj.alg;
import hu.pj.obj.Item;
import java.util.*;
public class ContinuousKnapsack {
protected List<Item> itemList = new ArrayList<Item>();
protected double maxWeight = 0;
protected double solutionWeight = 0;
protected double profit = 0;
protected boolean calculated = false;
public ContinuousKnapsack() {}
public ContinuousKnapsack(double _maxWeight) {
setMaxWeight(_maxWeight);
}
public List<Item> calcSolution() {
int n = itemList.size();
setInitialStateForCalculation();
if (n > 0 && maxWeight > 0) {
Collections.sort(itemList);
for (int i = 0; (maxWeight - solutionWeight) > 0.0 && i < n; i++) {
Item item = itemList.get(i);
if (item.getWeight() >= (maxWeight - solutionWeight)) {
item.setInKnapsack(maxWeight - solutionWeight);
solutionWeight = maxWeight;
profit += item.getInKnapsack() / item.getWeight() * item.getValue();
break;
} else {
item.setInKnapsack(item.getWeight());
solutionWeight += item.getInKnapsack();
profit += item.getValue();
}
}
calculated = true;
}
return itemList;
}
// add an item to the item list
public void add(String name, double weight, double value) {
if (name.equals(""))
name = "" + (itemList.size() + 1);
itemList.add(new Item(name, weight, value));
setInitialStateForCalculation();
}
public double getMaxWeight() {return maxWeight;}
public double getProfit() {return profit;}
public double getSolutionWeight() {return solutionWeight;}
public boolean isCalculated() {return calculated;}
public void setMaxWeight(double _maxWeight) {
maxWeight = Math.max(_maxWeight, 0);
}
// set the member with name "inKnapsack" by all items:
private void setInKnapsackByAll(double inKnapsack) {
for (Item item : itemList)
item.setInKnapsack(inKnapsack);
}
// set the data members of class in the state of starting the calculation:
protected void setInitialStateForCalculation() {
setInKnapsackByAll(-0.0001);
calculated = false;
profit = 0.0;
solutionWeight = 0.0;
}
} // class

View file

@ -0,0 +1,59 @@
package hu.pj.obj;
public class Item implements Comparable {
protected String name = "";
protected double weight = 0;
protected double value = 0;
protected double inKnapsack = 0; // the weight of item in solution
public Item() {}
public Item(Item item) {
setName(item.name);
setWeight(item.weight);
setValue(item.value);
}
public Item(double _weight, double _value) {
setWeight(_weight);
setValue(_value);
}
public Item(String _name, double _weight, double _value) {
setName(_name);
setWeight(_weight);
setValue(_value);
}
public void setName(String _name) {name = _name;}
public void setWeight(double _weight) {weight = Math.max(_weight, 0);}
public void setValue(double _value) {value = Math.max(_value, 0);}
public void setInKnapsack(double _inKnapsack) {
inKnapsack = Math.max(_inKnapsack, 0);
}
public void checkMembers() {
setWeight(weight);
setValue(value);
setInKnapsack(inKnapsack);
}
public String getName() {return name;}
public double getWeight() {return weight;}
public double getValue() {return value;}
public double getInKnapsack() {return inKnapsack;}
// implementing of Comparable interface:
public int compareTo(Object item) {
int result = 0;
Item i2 = (Item)item;
double rate1 = value / weight;
double rate2 = i2.value / i2.weight;
if (rate1 > rate2) result = -1; // if greater, put it previously
else if (rate1 < rate2) result = 1;
return result;
}
} // class

View file

@ -0,0 +1,22 @@
# 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)" ;

View file

@ -0,0 +1,12 @@
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)

View file

@ -0,0 +1,8 @@
$ 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

View file

@ -0,0 +1,32 @@
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

View file

@ -0,0 +1,14 @@
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)))

View file

@ -0,0 +1,47 @@
// 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)}")
}

View file

@ -0,0 +1,81 @@
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

View file

@ -0,0 +1,9 @@
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]];
overW = Accumulate[sortedTable[[1 ;;, 2]]][[overN]] - capacity;
output = Reverse@sortedTable[[Ordering[sortedTable[[1 ;;, 4]], -overN]]];
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]]]}]]

View file

@ -0,0 +1,12 @@
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}};
carryCapacity = 15;
Knapsack[weightPriceTable, carryCapacity] // Grid
salami 3. 95
ham 3.6 90
brawn 2.5 56
greaves 2.4 45
welt 3.5 63.3784
Total 15. 349.378

View file

@ -0,0 +1,31 @@
/*Knapsack
This model finds the optimal packing of a knapsack
Nigel_Galloway
January 10th., 2012
*/
set Items;
param weight{t in Items};
param value{t in Items};
var take{t in Items}, >=0, <=weight[t];
knap_weight : sum{t in Items} take[t] <= 15;
maximize knap_value: sum{t in Items} take[t] * (value[t]/weight[t]);
data;
param : Items : weight value :=
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
;
end;

View file

@ -0,0 +1,11 @@
%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)]

View file

@ -0,0 +1,38 @@
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}"

View file

@ -0,0 +1,34 @@
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; ]
let () =
let items = List.map (fun (name, w, p) -> (name, w, p, float p /. w)) items in
let items = List.sort (fun (_,_,_,v1) (_,_,_,v2) -> compare v2 v1) items in
let rec loop acc weight = function
| ((_,w,_,_) as item) :: tl ->
if w +. weight > 15.0
then (weight, acc, item)
else loop (item::acc) (w +. weight) tl
| [] -> assert false
in
let weight, res, (last,w,p,v) = loop [] 0.0 items in
print_endline " Items Weight Price";
let price =
List.fold_left (fun price (name,w,p,_) ->
Printf.printf " %7s: %6.2f %3d\n" name w p;
(p + price)
) 0 res
in
let rem_weight = 15.0 -. weight in
let last_price = v *. rem_weight in
Printf.printf " %7s: %6.2f %6.2f\n" last rem_weight last_price;
Printf.printf " Total Price: %.3f\n" (float price +. last_price);
;;

View file

@ -0,0 +1,18 @@
[
[ "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
] ;

View file

@ -0,0 +1,75 @@
/*--------------------------------------------------------------------
* 20.09.2014 Walter Pachl translated from REXX version 2
* utilizing ooRexx features like objects, array(s) and sort
*-------------------------------------------------------------------*/
maxweight = 15.0
items=.array~new
items~append(.item~new('beef', 3.8, 36.0))
items~append(.item~new('pork', 5.4, 43.0))
items~append(.item~new('ham', 3.6, 90.0))
items~append(.item~new('greaves', 2.4, 45.0))
items~append(.item~new('flitch', 4.0, 30.0))
items~append(.item~new('brawn', 2.5, 56.0))
items~append(.item~new('welt', 3.7, 67.0))
items~append(.item~new('salami', 3.0, 95.0))
items~append(.item~new('sausage', 5.9, 98.0))
/* show the input */
Say '# vpu name weight value'
i=0
Do x over items
i+=1
Say i format(x~vpu,2,3) left(x~name,7) format(x~weight,2,3) format(x~value,3,3)
End
/* sort the items by descending value per unit of weight */
items~sortWith(.DescendingComparator~new)
total_weight=0
total_value =0
Say ' '
Say 'Item Weight Value'
i=0
Do x over items
i+=1
Parse Var item.i name '*' weight '*' value
if total_weight+x~weight<maxweight then Do
total_weight = total_weight + x~weight
total_value = total_value + x~value
Say left(x~name,7) format(x~weight,3,3) format(x~value,3,3)
End
Else Do
weight=maxweight-total_weight
value=weight*x~vpu
total_value = total_value + value
total_weight = maxweight
Say left(x~name,7) format(weight,3,3) format(value,3,3)
Leave
End
End
Say copies('-',23)
Say 'total ' format(total_weight,4,3) format(total_value,3,3)
Exit
::class item
::attribute vpu
::attribute name
::attribute weight
::attribute value
::method init
Expose vpu
Use Arg name, weight, value
self~name=name
self~weight=weight
self~value=value
self~vpu=value/weight
::CLASS 'DescendingComparator' MIXINCLASS Comparator
::METHOD compare
use strict arg a, b
Select
When (a~vpu)<(b~vpu) Then res='1'
Otherwise res='-1'
End
Return res

View file

@ -0,0 +1,73 @@
/*--------------------------------------------------------------------
* 20.09.2014 Walter Pachl translated from REXX version 2
* utilizing ooRexx features like objects, array(s) and sort
* 21.09.2014 simplified (courtesy Rony Flatscher)
* (sort uses now the method "compareTo" defined for item)
*-------------------------------------------------------------------*/
maxweight = 15.0
items=.array~new
items~append(.item~new('beef', 3.8, 36.0))
items~append(.item~new('pork', 5.4, 43.0))
items~append(.item~new('ham', 3.6, 90.0))
items~append(.item~new('greaves', 2.4, 45.0))
items~append(.item~new('flitch', 4.0, 30.0))
items~append(.item~new('brawn', 2.5, 56.0))
items~append(.item~new('welt', 3.7, 67.0))
items~append(.item~new('salami', 3.0, 95.0))
items~append(.item~new('sausage', 5.9, 98.0))
/* show the input */
Say '# vpu name weight value'
i=0
Do x over items
i+=1
Say i format(x~vpu,2,3) left(x~name,7) format(x~weight,2,3) format(x~value,3,3)
End
/* sort the items by descending value per unit of weight */
items~sort /* using the method compareTo used for item */
total_weight=0
total_value =0
Say ' '
Say 'Item Weight Value'
i=0
Do x over items
i+=1
Parse Var item.i name '*' weight '*' value
if total_weight+x~weight<maxweight then Do
total_weight = total_weight + x~weight
total_value = total_value + x~value
Say left(x~name,7) format(x~weight,3,3) format(x~value,3,3)
End
Else Do
weight=maxweight-total_weight
value=weight*x~vpu
total_value = total_value + value
total_weight = maxweight
Say left(x~name,7) format(weight,3,3) format(value,3,3)
Leave
End
End
Say copies('-',23)
Say 'total ' format(total_weight,4,3) format(total_value,3,3)
Exit
::class item
::attribute vpu
::attribute name
::attribute weight
::attribute value
::method init
Expose vpu
Use Arg name, weight, value
self~name=name
self~weight=weight
self~value=value
self~vpu=value/weight
::method compareTo -- default sort order
Expose vpu
use Arg other
return -sign(vpu - other~vpu)

View file

@ -0,0 +1,64 @@
/* Added by @1x24. Translated from C++. Uses the PHP 7.x spaceship operator */
$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) {
return ($b['cost']/$b['weight']) <=> ($a['cost']/$a['weight']);
});
$limit = 15;
foreach ($data as $item):
if ($limit >= $item['weight']):
echo "Take all the {$item['name']}<br/>";
else:
echo "Take $limit kg of {$item['name']}<br/>";
break;
endif;
$limit -= $item['weight'];
endforeach;

View file

@ -0,0 +1,75 @@
*process source xref attributes;
KNAPSACK_CONTINUOUS: Proc Options(main);
/*--------------------------------------------------------------------
* 19.09.2014 Walter Pachl translated from FORTRAN
*-------------------------------------------------------------------*/
Dcl (divide,float,hbound,repeat) Builtin;
Dcl SYSPRINT Print;
Dcl maxweight Dec Fixed(15,3);
maxweight = 15.0;
Dcl (total_weight,total_value) Dec Fixed(15,3) Init(0);
Dcl vpu Dec Float(15);
Dcl (i,j) Bin Fixed(31);
Dcl 1 item(9),
2 name Char(7),
2 weight Dec Fixed(15,3),
2 value Dec Fixed(15,3);
Dcl temp Like item;
Call init_item(1,'beef', 3.8, 36.0);
Call init_item(2,'pork', 5.4, 43.0);
Call init_item(3,'ham', 3.6, 90.0);
Call init_item(4,'greaves', 2.4, 45.0);
Call init_item(5,'flitch', 4.0, 30.0);
Call init_item(6,'brawn', 2.5, 56.0);
Call init_item(7,'welt', 3.7, 67.0);
Call init_item(8,'salami', 3.0, 95.0);
Call init_item(9,'sausage', 5.9, 98.0);
/* sort item in descending order of their value per unit weight */
do i = 2 To hbound(item);
j = i - 1;
temp = item(i);
do while(j>=1&item(j).value/item(j).weight<temp.value/temp.weight);
item(j+1) = item(j);
j = j - 1;
end;
item(j+1) = temp;
end;
Do i=1 To hbound(item);
Put Edit(i,item(i))(Skip,f(2),x(2),a(7),2(f(8,3)));
End;
i = 0;
Put Skip;
Put Edit('Item Weight Value')(Skip,a);
do i=1 By 1 while(i < hbound(item) & total_weight < maxweight);
if total_weight+item(i).weight < maxweight then Do;
total_weight = total_weight + item(i).weight;
total_value = total_value + item(i).value;
Put Edit(item(i))(Skip,a(7),2(f(8,3)));
End;
Else Do;
vpu=divide(item(i).value,item(i).weight,15,8);
item(i).weight=maxweight-total_weight;
item(i).value=float(item(i).weight)*vpu;
total_value = total_value + item(i).value;
total_weight = total_weight + item(i).weight;
Put Edit(item(i).name, item(i).weight, item(i).value)
(Skip,a(7),2(f(8,3)));
Leave Loop;
end;
end;
Put Edit(repeat('-',22))(Skip,a);
Put Edit('total',total_weight, total_value)(Skip,a(6),f(9,3),f(8,3));
init_item: Proc(i,name,weight,value);
Dcl i Bin Fixed(31);
Dcl name Char(*);
Dcl (weight,value) Dec Fixed(15,3);
item(i).name = name;
item(i).weight = weight;
item(i).value = value;
End;
End;

View file

@ -0,0 +1,51 @@
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.

View file

@ -0,0 +1,30 @@
my @items = sort { $b->[2]/$b->[1] <=> $a->[2]/$a->[1] }
(
[qw'beef 3.8 36'],
[qw'pork 5.4 43'],
[qw'ham 3.6 90'],
[qw'greaves 2.4 45'],
[qw'flitch 4.0 30'],
[qw'brawn 2.5 56'],
[qw'welt 3.7 67'],
[qw'salami 3.0 95'],
[qw'sausage 5.9 98'],
);
my ($limit, $value) = (15, 0);
print "item fraction weight value\n";
for (@items) {
my $ratio = $_->[1] > $limit ? $limit/$_->[1] : 1;
print "$_->[0]\t";
$value += $_->[2] * $ratio;
$limit -= $_->[1];
if ($ratio == 1) {
print " all\t$_->[1]\t$_->[2]\n";
} else {
printf "%5.3f %s %8.3f\n", $ratio, $_->[1] * $ratio, $_->[2] * $ratio;
last;
}
}
print "-" x 40, "\ntotal value: $value\n";

View file

@ -0,0 +1,33 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">meats</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span>
<span style="color: #000080;font-style:italic;">--Item Weight (kg) Price (Value)</span>
<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>
<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>
<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>
<!--

View file

@ -0,0 +1,46 @@
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]).

View file

@ -0,0 +1,33 @@
(scl 2)
(de *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) )
(let K
(make
(let Weight 0
(for I (by '((L) (*/ (caddr L) -1.0 (cadr L))) sort *Items)
(T (= Weight 15.0))
(inc 'Weight (cadr I))
(T (> Weight 15.0)
(let W (- (cadr I) Weight -15.0)
(link (list (car I) W (*/ W (caddr I) (cadr I)))) ) )
(link I) ) ) )
(for I K
(tab (3 -9 8 8)
NIL
(car I)
(format (cadr I) *Scl)
(format (caddr I) *Scl) ) )
(tab (12 8 8)
NIL
(format (sum cadr K) *Scl)
(format (sum caddr K) *Scl) ) )

View file

@ -0,0 +1,65 @@
:- use_module(library(simplex)).
% tuples (name, weights, value).
knapsack :-
L = [( 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)],
gen_state(S0),
length(L, N),
numlist(1, N, LN),
( ( create_constraint_N(LN, L, S0, S1, [], LW, [], LV),
constraint(LW =< 15.0, S1, S2),
maximize(LV, S2, S3)
)),
compute_lenword(L, 0, Len),
sformat(A1, '~~w~~t~~~w|', [Len]),
sformat(A2, '~~t~~2f~~~w|', [10]),
sformat(A3, '~~t~~2f~~~w|', [10]),
print_results(S3, A1,A2,A3, L, LN, 0, 0).
create_constraint_N([], [], S, S, LW, LW, LV, LV).
create_constraint_N([HN|TN], [(_, W, V) | TL], S1, SF, LW, LWF, LV, LVF) :-
constraint([x(HN)] >= 0, S1, S2),
constraint([x(HN)] =< W, S2, S3),
X is V/W,
create_constraint_N(TN, TL, S3, SF, [x(HN) | LW], LWF, [X * x(HN) | LV], LVF).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
compute_lenword([], N, N).
compute_lenword([(Name, _, _)|T], N, NF):-
atom_length(Name, L),
( L > N -> N1 = L; N1 = N),
compute_lenword(T, N1, NF).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
print_results(_S, A1, A2, A3, [], [], WM, VM) :-
sformat(W1, A1, [' ']),
sformat(W2, A2, [WM]),
sformat(W3, A3, [VM]),
format('~w~w~w~n', [W1,W2,W3]).
print_results(S, A1, A2, A3, [(Name, W, V)|T], [N|TN], W1, V1) :-
variable_value(S, x(N), X),
( X = 0 -> W1 = W2, V1 = V2
;
sformat(S1, A1, [Name]),
sformat(S2, A2, [X]),
Vtemp is X * V/W,
sformat(S3, A3, [Vtemp]),
format('~w~w~w~n', [S1,S2,S3]),
W2 is W1 + X,
V2 is V1 + Vtemp ),
print_results(S, A1, A2, A3, T, TN, W2, V2).

View file

@ -0,0 +1,72 @@
Structure item
name.s
weight.f ;units are kilograms (kg)
Value.f
vDensity.f ;the density of the value, i.e. value/weight, and yes I made up the term ;)
EndStructure
#maxWeight = 15
Global itemCount = 0 ;this will be increased as needed to match actual count
Global Dim items.item(itemCount)
Procedure addItem(name.s, weight.f, Value.f)
If itemCount >= ArraySize(items())
Redim items.item(itemCount + 10)
EndIf
With items(itemCount)
\name = name
\weight = weight
\Value = Value
If Not \weight
\vDensity = \Value
Else
\vDensity = \Value / \weight
EndIf
EndWith
itemCount + 1
EndProcedure
;build item list
addItem("beef", 3.8, 36)
addItem("pork", 5.4, 43)
addItem("ham", 3.6, 90)
addItem("greaves", 2.4, 45)
addItem("flitch", 4.0, 30)
addItem("brawn", 2.5, 56)
addItem("welt", 3.7, 67)
addItem("salami", 3.0, 95)
addItem("sausage", 5.9, 98)
SortStructuredArray(items(), #PB_Sort_descending, OffsetOf(item\vDensity), #PB_Sort_Float, 0, itemCount - 1)
Define TotalWeight.f, TotalValue.f, i
NewList knapsack.item()
For i = 0 To itemCount
If TotalWeight + items(i)\weight < #maxWeight
AddElement(knapsack())
knapsack() = items(i)
TotalWeight + items(i)\weight
TotalValue + items(i)\Value
Else
AddElement(knapsack())
knapsack() = items(i)
knapsack()\weight = #maxWeight - TotalWeight
knapsack()\Value = knapsack()\weight * knapsack()\vDensity
TotalWeight = #maxWeight
TotalValue + knapsack()\Value
Break
EndIf
Next
If OpenConsole()
PrintN(LSet("Maximal weight", 26, " ") + "= " + Str(#maxWeight) + " kg")
PrintN(LSet("Total weight of solution", 26, " ") + "= " + Str(#maxWeight) + " kg")
PrintN(LSet("Total value", 26, " ") + "= " + StrF(TotalValue, 3) + " " + #CRLF$)
PrintN("You can carry the following materials in the knapsack: ")
ForEach knapsack()
PrintN(RSet(StrF(knapsack()\weight, 1), 5, " ") + " kg " + LSet(knapsack()\name, 10, " ") + " (Value = " + StrF(knapsack()\Value, 3) + ")")
Next
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
Input()
CloseConsole()
EndIf

View file

@ -0,0 +1,30 @@
# NAME, WEIGHT, VALUE (for this weight)
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)]
MAXWT = 15.0
sorted_items = sorted(((value/amount, amount, name)
for name, amount, value in items),
reverse = True)
wt = val = 0
bagged = []
for unit_value, amount, name in sorted_items:
portion = min(MAXWT - wt, amount)
wt += portion
addval = portion * unit_value
val += addval
bagged += [(name, portion, addval)]
if wt >= MAXWT:
break
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))

View file

@ -0,0 +1,43 @@
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)
}

View file

@ -0,0 +1,42 @@
/*REXX pgm solves the continuous burglar's knapsack problem; items with weight 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 d . /*get possible arguments from the C.L. */
if maxW=='' | maxW=="," then maxW=15 /*the burglar's knapsack maximum weight*/
if d=='' | d=="," then d= 3 /*# decimal digits shown 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. */
do #=1 while @.#\==''; parse var @.# n.# w.# v.# .; end; #=#-1
call show 'unsorted item list' /*display the header and the @ list.*/
call sortD /*invoke descemdomg sort for: n. w. v.*/
call hdr "burglar's knapsack contents"
do j=1 for # while totW<maxW; f=1 /*process the items. */
if totW+w.j>=maxW then f=(maxW-totW)/w.j /*calculate fraction. */
totW=totW+w.j*f; totV=totV+v.j*f /*add it ───► totals. */
call syf left(word('{all}',1+(f\==1)),5) n.j, w.j*f, v.j*f
end /*j*/ /* [↑] display item, maybe with {all} */
call sep; say /* [↓] $ suppresses trailing zeroes.*/
call sy left('total weight', nL, ""), $(format(totW,,d))
call sy left('total value', nL, ""), , $(format(totV,,d))
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sortD: do s=2 to #; a=n.s; !=w.s; u=v.s /* [↓] this is a descending sort. */
do k=s-1 by -1 to 1 while v.k/w.k<u/!; ?=k+1; n.?=n.k; w.?=w.k; v.?=v.k; end
?=k+1; n.?=a; w.?=!; v.?=u
end /*s*/; return /* ↑↑↑ algorithm is OK for small arrays*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
hdr: say; say; say center(arg(1),50,''); say; call title; call sep; return
sep: call sy copies('', nL), copies("", wL), copies('', vL); return
show: call hdr arg(1); do j=1 for #; call syf n.j, w.j, v.j; end; return
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), , d)), $(format(arg(3), , d)); return
title: call sy center('item',nL), center("weight", wL), center('value', vL); return
$: parse arg x;if pos(.,x)>1 then x=left(strip(strip(x,'T',0),,.),length(x)); return x

View file

@ -0,0 +1,77 @@
/*--------------------------------------------------------------------
* 19.09.2014 Walter Pachl translated from FORTRAN
* While this program works with all REXX interpreters,
* see section ooRexx for a version that utilizes the ooRexx features
*-------------------------------------------------------------------*/
maxweight = 15.0
input.0=0
Call init_input 'beef', 3.8, 36.0
Call init_input 'pork', 5.4, 43.0
Call init_input 'ham', 3.6, 90.0
Call init_input 'greaves', 2.4, 45.0
Call init_input 'flitch', 4.0, 30.0
Call init_input 'brawn', 2.5, 56.0
Call init_input 'welt', 3.7, 67.0
Call init_input 'salami', 3.0, 95.0
Call init_input 'sausage', 5.9, 98.0
/* sort the items by descending value per unit of weight */
Do i = 1 to input.0
Parse Var input.i name '*' weight '*' value
vpu=value/weight;
If i=1 Then Do
item.0=1
item.1=input.1
vpu.1=vpu
End
Else Do
Do ii=1 To item.0
If vpu.ii<vpu Then
Leave
End
Do jj=item.0 To ii By -1
jj1=jj+1
item.jj1=item.jj
vpu.jj1=vpu.jj
End
item.ii=input.i
vpu.ii=vpu
item.0=item.0+1
End
End
Say '# vpu name weight value'
Do i=1 To item.0
Parse Var item.i name '*' weight '*' value
Say i format(vpu.i,2,3) left(name,7) format(weight,2,3) format(value,3,3)
End
total_weight=0
total_value =0
Say ' '
Say 'Item Weight Value'
Do i=1 To item.0
Parse Var item.i name '*' weight '*' value
if total_weight+weight < maxweight then Do
total_weight = total_weight + weight
total_value = total_value + value
Say left(name,7) format(weight,3,3) format(value,3,3)
End
Else Do
weight=maxweight-total_weight
value=weight*vpu.i
total_value = total_value + value
total_weight = maxweight
Say left(name,7) format(weight,3,3) format(value,3,3)
Leave
End
End
Say copies('-',23)
Say 'total ' format(total_weight,4,3) format(total_value,3,3)
Exit
init_input: Procedure Expose input.
Parse Arg name,weight,value
i=input.0+1
input.i=name'*'weight'*'value
input.0=i
Return

View file

@ -0,0 +1,45 @@
#lang racket
(define shop-inventory
'((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)))
(define (continuous-knapsack shop sack sack-capacity sack-total-value)
;; solved by loading up on the highest value item...
(define (value/kg item) (/ (third item) (second item)))
(if (zero? sack-capacity)
(values (reverse sack) sack-total-value)
(let* ((best-value-item (argmax value/kg shop))
(bvi-full-weight (second best-value-item))
(amount-can-take (min sack-capacity bvi-full-weight))
(bvi-full-value (third best-value-item))
(bvi-taken-value (* bvi-full-value (/ amount-can-take bvi-full-weight))))
(continuous-knapsack (remove best-value-item shop)
(cons (list (first best-value-item)
(if (= amount-can-take bvi-full-weight)
'all-of amount-can-take) bvi-taken-value)
sack)
(- sack-capacity amount-can-take)
(+ sack-total-value bvi-taken-value)))))
(define (report-knapsack sack total-value)
(for-each (lambda (item)
(if (eq? 'all-of (second item))
(printf "Take all of the ~a (for ~a)~%"
(first item) (third item))
(printf "Take ~a of the ~a (for ~a)~%"
(real->decimal-string (second item))
(first item)
(real->decimal-string (third item)))))
sack)
(printf "For a grand total of: ~a" (real->decimal-string total-value)))
(call-with-values (lambda () (continuous-knapsack shop-inventory null 15 0))
report-knapsack)

View file

@ -0,0 +1,44 @@
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;
}

View file

@ -0,0 +1,20 @@
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_by{|item, weight, price| -price / weight}
maxW, value = 15.0, 0
items.each do |item, weight, price|
if (maxW -= weight) > 0
puts "Take all #{item}"
value += price
else
puts "Take %gkg of %s" % [t=weight+maxW, item], "",
"Total value of swag is %g" % (value+(price/weight)*t)
break
end
end

View file

@ -0,0 +1,57 @@
dim name$(9)
dim wgt(9)
dim price(9)
dim tak$(100)
name$(1) = "beef" : wgt(1) = 3.8 : price(1) = 36
name$(2) = "pork" : wgt(2) = 5.4 : price(2) = 43
name$(3) = "ham" : wgt(3) = 3.6 : price(3) = 90
name$(4) = "greaves" : wgt(4) = 2.4 : price(4) = 45
name$(5) = "flitch" : wgt(5) = 4.0 : price(5) = 30
name$(6) = "brawn" : wgt(6) = 2.5 : price(6) = 56
name$(7) = "welt" : wgt(7) = 3.7 : price(7) = 67
name$(8) = "salami" : wgt(8) = 3.0 : price(8) = 95
name$(9) = "sausage" : wgt(9) = 5.9 : price(9) = 98
for beef = 0 to 15 step 3.8
for pork = 0 to 15 step 5.4
for ham = 0 to 15 step 3.6
for greaves = 0 to 15 step 2.4
for flitch = 0 to 15 step 4.0
for brawn = 0 to 15 step 2.5
for welt = 0 to 15 step 3.7
for salami = 0 to 15 step 3.0
for sausage = 0 to 15 step 5.9
if beef + pork + ham + greaves + flitch + brawn + welt + salami + sausage <= 15 then
totPrice = 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
if totPrice >= maxPrice then
maxPrice = totPrice
theMax = max(totPrice,maxPrice)
t = t + 1
tak$(t) = str$(maxPrice);",";beef;",";pork;",";ham;",";greaves;",";flitch;",";brawn;",";welt;",";salami;",";sausage
end if
end if
next:next :next :next :next :next :next :next :next
print "Best 2 Options":print
for i = t-1 to t
totTake = val(word$(tak$(i),1,","))
if totTake > 0 then
totWgt = 0
for j = 2 to 10
wgt = val(word$(tak$(i),j,","))
totWgt = totWgt + wgt
value = wgt / wgt(j - 1) * price(j - 1)
if wgt <> 0 then print name$(j-1);chr$(9);"Value: ";using("###.#",value);chr$(9);"Weight: ";using("##.#",wgt)
next j
print "-------- Total ";using("###.#",totTake);chr$(9);"Weight: ";totWgt
end if
next i

View file

@ -0,0 +1,34 @@
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;
}
}
}

View file

@ -0,0 +1,36 @@
/* 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;

View file

@ -0,0 +1,57 @@
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)))
}

View file

@ -0,0 +1,30 @@
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 }"

View file

@ -0,0 +1,37 @@
package require Tcl 8.5
# Uses the trivial greedy algorithm
proc continuousKnapsack {items massLimit} {
# Add in the unit prices
set idx -1
foreach item $items {
lassign $item name mass value
lappend item [expr {$value / $mass}]
lset items [incr idx] $item
}
# Sort by unit prices
set items [lsort -decreasing -real -index 3 $items]
# Add items, using most valuable-per-unit first
set result {}
set total 0.0
set totalValue 0
foreach item $items {
lassign $item name mass value unit
if {$total + $mass < $massLimit} {
lappend result [list $name $mass $value]
set total [expr {$total + $mass}]
set totalValue [expr {$totalValue + $value}]
} else {
set mass [expr {$massLimit - $total}]
set value [expr {$unit * $mass}]
lappend result [list $name $mass $value]
set totalValue [expr {$totalValue + $value}]
break
}
}
# We return the total value too, purely for convenience
return [list $result $totalValue]
}

View file

@ -0,0 +1,19 @@
set 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}
}
lassign [continuousKnapsack $items 15.0] contents totalValue
puts [format "total value of knapsack: %.2f" $totalValue]
puts "contents:"
foreach item $contents {
lassign $item name mass value
puts [format "\t%.1fkg of %s, value %.2f" $mass $name $value]
}

View file

@ -0,0 +1,27 @@
#import flo
#import lin
items = # name: (weight,price)
<
'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)>
system = # a function to transform the item list to the data structure needed by the solver
linear_system$[
lower_bounds: *nS ~&\0., # all zeros because we can't steal less than zero
upper_bounds: ~&nmlPXS, # can't steal more than what's in the shop
costs: * ^|/~& negative+ vid, # prices divided by weights, negated so as to maximize
equations: ~&iNC\15.+ 1.-*@nS] # 1 equation constraining the total weight to 15
#cast %em
main = solution system items

View file

@ -0,0 +1,42 @@
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)
}

View file

@ -0,0 +1,54 @@
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)

View file

@ -0,0 +1,30 @@
int Name, Price, I, BestItem;
real Weight, Best, ItemWt, TotalWt;
def Items = 9;
real PricePerWt(Items);
int Taken(Items);
include c:\cxpl\codes;
[Name:= ["beef","pork","ham","greaves","flitch","brawn","welt","salami","sausage"];
Weight:= [ 3.8, 5.4, 3.6, 2.4, 4.0, 2.5, 3.7, 3.0, 5.9];
Price:= [ 36, 43, 90, 45, 30, 56, 67, 95, 98];
for I:= 0 to Items-1 do
[PricePerWt(I):= float(Price(I)) / Weight(I);
Taken(I):= false;
];
Format(2,1);
TotalWt:= 0.0;
repeat Best:= 0.0;
for I:= 0 to Items-1 do
if not Taken(I) and PricePerWt(I) > Best then
[Best:= PricePerWt(I); BestItem:= I];
Taken(BestItem):= true; \take item
ItemWt:= Weight(BestItem); \get its weight
TotalWt:= TotalWt + ItemWt; \add to total weight
if TotalWt > 15.0 then \if total is too much, reduce
ItemWt:= ItemWt - (TotalWt-15.0); \item weight by amount it's over
RlOut(0, ItemWt); Text(0, " kg of "); \show weight and item
Text(0, Name(BestItem)); CrLf(0);
until TotalWt >= 15.0; \all we can steal
]

View file

@ -0,0 +1,14 @@
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 }
}