Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

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

@ -2,36 +2,36 @@
#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" },
{ 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;
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;
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);
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;
return 0;
}

View file

@ -9,16 +9,16 @@ 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)
);
(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;
@ -43,43 +43,43 @@ 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;
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;
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;
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;

View file

@ -4,20 +4,20 @@
(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)))
'((🐂-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))
(- (// (* (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))
@ -25,11 +25,11 @@
;; 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))))))
(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)

View file

@ -1,71 +1,71 @@
class
CONTINUOUS_KNAPSACK
CONTINUOUS_KNAPSACK
create
make
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
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
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]]
items: ARRAY [TUPLE [name: STRING; weight: REAL_64; price: REAL_64]]
sorted: SORTED_TWO_WAY_LIST [REAL_64]
sorted: SORTED_TWO_WAY_LIST [REAL_64]
end

View file

@ -5,31 +5,31 @@
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.
{_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 = 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}
].
[{"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]};
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;

View file

@ -0,0 +1,77 @@
! Fractional knapsack: butcher's shop problem.
! Items may be cut; greedy optimum is achieved by sorting on value/weight
! ratio descending, then filling the knapsack in that order.
program butcher
use iso_fortran_env, only: real64
implicit none
integer, parameter :: NITEMS = 9
real(real64), parameter :: CAPACITY = 15.0_real64
character(len=10), parameter :: name(NITEMS) = [ &
"beef ", "pork ", "ham ", "greaves ", &
"flitch ", "brawn ", "welt ", "salami ", &
"sausage " ]
real(real64), parameter :: weight(NITEMS) = &
[ 3.8_real64, 5.4_real64, 3.6_real64, 2.4_real64, 4.0_real64, &
2.5_real64, 3.7_real64, 3.0_real64, 5.9_real64 ]
real(real64), parameter :: price(NITEMS) = &
[ 36.0_real64, 43.0_real64, 90.0_real64, 45.0_real64, 30.0_real64, &
56.0_real64, 67.0_real64, 95.0_real64, 98.0_real64 ]
real(real64) :: ratio(NITEMS), fraction(NITEMS)
real(real64) :: remaining, total_value, taken
integer :: order(NITEMS), i, j, tmp
! Compute value-per-kg ratios
do i = 1, NITEMS
ratio(i) = price(i) / weight(i)
end do
! Sort indices by ratio descending (insertion sort)
order = [(i, i = 1, NITEMS)]
do i = 2, NITEMS
j = i
do while (j > 1 .and. ratio(order(j)) > ratio(order(j-1)))
tmp = order(j); order(j) = order(j-1); order(j-1) = tmp
j = j - 1
end do
end do
! Greedy fill
fraction = 0.0_real64
remaining = CAPACITY
total_value = 0.0_real64
do i = 1, NITEMS
if (remaining <= 0.0_real64) exit
j = order(i)
taken = min(weight(j), remaining)
fraction(j) = taken / weight(j)
total_value = total_value + fraction(j) * price(j)
remaining = remaining - taken
end do
! Report
write(*, '(a)') "Fractional knapsack -- butcher's shop (capacity 15 kg)"
write(*, '(a)') repeat('-', 57)
write(*, '(a10, 2x, a10, 2x, a10, 2x, a10, 2x, a10)') &
"Item", "Weight kg", "Price", "Taken kg", "Value"
write(*, '(a)') repeat('-', 57)
do i = 1, NITEMS
j = order(i)
if (fraction(j) > 0.0_real64) then
write(*, '(a10, 2x, f9.1, 2x, f9.2, 2x, f9.4, 2x, f9.2)') &
trim(name(j)), weight(j), price(j), &
fraction(j) * weight(j), fraction(j) * price(j)
end if
end do
write(*, '(a)') repeat('-', 57)
write(*, '(a10, 2x, f9.4, 2x, 10x, 2x, 10x, 2x, f9.2)') &
"Total", CAPACITY - remaining, total_value
end program butcher

View file

@ -4,9 +4,9 @@ weightPriceTable =
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
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

@ -18,14 +18,14 @@ 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
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
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,57 @@
MODULE KnapsackProblem; (* Knapsack problem: Continuous - based on the Algol W sample, *)
(* which is based on the EasyLang sample *)
IMPORT Out;
CONST maxItems = 8;
maxName = 12;
TYPE ItemDesc = RECORD name : ARRAY maxName OF CHAR;
weight, cost : REAL
END;
Item = POINTER TO ItemDesc;
VAR sackItems : ARRAY maxItems + 1 OF Item;
t : Item;
weightLeft, w : REAL;
p, q : INTEGER;
PROCEDURE price( a : Item ) : REAL;
BEGIN
RETURN a.cost / a.weight
END price;
PROCEDURE newItem( name : ARRAY OF CHAR; weight, cost : REAL ) : Item;
VAR result : Item;
BEGIN
NEW( result );
result.name := name;
result.weight := weight;
result.cost := cost
RETURN result
END newItem;
BEGIN
sackItems[ 0 ] := newItem( "beef", 3.8, 36.0 );sackItems[ 1 ] := newItem( "pork", 5.4, 43.0 );
sackItems[ 2 ] := newItem( "ham", 3.6, 90.0 );sackItems[ 3 ] := newItem( "greaves", 2.4, 45.0 );
sackItems[ 4 ] := newItem( "flitch", 4.0, 30.0 );sackItems[ 5 ] := newItem( "brawn", 2.5, 56.0 );
sackItems[ 6 ] := newItem( "welt", 3.7, 67.0 );sackItems[ 7 ] := newItem( "salami", 3.0, 95.0 );
sackItems[ 8 ] := newItem( "sausage", 5.9, 98.0 );
FOR p := 0 TO maxItems DO
FOR q := p + 1 TO maxItems DO
IF price( sackItems[ q ] ) > price( sackItems[ p ] ) THEN
t := sackItems[ p ];
sackItems[ p ] := sackItems[ q ];
sackItems[ q ] := t
END
END
END;
weightLeft := 15.0;
p := -1;
WHILE ( p <= maxItems ) & ( weightLeft > 0.0 ) DO
INC( p );
IF sackItems[ p ].weight > weightLeft THEN w := weightLeft ELSE w := sackItems[ p ].weight END;
Out.Real( w, 12 );Out.String( " kg " );Out.String( sackItems[ p ].name );Out.Ln;
weightLeft := weightLeft - w
END
END KnapsackProblem.

View file

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

View file

@ -1,51 +1,51 @@
/* 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,
],
];
[
'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']);
@ -54,11 +54,11 @@ uasort($data, function($a, $b) {
$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'];
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

@ -1,33 +1,31 @@
(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>
with javascript_semantics
constant meats = {
--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}}
<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>
function by_weighted_value(integer i, j)
atom {?,weighti,pricei} = meats[i],
{?,weightj,pricej} = meats[j]
return compare(pricej/weightj,pricei/weighti)
end function
<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>
sequence tags = custom_sort(by_weighted_value,tagset(length(meats)))
<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>
<!--
atom weight = 15, worth = 0
for i=1 to length(tags) do
object {desc,wi,price} = meats[tags[i]]
atom amt = min(wi,weight)
printf(1,"%3.1fkg %s %s\n",{amt,iff(amt=wi?"(all the)":"of"),desc})
worth += (amt/wi)*price
weight -= amt
if weight=0 then exit end if
end for
printf(1,"Total value: %f\n",{worth})

View file

@ -0,0 +1,34 @@
do -- Knapsack problem: Continuous - based on the Algol W sample, which is based on the EasyLang sample
local class Item
function __construct( name : string, weight : number, cost : number )
self.name = name
self.weight = weight
self.cost = cost
end
function price() : number
return self.cost / self.weight
end
end
local sackItems = { new Item( "beef", 3.8, 36 ), new Item( "pork", 5.4, 43 )
, new Item( "ham", 3.6, 90 ), new Item( "greaves", 2.4, 45 )
, new Item( "flitch", 4.0, 30 ), new Item( "brawn", 2.5, 56 )
, new Item( "welt", 3.7, 67 ), new Item( "salami", 3.0, 95 )
, new Item( "sausage", 5.9, 98 )
}
sackItems:sort( function( a, b ) return a:price() > b:price() end )
local maxWeight, i = 15, 0
while i <= # sackItems and maxWeight > 0 do
i += 1
local w = sackItems[ i ].weight
if w > maxWeight then w = maxWeight end
print( $"{w} kg {sackItems[ i ].name}" )
maxWeight -= w
end
end

View file

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

@ -1,14 +1,14 @@
#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)))
'((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)

View file

@ -0,0 +1,49 @@
Rebol [
title: "Rosetta code: Knapsack problem/Continuous"
file: %Knapsack_problem-Continuous.r3
url: https://rosettacode.org/wiki/Knapsack_problem/Continuous
]
knapsack: function [
"Solves the fractional knapsack problem using a greedy algorithm."
items [block!] "flat block of [name weight value] triples"
max-weight [number!] "weight capacity of the knapsack"
][
;; build [name amount unit-value] triples, then sort by unit-value descending
ranked: copy []
foreach [name portion value] items [
repend ranked [name portion value / portion]
]
sort/skip/compare/reverse ranked 3 3 ;; skip=3 keeps triples together, compare on index 3
total-wt: total-val: 0.0
bagged: copy []
foreach [name portion value] ranked [
portion: min (max-weight - total-wt) portion ;; take all or whatever remains
total-wt: total-wt + portion
added-val: portion * value
total-val: total-val + added-val
repend bagged [name portion round/to added-val 0.01]
if total-wt >= max-weight [ break ] ;; bag is full
]
print "ITEM PORTION VALUE"
foreach [name portion value] bagged [
printf [10 8 8] reduce [name portion value]
]
print [ "^/TOTAL WEIGHT:" total-wt
"^/TOTAL VALUE:" round/to total-val 0.01 ]
]
knapsack [
"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
] 15

View file

@ -5,9 +5,9 @@ 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
lassign $item name mass value
lappend item [expr {$value / $mass}]
lset items [incr idx] $item
}
# Sort by unit prices
@ -18,18 +18,18 @@ proc continuousKnapsack {items massLimit} {
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
}
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

View file

@ -1,13 +1,13 @@
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}
{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

View file

@ -1,8 +1,8 @@
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"),
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] }