Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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] }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue