Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
125
Task/Knapsack-problem-0-1/ALGOL-68/knapsack-problem-0-1.alg
Normal file
125
Task/Knapsack-problem-0-1/ALGOL-68/knapsack-problem-0-1.alg
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
BEGIN # Knapsack problem: 0-1 #
|
||||
|
||||
PR read "bits.incl.a68" PR # include bit manipulation utilities #
|
||||
|
||||
# returns the next highest integer with the same number of set bits #
|
||||
PROC gospers hack = ( INT x )INT: # using Gosper's Hack #
|
||||
BEGIN
|
||||
INT c = x AND - x;
|
||||
INT r = x + c;
|
||||
ENTIER ( ENTIER ( ( r XOR x ) / 4 ) / c ) OR r
|
||||
END # gospers hack # ;
|
||||
|
||||
# knapsack items #
|
||||
MODE ITEM = STRUCT( STRING name, INT weight, value );
|
||||
[]ITEM possible items
|
||||
= ( ( "map", 9, 150 ), ( "compass", 13, 35 )
|
||||
, ( "water", 153, 200 ), ( "sandwich", 50, 160 )
|
||||
, ( "glucose", 15, 60 ), ( "tin", 68, 45 )
|
||||
, ( "banana", 27, 60 ), ( "apple", 39, 40 )
|
||||
, ( "cheese", 23, 30 ), ( "beer", 52, 10 )
|
||||
, ( "suntan cream", 11, 70 ), ( "camera", 32, 30 )
|
||||
, ( "t-shirt", 24, 15 ), ( "trousers", 48, 10 )
|
||||
, ( "umbrella", 73, 40 ), ( "waterproof trousers", 42, 70 )
|
||||
, ( "waterproof overclothes", 43, 75 ), ( "note-case", 22, 80 )
|
||||
, ( "sunglasses", 7, 20 ), ( "towel", 18, 12 )
|
||||
, ( "socks", 4, 50 ), ( "book", 30, 10 )
|
||||
);
|
||||
|
||||
[ 1 : UPB possible items ]ITEM sack items := possible items;
|
||||
|
||||
PRIO SWAP = 1;
|
||||
OP SWAP = ( REF ITEM a, b )VOID: BEGIN ITEM t = a; a := b; b := t END;
|
||||
|
||||
# sort the items into descending value order #
|
||||
FOR p TO UPB sack items - 1 DO
|
||||
FOR q FROM p + 1 TO UPB sack items DO
|
||||
IF value OF sack items[ q ] > value OF sack items[ p ] THEN sack items[ p ] SWAP sack items[ q ] FI
|
||||
OD
|
||||
OD;
|
||||
# calculate the maximum value of each number of items, #
|
||||
# if they could all be carried #
|
||||
[ 1 : UPB possible items ]INT possible value;
|
||||
INT curr value := 0;
|
||||
FOR p TO UPB sack items - 1 DO
|
||||
curr value +:= value OF sack items[ p ];
|
||||
possible value[ p ] := curr value
|
||||
OD;
|
||||
|
||||
# sort the items into descending weight order #
|
||||
FOR p TO UPB sack items - 1 DO
|
||||
FOR q FROM p + 1 TO UPB sack items DO
|
||||
IF weight OF sack items[ q ] > weight OF sack items[ p ] THEN sack items[ p ] SWAP sack items[ q ] FI
|
||||
OD
|
||||
OD;
|
||||
|
||||
# find the minimum and maximum number of items we can carry #
|
||||
# NB - assumes that each item weighs less than the maximum that can #
|
||||
# be carried #
|
||||
INT max weight = 400;
|
||||
INT min carry := 0;
|
||||
INT curr weight := weight OF sack items[ 1 ];
|
||||
FOR s pos FROM 2 TO UPB sack items WHILE curr weight <= max weight DO
|
||||
min carry +:= 1;
|
||||
curr weight +:= weight OF sack items[ s pos ]
|
||||
OD;
|
||||
INT max carry := 0;
|
||||
curr weight := weight OF sack items[ UPB sack items ];
|
||||
FOR s pos FROM UPB sack items - 1 BY -1 TO 1 WHILE curr weight <= max weight DO
|
||||
max carry +:= 1;
|
||||
curr weight +:= weight OF sack items[ s pos ]
|
||||
OD;
|
||||
|
||||
INT best items := 0;
|
||||
INT best value := 0;
|
||||
INT best weight := 0;
|
||||
|
||||
# for each possible number of items, find the best value for weight #
|
||||
# with that many items #
|
||||
# we use a bit mask to select the permutations, the maximum #
|
||||
# permutation is 2^length - 1 #
|
||||
INT max perm = 2 ^ UPB sack items - 1;
|
||||
|
||||
FOR item count FROM max carry BY -1 TO min carry WHILE best value < possible value[ item count ] DO
|
||||
# the lowest permutation is 2^number of items - 1 #
|
||||
INT perm := 2 ^ item count - 1;
|
||||
|
||||
WHILE perm <= max perm DO
|
||||
INT v := perm;
|
||||
INT weight := 0;
|
||||
INT value := 0;
|
||||
INT used := 0;
|
||||
FOR sack pos TO UPB sack items WHILE v > 0 AND weight <= max weight DO
|
||||
IF ODD v THEN
|
||||
weight +:= weight OF sack items[ sack pos ];
|
||||
value +:= value OF sack items[ sack pos ];
|
||||
used +:= 1
|
||||
FI;
|
||||
v OVERAB 2
|
||||
OD;
|
||||
IF weight <= max weight AND used = item count THEN
|
||||
IF value > best value THEN
|
||||
best items := perm;
|
||||
best value := value;
|
||||
best weight := weight
|
||||
FI
|
||||
FI;
|
||||
perm := gospers hack( perm )
|
||||
OD
|
||||
OD;
|
||||
|
||||
print( ( "At least ", whole( min carry, 0 ), " and at most ", whole( max carry, 0 ) ) );
|
||||
print( ( " items could be carried", newline ) );
|
||||
print( ( "Bast value: ", whole( best value, 0 ), " with weight: ", whole( best weight, 0 ), " is:", newline ) );
|
||||
INT items := best items;
|
||||
INT count := 0;
|
||||
FOR sack pos TO UPB sack items WHILE items > 0 DO
|
||||
IF ODD items THEN
|
||||
count +:= 1;
|
||||
print( ( " ", name OF sack items[ sack pos ], newline ) )
|
||||
FI;
|
||||
items OVERAB 2
|
||||
OD;
|
||||
print( ( "total: ", whole( count, 0 ), " items.", newline ) )
|
||||
|
||||
END
|
||||
109
Task/Knapsack-problem-0-1/Ada/knapsack-problem-0-1.adb
Normal file
109
Task/Knapsack-problem-0-1/Ada/knapsack-problem-0-1.adb
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
with Ada.Text_IO;
|
||||
with Ada.Strings.Unbounded;
|
||||
|
||||
procedure Knapsack_01 is
|
||||
package US renames Ada.Strings.Unbounded;
|
||||
|
||||
type Item is record
|
||||
Name : US.Unbounded_String;
|
||||
Weight : Positive;
|
||||
Value : Positive;
|
||||
Taken : Boolean;
|
||||
end record;
|
||||
|
||||
type Item_Array is array (Positive range <>) of Item;
|
||||
|
||||
function Total_Weight (Items : Item_Array; Untaken : Boolean := False) return Natural is
|
||||
Sum : Natural := 0;
|
||||
begin
|
||||
for I in Items'Range loop
|
||||
if Untaken or else Items (I).Taken then
|
||||
Sum := Sum + Items (I).Weight;
|
||||
end if;
|
||||
end loop;
|
||||
return Sum;
|
||||
end Total_Weight;
|
||||
|
||||
function Total_Value (Items : Item_Array; Untaken : Boolean := False) return Natural is
|
||||
Sum : Natural := 0;
|
||||
begin
|
||||
for I in Items'Range loop
|
||||
if Untaken or else Items (I).Taken then
|
||||
Sum := Sum + Items (I).Value;
|
||||
end if;
|
||||
end loop;
|
||||
return Sum;
|
||||
end Total_Value;
|
||||
|
||||
function Max (Left, Right : Natural) return Natural is
|
||||
begin
|
||||
if Right > Left then
|
||||
return Right;
|
||||
else
|
||||
return Left;
|
||||
end if;
|
||||
end Max;
|
||||
|
||||
procedure Solve_Knapsack_01 (Items : in out Item_Array;
|
||||
Weight_Limit : Positive := 400) is
|
||||
type W_Array is array (0..Items'Length, 0..Weight_Limit) of Natural;
|
||||
W : W_Array := (others => (others => 0));
|
||||
begin
|
||||
-- fill W
|
||||
for I in Items'Range loop
|
||||
for J in 1 .. Weight_Limit loop
|
||||
if Items (I).Weight > J then
|
||||
W (I, J) := W (I - 1, J);
|
||||
else
|
||||
W (I, J) := Max (W (I - 1, J),
|
||||
W (I - 1, J - Items (I).Weight) + Items (I).Value);
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
declare
|
||||
Rest : Natural := Weight_Limit;
|
||||
begin
|
||||
for I in reverse Items'Range loop
|
||||
if W (I, Rest) /= W (I - 1, Rest) then
|
||||
Items (I).Taken := True;
|
||||
Rest := Rest - Items (I).Weight;
|
||||
end if;
|
||||
end loop;
|
||||
end;
|
||||
end Solve_Knapsack_01;
|
||||
|
||||
All_Items : Item_Array :=
|
||||
( (US.To_Unbounded_String ("map"), 9, 150, False),
|
||||
(US.To_Unbounded_String ("compass"), 13, 35, False),
|
||||
(US.To_Unbounded_String ("water"), 153, 200, False),
|
||||
(US.To_Unbounded_String ("sandwich"), 50, 160, False),
|
||||
(US.To_Unbounded_String ("glucose"), 15, 60, False),
|
||||
(US.To_Unbounded_String ("tin"), 68, 45, False),
|
||||
(US.To_Unbounded_String ("banana"), 27, 60, False),
|
||||
(US.To_Unbounded_String ("apple"), 39, 40, False),
|
||||
(US.To_Unbounded_String ("cheese"), 23, 30, False),
|
||||
(US.To_Unbounded_String ("beer"), 52, 10, False),
|
||||
(US.To_Unbounded_String ("suntan cream"), 11, 70, False),
|
||||
(US.To_Unbounded_String ("camera"), 32, 30, False),
|
||||
(US.To_Unbounded_String ("t-shirt"), 24, 15, False),
|
||||
(US.To_Unbounded_String ("trousers"), 48, 10, False),
|
||||
(US.To_Unbounded_String ("umbrella"), 73, 40, False),
|
||||
(US.To_Unbounded_String ("waterproof trousers"), 42, 70, False),
|
||||
(US.To_Unbounded_String ("waterproof overclothes"), 43, 75, False),
|
||||
(US.To_Unbounded_String ("note-case"), 22, 80, False),
|
||||
(US.To_Unbounded_String ("sunglasses"), 7, 20, False),
|
||||
(US.To_Unbounded_String ("towel"), 18, 12, False),
|
||||
(US.To_Unbounded_String ("socks"), 4, 50, False),
|
||||
(US.To_Unbounded_String ("book"), 30, 10, False) );
|
||||
|
||||
begin
|
||||
Solve_Knapsack_01 (All_Items, 400);
|
||||
Ada.Text_IO.Put_Line ("Total Weight: " & Natural'Image (Total_Weight (All_Items)));
|
||||
Ada.Text_IO.Put_Line ("Total Value: " & Natural'Image (Total_Value (All_Items)));
|
||||
Ada.Text_IO.Put_Line ("Items:");
|
||||
for I in All_Items'Range loop
|
||||
if All_Items (I).Taken then
|
||||
Ada.Text_IO.Put_Line (" " & US.To_String (All_Items (I).Name));
|
||||
end if;
|
||||
end loop;
|
||||
end Knapsack_01;
|
||||
|
|
@ -41,7 +41,7 @@ int main( ) {
|
|||
int totalweight = 0 ;
|
||||
std::cout << "The following items should be packed in the knapsack:\n" ;
|
||||
for ( std::set<int>::const_iterator si = bestItems.begin( ) ;
|
||||
si != bestItems.end( ) ; si++ ) {
|
||||
si != bestItems.end( ) ; si++ ) {
|
||||
std::cout << (items.begin( ) + *si)->get<0>( ) << "\n" ;
|
||||
totalweight += (items.begin( ) + *si)->get<1>( ) ;
|
||||
}
|
||||
|
|
@ -61,35 +61,35 @@ int findBestPack( const std::vector<boost::tuple<std::string , int , int> > & it
|
|||
std::set<int> emptyset ;
|
||||
for ( int i = 0 ; i < n ; i++ ) {
|
||||
for ( int j = 0 ; j < weightlimit ; j++ ) {
|
||||
bestValues[ i ][ j ] = 0 ;
|
||||
solutionSets[ i ][ j ] = emptyset ;
|
||||
bestValues[ i ][ j ] = 0 ;
|
||||
solutionSets[ i ][ j ] = emptyset ;
|
||||
}
|
||||
}
|
||||
for ( int i = 0 ; i < n ; i++ ) {
|
||||
for ( int weight = 0 ; weight < weightlimit ; weight++ ) {
|
||||
if ( i == 0 )
|
||||
bestValues[ i ][ weight ] = 0 ;
|
||||
else {
|
||||
int itemweight = (items.begin( ) + i)->get<1>( ) ;
|
||||
if ( weight < itemweight ) {
|
||||
bestValues[ i ][ weight ] = bestValues[ i - 1 ][ weight ] ;
|
||||
solutionSets[ i ][ weight ] = solutionSets[ i - 1 ][ weight ] ;
|
||||
} else { // weight >= itemweight
|
||||
if ( bestValues[ i - 1 ][ weight - itemweight ] +
|
||||
(items.begin( ) + i)->get<2>( ) >
|
||||
bestValues[ i - 1 ][ weight ] ) {
|
||||
bestValues[ i ][ weight ] =
|
||||
bestValues[ i - 1 ][ weight - itemweight ] +
|
||||
(items.begin( ) + i)->get<2>( ) ;
|
||||
solutionSets[ i ][ weight ] =
|
||||
solutionSets[ i - 1 ][ weight - itemweight ] ;
|
||||
solutionSets[ i ][ weight ].insert( i ) ;
|
||||
}
|
||||
else {
|
||||
bestValues[ i ][ weight ] = bestValues[ i - 1 ][ weight ] ;
|
||||
solutionSets[ i ][ weight ] = solutionSets[ i - 1 ][ weight ] ;
|
||||
}
|
||||
}
|
||||
if ( i == 0 )
|
||||
bestValues[ i ][ weight ] = 0 ;
|
||||
else {
|
||||
int itemweight = (items.begin( ) + i)->get<1>( ) ;
|
||||
if ( weight < itemweight ) {
|
||||
bestValues[ i ][ weight ] = bestValues[ i - 1 ][ weight ] ;
|
||||
solutionSets[ i ][ weight ] = solutionSets[ i - 1 ][ weight ] ;
|
||||
} else { // weight >= itemweight
|
||||
if ( bestValues[ i - 1 ][ weight - itemweight ] +
|
||||
(items.begin( ) + i)->get<2>( ) >
|
||||
bestValues[ i - 1 ][ weight ] ) {
|
||||
bestValues[ i ][ weight ] =
|
||||
bestValues[ i - 1 ][ weight - itemweight ] +
|
||||
(items.begin( ) + i)->get<2>( ) ;
|
||||
solutionSets[ i ][ weight ] =
|
||||
solutionSets[ i - 1 ][ weight - itemweight ] ;
|
||||
solutionSets[ i ][ weight ].insert( i ) ;
|
||||
}
|
||||
else {
|
||||
bestValues[ i ][ weight ] = bestValues[ i - 1 ][ weight ] ;
|
||||
solutionSets[ i ][ weight ] = solutionSets[ i - 1 ][ weight ] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,28 +3,28 @@
|
|||
|
||||
(defun knapsack (max-weight items)
|
||||
(let ((cache (make-array (list (1+ max-weight) (1+ (length items)))
|
||||
:initial-element nil)))
|
||||
:initial-element nil)))
|
||||
|
||||
(labels ((knapsack1 (spc items)
|
||||
(if (not items) (return-from knapsack1 (list 0 0 '())))
|
||||
(mm-set (aref cache spc (length items))
|
||||
(let* ((i (first items))
|
||||
(w (second i))
|
||||
(v (third i))
|
||||
(x (knapsack1 spc (cdr items))))
|
||||
(if (> w spc) x
|
||||
(let* ((y (knapsack1 (- spc w) (cdr items)))
|
||||
(v (+ v (first y))))
|
||||
(if (< v (first x)) x
|
||||
(list v (+ w (second y)) (cons i (third y))))))))))
|
||||
(if (not items) (return-from knapsack1 (list 0 0 '())))
|
||||
(mm-set (aref cache spc (length items))
|
||||
(let* ((i (first items))
|
||||
(w (second i))
|
||||
(v (third i))
|
||||
(x (knapsack1 spc (cdr items))))
|
||||
(if (> w spc) x
|
||||
(let* ((y (knapsack1 (- spc w) (cdr items)))
|
||||
(v (+ v (first y))))
|
||||
(if (< v (first x)) x
|
||||
(list v (+ w (second y)) (cons i (third y))))))))))
|
||||
|
||||
(knapsack1 max-weight items))))
|
||||
|
||||
(print
|
||||
(knapsack 400
|
||||
'((map 9 150) (compass 13 35) (water 153 200) (sandwich 50 160)
|
||||
(glucose 15 60) (tin 68 45)(banana 27 60) (apple 39 40)
|
||||
(cheese 23 30) (beer 52 10) (cream 11 70) (camera 32 30)
|
||||
(T-shirt 24 15) (trousers 48 10) (umbrella 73 40)
|
||||
(trousers 42 70) (overclothes 43 75) (notecase 22 80)
|
||||
(glasses 7 20) (towel 18 12) (socks 4 50) (book 30 10))))
|
||||
'((map 9 150) (compass 13 35) (water 153 200) (sandwich 50 160)
|
||||
(glucose 15 60) (tin 68 45)(banana 27 60) (apple 39 40)
|
||||
(cheese 23 30) (beer 52 10) (cream 11 70) (camera 32 30)
|
||||
(T-shirt 24 15) (trousers 48 10) (umbrella 73 40)
|
||||
(trousers 42 70) (overclothes 43 75) (notecase 22 80)
|
||||
(glasses 7 20) (towel 18 12) (socks 4 50) (book 30 10))))
|
||||
|
|
|
|||
|
|
@ -55,13 +55,13 @@ function TBitIterator.Next(var Index: integer): boolean;
|
|||
begin
|
||||
Result:=False;
|
||||
while FNumber>0 do
|
||||
begin
|
||||
Result:=(FNumber and 1)=1;
|
||||
if Result then Index:=FIndex;
|
||||
FNumber:=FNumber shr 1;
|
||||
Inc(FIndex);
|
||||
if Result then break;
|
||||
end;
|
||||
begin
|
||||
Result:=(FNumber and 1)=1;
|
||||
if Result then Index:=FIndex;
|
||||
FNumber:=FNumber shr 1;
|
||||
Inc(FIndex);
|
||||
if Result then break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{=============================================================================}
|
||||
|
|
@ -78,10 +78,10 @@ try
|
|||
BI.Start(N);
|
||||
Weight:=0; Value:=0;
|
||||
while BI.Next(Inx) do
|
||||
begin
|
||||
Weight:=Weight+ItemsList[Inx].Weight;
|
||||
Value:=Value+ItemsList[Inx].Value;
|
||||
end;
|
||||
begin
|
||||
Weight:=Weight+ItemsList[Inx].Weight;
|
||||
Value:=Value+ItemsList[Inx].Value;
|
||||
end;
|
||||
finally BI.Free; end;
|
||||
end;
|
||||
|
||||
|
|
@ -104,30 +104,30 @@ Max:=1 shl Length(ItemsList)-1;
|
|||
BestValue:=0;
|
||||
{Iterate through all combinations of bits}
|
||||
for I:=1 to Max do
|
||||
begin
|
||||
{Get the sum of the weights and values}
|
||||
GetSums(I,WeightSum,ValueSum);
|
||||
{Ignore any weight greater than 400}
|
||||
if WeightSum>400 then continue;
|
||||
{Test if this is the best value so far}
|
||||
if ValueSum>BestValue then
|
||||
begin
|
||||
BestValue:=ValueSum;
|
||||
BestWeight:=WeightSum;
|
||||
BestIndex:=I;
|
||||
end;
|
||||
end;
|
||||
begin
|
||||
{Get the sum of the weights and values}
|
||||
GetSums(I,WeightSum,ValueSum);
|
||||
{Ignore any weight greater than 400}
|
||||
if WeightSum>400 then continue;
|
||||
{Test if this is the best value so far}
|
||||
if ValueSum>BestValue then
|
||||
begin
|
||||
BestValue:=ValueSum;
|
||||
BestWeight:=WeightSum;
|
||||
BestIndex:=I;
|
||||
end;
|
||||
end;
|
||||
{Display the best result}
|
||||
Memo.Lines.Add(' Item Weight Value');
|
||||
Memo.Lines.Add('---------------------------------------');
|
||||
BI.Start(BestIndex);
|
||||
while BI.Next(Inx) do
|
||||
begin
|
||||
S:=' '+Format('%-25s',[ItemsList[Inx].Name]);
|
||||
S:=S+Format('%5d',[ItemsList[Inx].Weight]);
|
||||
S:=S+Format('%7d',[ItemsList[Inx].Value]);
|
||||
Memo.Lines.Add(S);
|
||||
end;
|
||||
begin
|
||||
S:=' '+Format('%-25s',[ItemsList[Inx].Name]);
|
||||
S:=S+Format('%5d',[ItemsList[Inx].Weight]);
|
||||
S:=S+Format('%7d',[ItemsList[Inx].Value]);
|
||||
Memo.Lines.Add(S);
|
||||
end;
|
||||
Memo.Lines.Add('---------------------------------------');
|
||||
Memo.Lines.Add(Format('Total %6d %6d',[BestWeight,BestValue]));
|
||||
Memo.Lines.Add('Best Inx: '+IntToStr(BestIndex));
|
||||
|
|
|
|||
|
|
@ -15,20 +15,20 @@
|
|||
|
||||
;; compute best score (i), assuming best (i-1 rest) is known
|
||||
(define (score i restant)
|
||||
(if (< i 0) 0
|
||||
(hash-ref! H (t-idx i restant)
|
||||
(if ( >= restant (poids i))
|
||||
(max
|
||||
(score (1- i) restant)
|
||||
(+ (score (1- i) (- restant (poids i))) (valeur i)))
|
||||
(score (1- i) restant)))))
|
||||
(if (< i 0) 0
|
||||
(hash-ref! H (t-idx i restant)
|
||||
(if ( >= restant (poids i))
|
||||
(max
|
||||
(score (1- i) restant)
|
||||
(+ (score (1- i) (- restant (poids i))) (valeur i)))
|
||||
(score (1- i) restant)))))
|
||||
|
||||
;; compute best scores, starting from last item
|
||||
(define (task W)
|
||||
(define restant W)
|
||||
(define N (1- (table-count T)))
|
||||
(writeln 'total-value (score N W))
|
||||
(for/list ((i (in-range N -1 -1)))
|
||||
#:continue (= (t-get i restant) (t-get (1- i) restant))
|
||||
(set! restant (- restant (poids i)))
|
||||
(name i)))
|
||||
(writeln 'total-value (score N W))
|
||||
(for/list ((i (in-range N -1 -1)))
|
||||
#:continue (= (t-get i restant) (t-get (1- i) restant))
|
||||
(set! restant (- restant (poids i)))
|
||||
(name i)))
|
||||
|
|
|
|||
|
|
@ -1,40 +1,40 @@
|
|||
class
|
||||
APPLICATION
|
||||
APPLICATION
|
||||
|
||||
create
|
||||
make
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
local
|
||||
knapsack: KNAPSACKZEROONE
|
||||
do
|
||||
create knapsack.make (400)
|
||||
knapsack.add_item (create {ITEM}.make ("", 0, 0))
|
||||
knapsack.add_item (create {ITEM}.make ("map", 9, 150))
|
||||
knapsack.add_item (create {ITEM}.make ("compass", 13, 35))
|
||||
knapsack.add_item (create {ITEM}.make ("water", 153, 200))
|
||||
knapsack.add_item (create {ITEM}.make ("sandwich", 50, 160))
|
||||
knapsack.add_item (create {ITEM}.make ("glucose", 15, 60))
|
||||
knapsack.add_item (create {ITEM}.make ("tin", 68, 45))
|
||||
knapsack.add_item (create {ITEM}.make ("banana", 27, 60))
|
||||
knapsack.add_item (create {ITEM}.make ("apple", 39, 40))
|
||||
knapsack.add_item (create {ITEM}.make ("cheese", 23, 30))
|
||||
knapsack.add_item (create {ITEM}.make ("beer", 52, 10))
|
||||
knapsack.add_item (create {ITEM}.make ("suntan cream", 11, 70))
|
||||
knapsack.add_item (create {ITEM}.make ("camera", 32, 30))
|
||||
knapsack.add_item (create {ITEM}.make ("T-shirt", 24, 15))
|
||||
knapsack.add_item (create {ITEM}.make ("trousers", 48, 10))
|
||||
knapsack.add_item (create {ITEM}.make ("umbrella, ella ella", 73, 40))
|
||||
knapsack.add_item (create {ITEM}.make ("waterproof trousers", 42, 70))
|
||||
knapsack.add_item (create {ITEM}.make ("waterproof overclothes", 43, 75))
|
||||
knapsack.add_item (create {ITEM}.make ("note-case", 22, 80))
|
||||
knapsack.add_item (create {ITEM}.make ("sunglasses", 7, 20))
|
||||
knapsack.add_item (create {ITEM}.make ("towel", 18, 12))
|
||||
knapsack.add_item (create {ITEM}.make ("socks", 4, 50))
|
||||
knapsack.add_item (create {ITEM}.make ("book", 30, 10))
|
||||
knapsack.compute_solution
|
||||
end
|
||||
make
|
||||
local
|
||||
knapsack: KNAPSACKZEROONE
|
||||
do
|
||||
create knapsack.make (400)
|
||||
knapsack.add_item (create {ITEM}.make ("", 0, 0))
|
||||
knapsack.add_item (create {ITEM}.make ("map", 9, 150))
|
||||
knapsack.add_item (create {ITEM}.make ("compass", 13, 35))
|
||||
knapsack.add_item (create {ITEM}.make ("water", 153, 200))
|
||||
knapsack.add_item (create {ITEM}.make ("sandwich", 50, 160))
|
||||
knapsack.add_item (create {ITEM}.make ("glucose", 15, 60))
|
||||
knapsack.add_item (create {ITEM}.make ("tin", 68, 45))
|
||||
knapsack.add_item (create {ITEM}.make ("banana", 27, 60))
|
||||
knapsack.add_item (create {ITEM}.make ("apple", 39, 40))
|
||||
knapsack.add_item (create {ITEM}.make ("cheese", 23, 30))
|
||||
knapsack.add_item (create {ITEM}.make ("beer", 52, 10))
|
||||
knapsack.add_item (create {ITEM}.make ("suntan cream", 11, 70))
|
||||
knapsack.add_item (create {ITEM}.make ("camera", 32, 30))
|
||||
knapsack.add_item (create {ITEM}.make ("T-shirt", 24, 15))
|
||||
knapsack.add_item (create {ITEM}.make ("trousers", 48, 10))
|
||||
knapsack.add_item (create {ITEM}.make ("umbrella, ella ella", 73, 40))
|
||||
knapsack.add_item (create {ITEM}.make ("waterproof trousers", 42, 70))
|
||||
knapsack.add_item (create {ITEM}.make ("waterproof overclothes", 43, 75))
|
||||
knapsack.add_item (create {ITEM}.make ("note-case", 22, 80))
|
||||
knapsack.add_item (create {ITEM}.make ("sunglasses", 7, 20))
|
||||
knapsack.add_item (create {ITEM}.make ("towel", 18, 12))
|
||||
knapsack.add_item (create {ITEM}.make ("socks", 4, 50))
|
||||
knapsack.add_item (create {ITEM}.make ("book", 30, 10))
|
||||
knapsack.compute_solution
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,35 +1,35 @@
|
|||
class
|
||||
ITEM
|
||||
ITEM
|
||||
|
||||
create
|
||||
make, make_from_other
|
||||
make, make_from_other
|
||||
|
||||
feature
|
||||
|
||||
name: STRING
|
||||
name: STRING
|
||||
|
||||
weight: INTEGER
|
||||
weight: INTEGER
|
||||
|
||||
value: INTEGER
|
||||
value: INTEGER
|
||||
|
||||
make_from_other (other: ITEM)
|
||||
-- Item with name, weight and value set to 'other's name, weight and value.
|
||||
do
|
||||
name := other.name
|
||||
weight := other.weight
|
||||
value := other.value
|
||||
end
|
||||
make_from_other (other: ITEM)
|
||||
-- Item with name, weight and value set to 'other's name, weight and value.
|
||||
do
|
||||
name := other.name
|
||||
weight := other.weight
|
||||
value := other.value
|
||||
end
|
||||
|
||||
make (a_name: String; a_weight, a_value: INTEGER)
|
||||
-- Item with name, weight and value set to 'a_name', 'a_weight' and 'a_value'.
|
||||
require
|
||||
a_name /= Void
|
||||
a_weight >= 0
|
||||
a_value >= 0
|
||||
do
|
||||
name := a_name
|
||||
weight := a_weight
|
||||
value := a_value
|
||||
end
|
||||
make (a_name: String; a_weight, a_value: INTEGER)
|
||||
-- Item with name, weight and value set to 'a_name', 'a_weight' and 'a_value'.
|
||||
require
|
||||
a_name /= Void
|
||||
a_weight >= 0
|
||||
a_value >= 0
|
||||
do
|
||||
name := a_name
|
||||
weight := a_weight
|
||||
value := a_value
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,106 +1,106 @@
|
|||
class
|
||||
KNAPSACKZEROONE
|
||||
KNAPSACKZEROONE
|
||||
|
||||
create
|
||||
make
|
||||
make
|
||||
|
||||
feature
|
||||
|
||||
items: ARRAY [ITEM]
|
||||
items: ARRAY [ITEM]
|
||||
|
||||
max_weight: INTEGER
|
||||
max_weight: INTEGER
|
||||
|
||||
feature
|
||||
|
||||
make (a_max_weight: INTEGER)
|
||||
-- Make an empty knapsack.
|
||||
require
|
||||
a_max_weight >= 0
|
||||
do
|
||||
create items.make_empty
|
||||
max_weight := a_max_weight
|
||||
end
|
||||
make (a_max_weight: INTEGER)
|
||||
-- Make an empty knapsack.
|
||||
require
|
||||
a_max_weight >= 0
|
||||
do
|
||||
create items.make_empty
|
||||
max_weight := a_max_weight
|
||||
end
|
||||
|
||||
add_item (item: ITEM)
|
||||
-- Add 'item' to knapsack.
|
||||
local
|
||||
temp: ITEM
|
||||
do
|
||||
create temp.make_from_other (item)
|
||||
items.force (item, items.count + 1)
|
||||
end
|
||||
add_item (item: ITEM)
|
||||
-- Add 'item' to knapsack.
|
||||
local
|
||||
temp: ITEM
|
||||
do
|
||||
create temp.make_from_other (item)
|
||||
items.force (item, items.count + 1)
|
||||
end
|
||||
|
||||
compute_solution
|
||||
local
|
||||
M: ARRAY [INTEGER]
|
||||
n: INTEGER
|
||||
i, j: INTEGER
|
||||
w_i, v_i: INTEGER
|
||||
item_i: ITEM
|
||||
final_items: LINKED_LIST [ITEM]
|
||||
do
|
||||
n := items.count
|
||||
create M.make_filled (0, 1, n * max_weight)
|
||||
from
|
||||
i := 2
|
||||
until
|
||||
(i > n)
|
||||
loop
|
||||
from
|
||||
j := 1
|
||||
until
|
||||
j > max_weight
|
||||
loop
|
||||
item_i := items [i]
|
||||
w_i := item_i.weight
|
||||
if w_i <= j then
|
||||
v_i := item_i.value
|
||||
M [(i - 1) * max_weight + j] := max (M [(i - 2) * max_weight + j], M [(i - 2) * max_weight + j - w_i + 1] + v_i)
|
||||
else
|
||||
M [(i - 1) * max_weight + j] := M [(i - 2) * max_weight + j]
|
||||
end
|
||||
j := j + 1
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
io.put_string ("The final value of the knapsack will be: ")
|
||||
io.put_integer (M [(n - 1) * max_weight + max_weight]);
|
||||
io.new_line
|
||||
--compute the items that fit into the knapsack
|
||||
create final_items.make
|
||||
io.put_string ("We'll take the following items: %N");
|
||||
from
|
||||
i := n
|
||||
j := max_weight
|
||||
until
|
||||
i <= 1 or j <= 1
|
||||
loop
|
||||
item_i := items [i]
|
||||
w_i := item_i.weight
|
||||
if w_i <= j then
|
||||
v_i := item_i.value
|
||||
if M [(i - 1) * max_weight + j] = M [(i - 2) * max_weight + j] then
|
||||
else
|
||||
final_items.extend (item_i)
|
||||
io.put_string (item_i.name)
|
||||
io.new_line
|
||||
j := j - w_i
|
||||
end
|
||||
else
|
||||
end
|
||||
i := i - 1
|
||||
end
|
||||
end
|
||||
compute_solution
|
||||
local
|
||||
M: ARRAY [INTEGER]
|
||||
n: INTEGER
|
||||
i, j: INTEGER
|
||||
w_i, v_i: INTEGER
|
||||
item_i: ITEM
|
||||
final_items: LINKED_LIST [ITEM]
|
||||
do
|
||||
n := items.count
|
||||
create M.make_filled (0, 1, n * max_weight)
|
||||
from
|
||||
i := 2
|
||||
until
|
||||
(i > n)
|
||||
loop
|
||||
from
|
||||
j := 1
|
||||
until
|
||||
j > max_weight
|
||||
loop
|
||||
item_i := items [i]
|
||||
w_i := item_i.weight
|
||||
if w_i <= j then
|
||||
v_i := item_i.value
|
||||
M [(i - 1) * max_weight + j] := max (M [(i - 2) * max_weight + j], M [(i - 2) * max_weight + j - w_i + 1] + v_i)
|
||||
else
|
||||
M [(i - 1) * max_weight + j] := M [(i - 2) * max_weight + j]
|
||||
end
|
||||
j := j + 1
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
io.put_string ("The final value of the knapsack will be: ")
|
||||
io.put_integer (M [(n - 1) * max_weight + max_weight]);
|
||||
io.new_line
|
||||
--compute the items that fit into the knapsack
|
||||
create final_items.make
|
||||
io.put_string ("We'll take the following items: %N");
|
||||
from
|
||||
i := n
|
||||
j := max_weight
|
||||
until
|
||||
i <= 1 or j <= 1
|
||||
loop
|
||||
item_i := items [i]
|
||||
w_i := item_i.weight
|
||||
if w_i <= j then
|
||||
v_i := item_i.value
|
||||
if M [(i - 1) * max_weight + j] = M [(i - 2) * max_weight + j] then
|
||||
else
|
||||
final_items.extend (item_i)
|
||||
io.put_string (item_i.name)
|
||||
io.new_line
|
||||
j := j - w_i
|
||||
end
|
||||
else
|
||||
end
|
||||
i := i - 1
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE}
|
||||
|
||||
max (a, b: INTEGER): INTEGER
|
||||
-- Max of 'a' and 'b'.
|
||||
do
|
||||
Result := a
|
||||
if a < b then
|
||||
Result := b
|
||||
end
|
||||
end
|
||||
max (a, b: INTEGER): INTEGER
|
||||
-- Max of 'a' and 'b'.
|
||||
do
|
||||
Result := a
|
||||
if a < b then
|
||||
Result := b
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
(defun ks (max-w items)
|
||||
(let ((cache (make-vector (1+ (length items)) nil)))
|
||||
(dotimes (n (1+ (length items)))
|
||||
(setf (aref cache n) (make-hash-table :test 'eql)))
|
||||
(defun ks-emb (spc items)
|
||||
(let ((slot (gethash spc (aref cache (length items)))))
|
||||
(cond
|
||||
((null items) (list 0 0 '()))
|
||||
(slot slot)
|
||||
(t (puthash spc
|
||||
(let*
|
||||
((i (car items))
|
||||
(w (nth 1 i))
|
||||
(v (nth 2 i))
|
||||
(x (ks-emb spc (cdr items))))
|
||||
(cond
|
||||
((> w spc) x)
|
||||
(t
|
||||
(let* ((y (ks-emb (- spc w) (cdr items)))
|
||||
(v (+ v (car y))))
|
||||
(cond
|
||||
((< v (car x)) x)
|
||||
(t
|
||||
(list v (+ w (nth 1 y)) (cons i (nth 2 y)))))))))
|
||||
(aref cache (length items)))))))
|
||||
(ks-emb max-w items)))
|
||||
|
||||
(ks 400
|
||||
'((map 9 150) (compass 13 35) (water 153 200) (sandwich 50 160)
|
||||
(glucose 15 60) (tin 68 45)(banana 27 60) (apple 39 40)
|
||||
(cheese 23 30) (beer 52 10) (cream 11 70) (camera 32 30)
|
||||
(T-shirt 24 15) (trousers 48 10) (umbrella 73 40)
|
||||
(waterproof-trousers 42 70) (overclothes 43 75) (notecase 22 80)
|
||||
(glasses 7 20) (towel 18 12) (socks 4 50) (book 30 10)))
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
(defun best-rate (l1 l2)
|
||||
"predicate for sorting a list of elements regarding the value/weight rate"
|
||||
(let*
|
||||
((r1 (/ (* 1.0 (nth 2 l1)) (nth 1 l1)))
|
||||
(r2 (/ (* 1.0 (nth 2 l2)) (nth 1 l2))))
|
||||
(cond
|
||||
((> r1 r2) t)
|
||||
(t nil))))
|
||||
|
||||
(defun ks1 (l max)
|
||||
"return a complete list - complete means 'less than max-weight
|
||||
but add the next element is impossible'"
|
||||
(let ((l (sort l 'best-rate)))
|
||||
(cond
|
||||
((null l) l)
|
||||
((<= (nth 1 (car l)) max)
|
||||
(cons (car l) (ks1 (cdr l) (- max (nth 1 (car l))))))
|
||||
(t (ks1 (cdr l) max)))))
|
||||
|
||||
(defun totval (lol)
|
||||
"totalize values of a list - lol is not for laughing
|
||||
but for list of list"
|
||||
(cond
|
||||
((null lol) 0)
|
||||
(t
|
||||
(+
|
||||
(nth 2 (car lol))
|
||||
(totval (cdr lol))))))
|
||||
|
||||
(defun ks (l max)
|
||||
"browse the list to find the best subset to put in the f***ing knapsack"
|
||||
(cond
|
||||
((null (cdr l)) (list (car l)))
|
||||
(t
|
||||
(let*
|
||||
((x (ks1 l max))
|
||||
(y (ks (cdr l) max)))
|
||||
(cond
|
||||
((> (totval x) (totval y)) x)
|
||||
(t y))))))
|
||||
|
||||
(ks '((map 9 150) (compass 13 35) (water 153 200) (sandwich 50 160)
|
||||
(glucose 15 60) (tin 68 45)(banana 27 60) (apple 39 40)
|
||||
(cheese 23 30) (beer 52 10) (cream 11 70) (camera 32 30)
|
||||
(T-shirt 24 15) (trousers 48 10) (umbrella 73 40)
|
||||
(waterproof-trousers 42 70) (overclothes 43 75) (notecase 22 80)
|
||||
(glasses 7 20) (towel 18 12) (socks 4 50) (book 30 10)) 400)
|
||||
73
Task/Knapsack-problem-0-1/Frink/knapsack-problem-0-1.frink
Normal file
73
Task/Knapsack-problem-0-1/Frink/knapsack-problem-0-1.frink
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
knapsack[values, weights, capacity] :=
|
||||
{
|
||||
n = length[values]
|
||||
|
||||
if length[weights] != n
|
||||
{
|
||||
println["knapsack: length of values does not equal length of weights."]
|
||||
return undef
|
||||
}
|
||||
|
||||
V = new array[[n+1, capacity+1], 0]
|
||||
keep = new array[[n+1, capacity+1], false]
|
||||
|
||||
for i = 1 to n
|
||||
{
|
||||
for w = 0 to capacity
|
||||
{
|
||||
if weights@(i-1) <= w and (values@(i-1) + V@(i-1)@(w - weights@(i-1)) > V@(i-1)@w)
|
||||
{
|
||||
V@i@w = values@(i-1) + V@(i-1)@(w-weights@(i-1))
|
||||
keep@i@w = true
|
||||
} else
|
||||
{
|
||||
V@i@w = V@(i-1)@w
|
||||
keep@i@w = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
included = new array
|
||||
K = capacity
|
||||
for i = n to 1 step -1
|
||||
if keep@i@K == true
|
||||
{
|
||||
included.push[ [i-1, values@(i-1), weights@(i-1)] ]
|
||||
K = K - weights@(i-1)
|
||||
}
|
||||
|
||||
return concat[V@n@capacity, included.transpose[]]
|
||||
}
|
||||
|
||||
i= [["map", 9, 150],
|
||||
["compass", 13, 35],
|
||||
["water", 153, 200],
|
||||
["sandwich", 50, 160],
|
||||
["glucose", 15, 60],
|
||||
["tin", 68, 45],
|
||||
["banana", 27, 60],
|
||||
["apple", 39, 40],
|
||||
["cheese", 23, 30],
|
||||
["beer", 52, 10],
|
||||
["suntan cream", 11, 70],
|
||||
["camera", 32, 30],
|
||||
["T-shirt", 24, 15],
|
||||
["trousers", 48, 10],
|
||||
["umbrella", 73, 40],
|
||||
["waterproof trousers", 42, 70],
|
||||
["waterproof overclothes", 43, 75],
|
||||
["note-case", 22, 80],
|
||||
["sunglasses", 7, 20],
|
||||
["towel", 18, 12],
|
||||
["socks", 4, 50],
|
||||
["book", 30, 10]]
|
||||
|
||||
[maxval, indices, values, weights] = knapsack[i.getColumn[2], i.getColumn[1], 400]
|
||||
println["Items:"]
|
||||
|
||||
for ind = sort[indices]
|
||||
println[" " +i@ind@0]
|
||||
|
||||
println[]
|
||||
println["Total weight: " + sum[weights]]
|
||||
println["Total value: $maxval"]
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
inv = [("map",9,150), ("compass",13,35), ("water",153,200), ("sandwich",50,160),
|
||||
("glucose",15,60), ("tin",68,45), ("banana",27,60), ("apple",39,40),
|
||||
("cheese",23,30), ("beer",52,10), ("cream",11,70), ("camera",32,30),
|
||||
("tshirt",24,15), ("trousers",48,10), ("umbrella",73,40), ("trousers",42,70),
|
||||
("overclothes",43,75), ("notecase",22,80), ("sunglasses",7,20), ("towel",18,12),
|
||||
("socks",4,50), ("book",30,10)]
|
||||
("glucose",15,60), ("tin",68,45), ("banana",27,60), ("apple",39,40),
|
||||
("cheese",23,30), ("beer",52,10), ("cream",11,70), ("camera",32,30),
|
||||
("tshirt",24,15), ("trousers",48,10), ("umbrella",73,40), ("trousers",42,70),
|
||||
("overclothes",43,75), ("notecase",22,80), ("sunglasses",7,20), ("towel",18,12),
|
||||
("socks",4,50), ("book",30,10)]
|
||||
|
||||
-- get all combos of items under total weight sum; returns value sum and list
|
||||
combs [] _ = [ (0, []) ]
|
||||
combs ((name,w,v):rest) cap = combs rest cap ++
|
||||
if w > cap then [] else map (prepend (name,w,v)) (combs rest (cap - w))
|
||||
where prepend (name,w,v) (v2, lst) = (v2 + v, (name,w,v):lst)
|
||||
if w > cap then [] else map (prepend (name,w,v)) (combs rest (cap - w))
|
||||
where prepend (name,w,v) (v2, lst) = (v2 + v, (name,w,v):lst)
|
||||
|
||||
main = do
|
||||
putStr "Total value: "; print value
|
||||
mapM_ print items
|
||||
where (value, items) = maximum $ combs inv 400
|
||||
putStr "Total value: "; print value
|
||||
mapM_ print items
|
||||
where (value, items) = maximum $ combs inv 400
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
inv = [("map",9,150), ("compass",13,35), ("water",153,200), ("sandwich",50,160),
|
||||
("glucose",15,60), ("tin",68,45), ("banana",27,60), ("apple",39,40),
|
||||
("cheese",23,30), ("beer",52,10), ("cream",11,70), ("camera",32,30),
|
||||
("tshirt",24,15), ("trousers",48,10), ("umbrella",73,40), ("trousers",42,70),
|
||||
("overclothes",43,75), ("notecase",22,80), ("sunglasses",7,20), ("towel",18,12),
|
||||
("socks",4,50), ("book",30,10)]
|
||||
("glucose",15,60), ("tin",68,45), ("banana",27,60), ("apple",39,40),
|
||||
("cheese",23,30), ("beer",52,10), ("cream",11,70), ("camera",32,30),
|
||||
("tshirt",24,15), ("trousers",48,10), ("umbrella",73,40), ("trousers",42,70),
|
||||
("overclothes",43,75), ("notecase",22,80), ("sunglasses",7,20), ("towel",18,12),
|
||||
("socks",4,50), ("book",30,10)]
|
||||
|
||||
combs [] _ = (0, [])
|
||||
combs ((name,w,v):rest) cap
|
||||
| w <= cap = max skipthis $ prepend (name,w,v) (combs rest (cap - w))
|
||||
| otherwise = skipthis
|
||||
where prepend (name,w,v) (v2, lst) = (v2 + v, (name,w,v):lst)
|
||||
skipthis = combs rest cap
|
||||
| w <= cap = max skipthis $ prepend (name,w,v) (combs rest (cap - w))
|
||||
| otherwise = skipthis
|
||||
where prepend (name,w,v) (v2, lst) = (v2 + v, (name,w,v):lst)
|
||||
skipthis = combs rest cap
|
||||
|
||||
main = do print $ combs inv 400
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ inv = [("map",9,150), ("compass",13,35), ("water",153,200), ("sandwich",50,160),
|
|||
("sunglasses",7,20), ("towel",18,12), ("socks",4,50), ("book",30,10)]
|
||||
|
||||
knapsack = foldr addItem (repeat (0,[])) where
|
||||
addItem (name,w,v) list = left ++ zipWith max right newlist where
|
||||
newlist = map (\(val, names)->(val + v, name:names)) list
|
||||
(left,right) = splitAt w list
|
||||
addItem (name,w,v) list = left ++ zipWith max right newlist where
|
||||
newlist = map (\(val, names)->(val + v, name:names)) list
|
||||
(left,right) = splitAt w list
|
||||
|
||||
main = print $ (knapsack inv) !! 400
|
||||
|
|
|
|||
202
Task/Knapsack-problem-0-1/JavaScript/knapsack-problem-0-1-1.js
Normal file
202
Task/Knapsack-problem-0-1/JavaScript/knapsack-problem-0-1-1.js
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*global portviz:false, _:false */
|
||||
/*
|
||||
* 0-1 knapsack solution, recursive, memoized, approximate.
|
||||
*
|
||||
* credits:
|
||||
*
|
||||
* the Go implementation here:
|
||||
* http://rosettacode.org/mw/index.php?title=Knapsack_problem/0-1
|
||||
*
|
||||
* approximation details here:
|
||||
* http://math.mit.edu/~goemans/18434S06/knapsack-katherine.pdf
|
||||
*/
|
||||
portviz.knapsack = {};
|
||||
(function() {
|
||||
this.combiner = function(items, weightfn, valuefn) {
|
||||
// approximation guarantees result >= (1-e) * optimal
|
||||
var _epsilon = 0.01;
|
||||
var _p = _.max(_.map(items,valuefn));
|
||||
var _k = _epsilon * _p / items.length;
|
||||
|
||||
var _memo = (function(){
|
||||
var _mem = {};
|
||||
var _key = function(i, w) {
|
||||
return i + '::' + w;
|
||||
};
|
||||
return {
|
||||
get: function(i, w) {
|
||||
return _mem[_key(i,w)];
|
||||
},
|
||||
put: function(i, w, r) {
|
||||
_mem[_key(i,w)]=r;
|
||||
return r;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
var _m = function(i, w) {
|
||||
|
||||
i = Math.round(i);
|
||||
w = Math.round(w);
|
||||
|
||||
|
||||
if (i < 0 || w === 0) {
|
||||
// empty base case
|
||||
return {items: [], totalWeight: 0, totalValue: 0};
|
||||
}
|
||||
|
||||
var mm = _memo.get(i,w);
|
||||
if (!_.isUndefined(mm)) {
|
||||
return mm;
|
||||
}
|
||||
|
||||
var item = items[i];
|
||||
if (weightfn(item) > w) {
|
||||
//item does not fit, try the next item
|
||||
return _memo.put(i, w, _m(i-1, w));
|
||||
}
|
||||
// this item could fit.
|
||||
// are we better off excluding it?
|
||||
var excluded = _m(i-1, w);
|
||||
// or including it?
|
||||
var included = _m(i-1, w - weightfn(item));
|
||||
if (included.totalValue + Math.floor(valuefn(item)/_k) > excluded.totalValue) {
|
||||
// better off including it
|
||||
// make a copy of the list
|
||||
var i1 = included.items.slice();
|
||||
i1.push(item);
|
||||
return _memo.put(i, w,
|
||||
{items: i1,
|
||||
totalWeight: included.totalWeight + weightfn(item),
|
||||
totalValue: included.totalValue + Math.floor(valuefn(item)/_k)});
|
||||
}
|
||||
//better off excluding it
|
||||
return _memo.put(i,w, excluded);
|
||||
};
|
||||
return {
|
||||
/* one point */
|
||||
one: function(maxweight) {
|
||||
var scaled = _m(items.length - 1, maxweight);
|
||||
return {
|
||||
items: scaled.items,
|
||||
totalWeight: scaled.totalWeight,
|
||||
totalValue: scaled.totalValue * _k
|
||||
};
|
||||
},
|
||||
/* the entire EF */
|
||||
ef: function(maxweight, step) {
|
||||
return _.map(_.range(0, maxweight+1, step), function(weight) {
|
||||
var scaled = _m(items.length - 1, weight);
|
||||
return {
|
||||
items: scaled.items,
|
||||
totalWeight: scaled.totalWeight,
|
||||
totalValue: scaled.totalValue * _k
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
}).apply(portviz.knapsack);
|
||||
|
||||
/*global portviz:false, _:false */
|
||||
/*
|
||||
* after rosettacode.org/mw/index.php?title=Knapsack_problem/0-1
|
||||
*/
|
||||
var allwants = [
|
||||
{name:"map", weight:9, value: 150},
|
||||
{name:"compass", weight:13, value: 35},
|
||||
{name:"water", weight:153, value: 200},
|
||||
{name:"sandwich", weight: 50, value: 160},
|
||||
{name:"glucose", weight:15, value: 60},
|
||||
{name:"tin", weight:68, value: 45},
|
||||
{name:"banana", weight:27, value: 60},
|
||||
{name:"apple", weight:39, value: 40},
|
||||
{name:"cheese", weight:23, value: 30},
|
||||
{name:"beer", weight:52, value: 10},
|
||||
{name:"suntan cream", weight:11, value: 70},
|
||||
{name:"camera", weight:32, value: 30},
|
||||
{name:"T-shirt", weight:24, value: 15},
|
||||
{name:"trousers", weight:48, value: 10},
|
||||
{name:"umbrella", weight:73, value: 40},
|
||||
{name:"waterproof trousers", weight:42, value: 70},
|
||||
{name:"waterproof overclothes", weight:43, value: 75},
|
||||
{name:"note-case", weight:22, value: 80},
|
||||
{name:"sunglasses", weight:7, value: 20},
|
||||
{name:"towel", weight:18, value: 12},
|
||||
{name:"socks", weight:4, value: 50},
|
||||
{name:"book", weight:30, value: 10}
|
||||
];
|
||||
|
||||
var near = function(actual, expected, tolerance) {
|
||||
if (expected === 0 && actual === 0) return true;
|
||||
if (expected === 0) {
|
||||
return Math.abs(expected - actual) / actual < tolerance;
|
||||
}
|
||||
return Math.abs(expected - actual) / expected < tolerance;
|
||||
};
|
||||
|
||||
test("one knapsack", function() {
|
||||
var combiner =
|
||||
portviz.knapsack.combiner(allwants,
|
||||
function(x){return x.weight;},
|
||||
function(x){return x.value;});
|
||||
var oneport = combiner.one(400);
|
||||
ok(near(oneport.totalValue, 1030, 0.01), "correct total value");
|
||||
ok(near(oneport.totalValue, 1030, 0.01), "correct total value");
|
||||
equal(oneport.totalWeight, 396, "correct total weight");
|
||||
});
|
||||
|
||||
test("frontier", function() {
|
||||
var combiner =
|
||||
portviz.knapsack.combiner(allwants,
|
||||
function(x){return x.weight;},
|
||||
function(x){return x.value;});
|
||||
var ef = combiner.ef(400, 1);
|
||||
equal(ef.length, 401, "401 because it includes the endpoints");
|
||||
ef = combiner.ef(400, 40);
|
||||
equal(ef.length, 11, "11 because it includes the endpoints");
|
||||
var expectedTotalValue = [
|
||||
0,
|
||||
330,
|
||||
445,
|
||||
590,
|
||||
685,
|
||||
755,
|
||||
810,
|
||||
860,
|
||||
902,
|
||||
960,
|
||||
1030
|
||||
] ;
|
||||
_.each(ef, function(element, index) {
|
||||
// 15% error! bleah!
|
||||
ok(near(element.totalValue, expectedTotalValue[index], 0.15),
|
||||
'actual ' + element.totalValue + ' expected ' + expectedTotalValue[index]);
|
||||
});
|
||||
deepEqual(_.pluck(ef, 'totalWeight'), [
|
||||
0,
|
||||
39,
|
||||
74,
|
||||
118,
|
||||
158,
|
||||
200,
|
||||
236,
|
||||
266,
|
||||
316,
|
||||
354,
|
||||
396
|
||||
]);
|
||||
deepEqual(_.map(ef, function(x){return x.items.length;}), [
|
||||
0,
|
||||
4,
|
||||
6,
|
||||
7,
|
||||
9,
|
||||
10,
|
||||
10,
|
||||
12,
|
||||
14,
|
||||
11,
|
||||
12
|
||||
]);
|
||||
});
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>KNAPSACK 22 JavaScript</title> </head> <body> <noscript>Vkluch JS</noscript>
|
||||
|
||||
https://jdoodle.com/h/2Ut
|
||||
|
||||
rextester.com/BQYV50962
|
||||
|
||||
<script>
|
||||
|
||||
var n=22; G=400; a = Math.pow(2,n+1); // KNAPSACKj.js
|
||||
var dec, i, h, k, max, m, s;
|
||||
var L=[n], C=[n], j=[n], q=[a], d=[a]; e=[a];
|
||||
|
||||
document.write("<br><br># Kol Cena<br>")
|
||||
document.write("# Amo Price<br><br>")
|
||||
|
||||
L=[ 9,13,153,50,15,68,27,39,23,52,11,32,24,48,73,42,43,22,7,18,4,30 ]
|
||||
C=[ 150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,50,10 ]
|
||||
|
||||
for (i=0; i<n; i++)
|
||||
{ // L[i]=1+Math.floor(Math.random()*3)
|
||||
// C[i]=10+Math.floor(Math.random()*9);
|
||||
j[i]=0;
|
||||
document.write( (i+1) +" "+ L[i] +" "+ C[i] +"<br>")
|
||||
}
|
||||
for (i=0; i<a; i++) { q[i]=0; d[i]=0;}
|
||||
document.write("<br>")
|
||||
|
||||
document.write("Mx Kol St-st Schifr<br>")
|
||||
document.write("Mx Amo Price Cipher<br>")
|
||||
|
||||
for (h = a-1; h>(a-1)/2; h--)
|
||||
{ dec=h; e[h]=""
|
||||
|
||||
while (dec > 0)
|
||||
{ s = Math.floor(dec % 2);
|
||||
e[h] = s + e[h]; dec = Math.floor(dec/2);
|
||||
}
|
||||
|
||||
if (e[h] == "") {e[h] = "0";}
|
||||
e[h]= e[h].substr(1, e[h].length-1);
|
||||
|
||||
for (k=0; k<n; k++)
|
||||
{ j[k] = Number(e[h].substr(k,1));
|
||||
q[h]=q[h]+j[k]*C[k];
|
||||
d[h]=d[h]+L[k]*j[k];
|
||||
}
|
||||
|
||||
// if (d[h] <= G)
|
||||
// document.write("<br>"+ G +" "+ d[h] +" "+ q[h] +" "+ e[h])
|
||||
|
||||
} document.write("<br>")
|
||||
|
||||
max=0; m=1;
|
||||
for (i=0; i<a; i++)
|
||||
{ if (d[i]<=G && q[i]>max){ max=q[i]; m=i;}
|
||||
}
|
||||
|
||||
document.write("<br>"+ d[m] +" "+ q[m] +" "+ e[m] +"<br><br>")
|
||||
|
||||
document.write("Mx St-st Schifr<br>")
|
||||
document.write("Mx Price Cipher<br><br>")
|
||||
|
||||
</script>
|
||||
|
||||
</body> </html>
|
||||
|
|
@ -3,48 +3,48 @@ integer iMAX_WEIGHT = 400;
|
|||
integer iSTRIDE = 4;
|
||||
list lList = [];
|
||||
default {
|
||||
integer iNotecardLine = 0;
|
||||
state_entry() {
|
||||
llOwnerSay("Reading '"+sNOTECARD+"'");
|
||||
llGetNotecardLine(sNOTECARD, iNotecardLine);
|
||||
}
|
||||
dataserver(key kRequestId, string sData) {
|
||||
if(sData==EOF) {
|
||||
//llOwnerSay("EOF");
|
||||
lList = llListSort(lList, iSTRIDE, FALSE);
|
||||
integer iTotalWeight = 0;
|
||||
integer iTotalValue = 0;
|
||||
list lKnapsack = [];
|
||||
integer x = 0;
|
||||
while(x*iSTRIDE<llGetListLength(lList)) {
|
||||
float fValueWeight = (float)llList2String(lList, x*iSTRIDE);
|
||||
string sItem = (string)llList2String(lList, x*iSTRIDE+1);
|
||||
integer iWeight = (integer)llList2String(lList, x*iSTRIDE+2);
|
||||
integer iValue = (integer)llList2String(lList, x*iSTRIDE+3);
|
||||
if(iTotalWeight+iWeight<iMAX_WEIGHT) {
|
||||
iTotalWeight += iWeight;
|
||||
iTotalValue += iValue;
|
||||
lKnapsack += [sItem, iWeight, iValue, fValueWeight];
|
||||
}
|
||||
x++;
|
||||
}
|
||||
for(x=0 ; x*iSTRIDE<llGetListLength(lKnapsack) ; x++) {
|
||||
llOwnerSay((string)x+": "+llList2String(lList, x*iSTRIDE+1)+", "+llList2String(lList, x*iSTRIDE+2)+", "+llList2String(lList, x*iSTRIDE+3));
|
||||
integer iNotecardLine = 0;
|
||||
state_entry() {
|
||||
llOwnerSay("Reading '"+sNOTECARD+"'");
|
||||
llGetNotecardLine(sNOTECARD, iNotecardLine);
|
||||
}
|
||||
dataserver(key kRequestId, string sData) {
|
||||
if(sData==EOF) {
|
||||
//llOwnerSay("EOF");
|
||||
lList = llListSort(lList, iSTRIDE, FALSE);
|
||||
integer iTotalWeight = 0;
|
||||
integer iTotalValue = 0;
|
||||
list lKnapsack = [];
|
||||
integer x = 0;
|
||||
while(x*iSTRIDE<llGetListLength(lList)) {
|
||||
float fValueWeight = (float)llList2String(lList, x*iSTRIDE);
|
||||
string sItem = (string)llList2String(lList, x*iSTRIDE+1);
|
||||
integer iWeight = (integer)llList2String(lList, x*iSTRIDE+2);
|
||||
integer iValue = (integer)llList2String(lList, x*iSTRIDE+3);
|
||||
if(iTotalWeight+iWeight<iMAX_WEIGHT) {
|
||||
iTotalWeight += iWeight;
|
||||
iTotalValue += iValue;
|
||||
lKnapsack += [sItem, iWeight, iValue, fValueWeight];
|
||||
}
|
||||
x++;
|
||||
}
|
||||
for(x=0 ; x*iSTRIDE<llGetListLength(lKnapsack) ; x++) {
|
||||
llOwnerSay((string)x+": "+llList2String(lList, x*iSTRIDE+1)+", "+llList2String(lList, x*iSTRIDE+2)+", "+llList2String(lList, x*iSTRIDE+3));
|
||||
|
||||
}
|
||||
llOwnerSay("iTotalWeight="+(string)iTotalWeight);
|
||||
llOwnerSay("iTotalValue="+(string)iTotalValue);
|
||||
} else {
|
||||
//llOwnerSay((string)iNotecardLine+": "+sData);
|
||||
if(llStringTrim(sData, STRING_TRIM)!="") {
|
||||
list lParsed = llParseString2List(sData, [","], []);
|
||||
string sItem = llStringTrim(llList2String(lParsed, 0), STRING_TRIM);
|
||||
integer iWeight = (integer)llStringTrim(llList2String(lParsed, 1), STRING_TRIM);
|
||||
integer iValue = (integer)llStringTrim(llList2String(lParsed, 2), STRING_TRIM);
|
||||
float fValueWeight = (1.0*iValue)/iWeight;
|
||||
lList += [fValueWeight, sItem, iWeight, iValue];
|
||||
}
|
||||
llGetNotecardLine(sNOTECARD, ++iNotecardLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
llOwnerSay("iTotalWeight="+(string)iTotalWeight);
|
||||
llOwnerSay("iTotalValue="+(string)iTotalValue);
|
||||
} else {
|
||||
//llOwnerSay((string)iNotecardLine+": "+sData);
|
||||
if(llStringTrim(sData, STRING_TRIM)!="") {
|
||||
list lParsed = llParseString2List(sData, [","], []);
|
||||
string sItem = llStringTrim(llList2String(lParsed, 0), STRING_TRIM);
|
||||
integer iWeight = (integer)llStringTrim(llList2String(lParsed, 1), STRING_TRIM);
|
||||
integer iValue = (integer)llStringTrim(llList2String(lParsed, 2), STRING_TRIM);
|
||||
float fValueWeight = (1.0*iValue)/iWeight;
|
||||
lList += [fValueWeight, sItem, iWeight, iValue];
|
||||
}
|
||||
llGetNotecardLine(sNOTECARD, ++iNotecardLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,60 +4,60 @@ global neededItems = #()
|
|||
global totalValue = 0
|
||||
struct kn_item
|
||||
(
|
||||
item, weight, value
|
||||
item, weight, value
|
||||
)
|
||||
|
||||
itemStrings = #("map#9#150","compass#13#35","water#153#200", \
|
||||
"sandwich#50#160","glucose#15#60","tin#68#45", \
|
||||
"banana#27#60","apple#39#40","cheese#23#30", \
|
||||
"beer#52#10","suntan cream#11#70","camera#32#30", \
|
||||
"T-shirt#24#15","trousers#48#10","umbrella#73#40", \
|
||||
"waterproof trousers#42#70","waterproof overclothes#43#75", \
|
||||
"note-case#22#80","sunglasses#7#20", "towel#18#12", \
|
||||
"socks#4#50","book#30#10")
|
||||
"sandwich#50#160","glucose#15#60","tin#68#45", \
|
||||
"banana#27#60","apple#39#40","cheese#23#30", \
|
||||
"beer#52#10","suntan cream#11#70","camera#32#30", \
|
||||
"T-shirt#24#15","trousers#48#10","umbrella#73#40", \
|
||||
"waterproof trousers#42#70","waterproof overclothes#43#75", \
|
||||
"note-case#22#80","sunglasses#7#20", "towel#18#12", \
|
||||
"socks#4#50","book#30#10")
|
||||
|
||||
fn sortByValue a b =
|
||||
(
|
||||
if a[1].value > b[1].value then return -1
|
||||
else
|
||||
(
|
||||
if a[1].value == b[1].value then return 0
|
||||
else return 1
|
||||
)
|
||||
if a[1].value > b[1].value then return -1
|
||||
else
|
||||
(
|
||||
if a[1].value == b[1].value then return 0
|
||||
else return 1
|
||||
)
|
||||
)
|
||||
fn chooseBestItem maximumWeight: items: =
|
||||
(
|
||||
local itemsCopy = deepcopy items
|
||||
local possibleItems = #()
|
||||
for i = 1 to itemsCopy.count do
|
||||
(
|
||||
if itemsCopy[i].weight <= maximumWeight do append possibleItems (#(itemsCopy[i],i))
|
||||
)
|
||||
qsort possibleItems sortByValue
|
||||
if possibleItems.count > 0 then return possibleItems[1] else return 0
|
||||
local itemsCopy = deepcopy items
|
||||
local possibleItems = #()
|
||||
for i = 1 to itemsCopy.count do
|
||||
(
|
||||
if itemsCopy[i].weight <= maximumWeight do append possibleItems (#(itemsCopy[i],i))
|
||||
)
|
||||
qsort possibleItems sortByValue
|
||||
if possibleItems.count > 0 then return possibleItems[1] else return 0
|
||||
)
|
||||
|
||||
|
||||
for i = 1 to itemStrings.count do
|
||||
(
|
||||
local split = filterstring itemStrings[i] "#"
|
||||
local itemStruct = kn_item item:split[1] weight:(split[2] as integer) \
|
||||
value:(split[3] as integer)
|
||||
appendifunique globalItems itemstruct
|
||||
local split = filterstring itemStrings[i] "#"
|
||||
local itemStruct = kn_item item:split[1] weight:(split[2] as integer) \
|
||||
value:(split[3] as integer)
|
||||
appendifunique globalItems itemstruct
|
||||
)
|
||||
|
||||
while usedMass < 400 do
|
||||
(
|
||||
local item = chooseBestItem maximumweight:(400-usedMass) items:(globalItems)
|
||||
if item != 0 then
|
||||
(
|
||||
deleteitem globalItems (item[2])
|
||||
appendifunique neededItems item[1]
|
||||
usedMass += item[1].weight
|
||||
) else exit
|
||||
local item = chooseBestItem maximumweight:(400-usedMass) items:(globalItems)
|
||||
if item != 0 then
|
||||
(
|
||||
deleteitem globalItems (item[2])
|
||||
appendifunique neededItems item[1]
|
||||
usedMass += item[1].weight
|
||||
) else exit
|
||||
)
|
||||
for i in neededitems do
|
||||
(
|
||||
format "Item name: %, weight: %, value:%\n" i.item i.weight i.value
|
||||
totalValue += i.value
|
||||
format "Item name: %, weight: %, value:%\n" i.item i.weight i.value
|
||||
totalValue += i.value
|
||||
)
|
||||
format "Total mass: %, Total Value: %\n" usedMass totalValue
|
||||
|
|
|
|||
|
|
@ -4,26 +4,26 @@ items := ["map","compass","water","sandwich","glucose","tin","banana","apple","c
|
|||
acc := Array(1..numelems(vals)+1,1..400+1,1,fill=0):
|
||||
len := numelems(weights):
|
||||
for i from 2 to len+1 do #number of items picked + 1
|
||||
for j from 2 to 401 do #weight capacity left + 1
|
||||
if weights[i-1] > j-1 then
|
||||
acc[i,j] := acc[i-1, j]:
|
||||
else
|
||||
acc[i,j] := max(acc[i-1,j], acc[i-1, j-weights[i-1]]+vals[i-1]):
|
||||
end if:
|
||||
end do:
|
||||
for j from 2 to 401 do #weight capacity left + 1
|
||||
if weights[i-1] > j-1 then
|
||||
acc[i,j] := acc[i-1, j]:
|
||||
else
|
||||
acc[i,j] := max(acc[i-1,j], acc[i-1, j-weights[i-1]]+vals[i-1]):
|
||||
end if:
|
||||
end do:
|
||||
end do:
|
||||
printf("Total Value is %d\n", acc[len+1, 401]):
|
||||
count := 0:
|
||||
i := len+1:
|
||||
j := 401:
|
||||
while (i>1 and j>1) do
|
||||
if acc[i,j] <> acc[i-1,j] then
|
||||
printf("Item: %s\n", items[i-1]):
|
||||
count := count+weights[i-1]:
|
||||
j := j-weights[i-1]:
|
||||
i := i-1:
|
||||
else
|
||||
i := i-1:
|
||||
end if:
|
||||
if acc[i,j] <> acc[i-1,j] then
|
||||
printf("Item: %s\n", items[i-1]):
|
||||
count := count+weights[i-1]:
|
||||
j := j-weights[i-1]:
|
||||
i := i-1:
|
||||
else
|
||||
i := i-1:
|
||||
end if:
|
||||
end do:
|
||||
printf("Total Weight is %d\n", count):
|
||||
|
|
|
|||
|
|
@ -19,28 +19,28 @@ maximize knap_value: sum{t in Items} take[t] * value[t];
|
|||
data;
|
||||
|
||||
param : Items : weight value :=
|
||||
map 9 150
|
||||
compass 13 35
|
||||
water 153 200
|
||||
sandwich 50 160
|
||||
glucose 15 60
|
||||
tin 68 45
|
||||
banana 27 60
|
||||
apple 39 40
|
||||
cheese 23 30
|
||||
beer 52 10
|
||||
suntancream 11 70
|
||||
camera 32 30
|
||||
T-shirt 24 15
|
||||
trousers 48 10
|
||||
umbrella 73 40
|
||||
w-trousers 42 70
|
||||
w-overclothes 43 75
|
||||
note-case 22 80
|
||||
sunglasses 7 20
|
||||
towel 18 12
|
||||
socks 4 50
|
||||
book 30 10
|
||||
map 9 150
|
||||
compass 13 35
|
||||
water 153 200
|
||||
sandwich 50 160
|
||||
glucose 15 60
|
||||
tin 68 45
|
||||
banana 27 60
|
||||
apple 39 40
|
||||
cheese 23 30
|
||||
beer 52 10
|
||||
suntancream 11 70
|
||||
camera 32 30
|
||||
T-shirt 24 15
|
||||
trousers 48 10
|
||||
umbrella 73 40
|
||||
w-trousers 42 70
|
||||
w-overclothes 43 75
|
||||
note-case 22 80
|
||||
sunglasses 7 20
|
||||
towel 18 12
|
||||
socks 4 50
|
||||
book 30 10
|
||||
;
|
||||
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -12,61 +12,61 @@
|
|||
|
||||
function knapSolveFast2($w, $v, $i, $aW, &$m) {
|
||||
|
||||
global $numcalls;
|
||||
$numcalls ++;
|
||||
// echo "Called with i=$i, aW=$aW<br>";
|
||||
global $numcalls;
|
||||
$numcalls ++;
|
||||
// echo "Called with i=$i, aW=$aW<br>";
|
||||
|
||||
// Return memo if we have one
|
||||
if (isset($m[$i][$aW])) {
|
||||
return array( $m[$i][$aW], $m['picked'][$i][$aW] );
|
||||
} else {
|
||||
// Return memo if we have one
|
||||
if (isset($m[$i][$aW])) {
|
||||
return array( $m[$i][$aW], $m['picked'][$i][$aW] );
|
||||
} else {
|
||||
|
||||
// At end of decision branch
|
||||
if ($i == 0) {
|
||||
if ($w[$i] <= $aW) { // Will this item fit?
|
||||
$m[$i][$aW] = $v[$i]; // Memo this item
|
||||
$m['picked'][$i][$aW] = array($i); // and the picked item
|
||||
return array($v[$i],array($i)); // Return the value of this item and add it to the picked list
|
||||
// At end of decision branch
|
||||
if ($i == 0) {
|
||||
if ($w[$i] <= $aW) { // Will this item fit?
|
||||
$m[$i][$aW] = $v[$i]; // Memo this item
|
||||
$m['picked'][$i][$aW] = array($i); // and the picked item
|
||||
return array($v[$i],array($i)); // Return the value of this item and add it to the picked list
|
||||
|
||||
} else {
|
||||
// Won't fit
|
||||
$m[$i][$aW] = 0; // Memo zero
|
||||
$m['picked'][$i][$aW] = array(); // and a blank array entry...
|
||||
return array(0,array()); // Return nothing
|
||||
}
|
||||
}
|
||||
|
||||
// Not at end of decision branch..
|
||||
// Get the result of the next branch (without this one)
|
||||
list ($without_i, $without_PI) = knapSolveFast2($w, $v, $i-1, $aW, $m);
|
||||
} else {
|
||||
// Won't fit
|
||||
$m[$i][$aW] = 0; // Memo zero
|
||||
$m['picked'][$i][$aW] = array(); // and a blank array entry...
|
||||
return array(0,array()); // Return nothing
|
||||
}
|
||||
}
|
||||
|
||||
if ($w[$i] > $aW) { // Does it return too many?
|
||||
|
||||
$m[$i][$aW] = $without_i; // Memo without including this one
|
||||
$m['picked'][$i][$aW] = $without_PI; // and a blank array entry...
|
||||
return array($without_i, $without_PI); // and return it
|
||||
// Not at end of decision branch..
|
||||
// Get the result of the next branch (without this one)
|
||||
list ($without_i, $without_PI) = knapSolveFast2($w, $v, $i-1, $aW, $m);
|
||||
|
||||
} else {
|
||||
|
||||
// Get the result of the next branch (WITH this one picked, so available weight is reduced)
|
||||
list ($with_i,$with_PI) = knapSolveFast2($w, $v, ($i-1), ($aW - $w[$i]), $m);
|
||||
$with_i += $v[$i]; // ..and add the value of this one..
|
||||
|
||||
// Get the greater of WITH or WITHOUT
|
||||
if ($with_i > $without_i) {
|
||||
$res = $with_i;
|
||||
$picked = $with_PI;
|
||||
array_push($picked,$i);
|
||||
} else {
|
||||
$res = $without_i;
|
||||
$picked = $without_PI;
|
||||
}
|
||||
|
||||
$m[$i][$aW] = $res; // Store it in the memo
|
||||
$m['picked'][$i][$aW] = $picked; // and store the picked item
|
||||
return array ($res,$picked); // and then return it
|
||||
}
|
||||
}
|
||||
if ($w[$i] > $aW) { // Does it return too many?
|
||||
|
||||
$m[$i][$aW] = $without_i; // Memo without including this one
|
||||
$m['picked'][$i][$aW] = $without_PI; // and a blank array entry...
|
||||
return array($without_i, $without_PI); // and return it
|
||||
|
||||
} else {
|
||||
|
||||
// Get the result of the next branch (WITH this one picked, so available weight is reduced)
|
||||
list ($with_i,$with_PI) = knapSolveFast2($w, $v, ($i-1), ($aW - $w[$i]), $m);
|
||||
$with_i += $v[$i]; // ..and add the value of this one..
|
||||
|
||||
// Get the greater of WITH or WITHOUT
|
||||
if ($with_i > $without_i) {
|
||||
$res = $with_i;
|
||||
$picked = $with_PI;
|
||||
array_push($picked,$i);
|
||||
} else {
|
||||
$res = $without_i;
|
||||
$picked = $without_PI;
|
||||
}
|
||||
|
||||
$m[$i][$aW] = $res; // Store it in the memo
|
||||
$m['picked'][$i][$aW] = $picked; // and store the picked item
|
||||
return array ($res,$picked); // and then return it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -92,9 +92,9 @@ echo "<table border cellspacing=0>";
|
|||
echo "<tr><td>Item</td><td>Value</td><td>Weight</td></tr>";
|
||||
$totalVal = $totalWt = 0;
|
||||
foreach($pickedItems as $key) {
|
||||
$totalVal += $v4[$key];
|
||||
$totalWt += $w4[$key];
|
||||
echo "<tr><td>".$items4[$key]."</td><td>".$v4[$key]."</td><td>".$w4[$key]."</td></tr>";
|
||||
$totalVal += $v4[$key];
|
||||
$totalWt += $w4[$key];
|
||||
echo "<tr><td>".$items4[$key]."</td><td>".$v4[$key]."</td><td>".$w4[$key]."</td></tr>";
|
||||
}
|
||||
echo "<tr><td align=right><b>Totals</b></td><td>$totalVal</td><td>$totalWt</td></tr>";
|
||||
echo "</table><hr>";
|
||||
|
|
|
|||
|
|
@ -9,25 +9,25 @@
|
|||
|
||||
function knapSolve($w,$v,$i,$aW) {
|
||||
|
||||
global $numcalls;
|
||||
$numcalls ++;
|
||||
// echo "Called with i=$i, aW=$aW<br>";
|
||||
global $numcalls;
|
||||
$numcalls ++;
|
||||
// echo "Called with i=$i, aW=$aW<br>";
|
||||
|
||||
if ($i == 0) {
|
||||
if ($w[$i] <= $aW) {
|
||||
return $v[$i];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
$without_i = knapSolve($w, $v, $i-1, $aW);
|
||||
if ($w[$i] > $aW) {
|
||||
return $without_i;
|
||||
} else {
|
||||
$with_i = $v[$i] + knapSolve($w, $v, ($i-1), ($aW - $w[$i]));
|
||||
return max($with_i, $without_i);
|
||||
}
|
||||
if ($i == 0) {
|
||||
if ($w[$i] <= $aW) {
|
||||
return $v[$i];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
$without_i = knapSolve($w, $v, $i-1, $aW);
|
||||
if ($w[$i] > $aW) {
|
||||
return $without_i;
|
||||
} else {
|
||||
$with_i = $v[$i] + knapSolve($w, $v, ($i-1), ($aW - $w[$i]));
|
||||
return max($with_i, $without_i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -44,36 +44,36 @@ function knapSolve($w,$v,$i,$aW) {
|
|||
|
||||
function knapSolveFast($w,$v,$i,$aW,&$m) { // Note: We use &$m because the function writes to the $m array
|
||||
|
||||
global $numcalls;
|
||||
$numcalls ++;
|
||||
// echo "Called with i=$i, aW=$aW<br>";
|
||||
global $numcalls;
|
||||
$numcalls ++;
|
||||
// echo "Called with i=$i, aW=$aW<br>";
|
||||
|
||||
// Return memo if we have one
|
||||
if (isset($m[$i][$aW])) {
|
||||
return $m[$i][$aW];
|
||||
} else {
|
||||
// Return memo if we have one
|
||||
if (isset($m[$i][$aW])) {
|
||||
return $m[$i][$aW];
|
||||
} else {
|
||||
|
||||
if ($i == 0) {
|
||||
if ($w[$i] <= $aW) {
|
||||
$m[$i][$aW] = $v[$i]; // save memo
|
||||
return $v[$i];
|
||||
} else {
|
||||
$m[$i][$aW] = 0; // save memo
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
$without_i = knapSolveFast($w, $v, $i-1, $aW,$m);
|
||||
if ($w[$i] > $aW) {
|
||||
$m[$i][$aW] = $without_i; // save memo
|
||||
return $without_i;
|
||||
} else {
|
||||
$with_i = $v[$i] + knapSolveFast($w, $v, ($i-1), ($aW - $w[$i]),$m);
|
||||
$res = max($with_i, $without_i);
|
||||
$m[$i][$aW] = $res; // save memo
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
if ($i == 0) {
|
||||
if ($w[$i] <= $aW) {
|
||||
$m[$i][$aW] = $v[$i]; // save memo
|
||||
return $v[$i];
|
||||
} else {
|
||||
$m[$i][$aW] = 0; // save memo
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
$without_i = knapSolveFast($w, $v, $i-1, $aW,$m);
|
||||
if ($w[$i] > $aW) {
|
||||
$m[$i][$aW] = $without_i; // save memo
|
||||
return $without_i;
|
||||
} else {
|
||||
$with_i = $v[$i] + knapSolveFast($w, $v, ($i-1), ($aW - $w[$i]),$m);
|
||||
$res = max($with_i, $without_i);
|
||||
$m[$i][$aW] = $res; // save memo
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
my $raw = <<'TABLE';
|
||||
map 9 150
|
||||
compass 13 35
|
||||
water 153 200
|
||||
sandwich 50 160
|
||||
glucose 15 60
|
||||
tin 68 45
|
||||
banana 27 60
|
||||
apple 39 40
|
||||
cheese 23 30
|
||||
beer 52 10
|
||||
suntancream 11 70
|
||||
camera 32 30
|
||||
T-shirt 24 15
|
||||
trousers 48 10
|
||||
umbrella 73 40
|
||||
waterproof trousers 42 70
|
||||
waterproof overclothes 43 75
|
||||
note-case 22 80
|
||||
sunglasses 7 20
|
||||
towel 18 12
|
||||
socks 4 50
|
||||
book 30 10
|
||||
map 9 150
|
||||
compass 13 35
|
||||
water 153 200
|
||||
sandwich 50 160
|
||||
glucose 15 60
|
||||
tin 68 45
|
||||
banana 27 60
|
||||
apple 39 40
|
||||
cheese 23 30
|
||||
beer 52 10
|
||||
suntancream 11 70
|
||||
camera 32 30
|
||||
T-shirt 24 15
|
||||
trousers 48 10
|
||||
umbrella 73 40
|
||||
waterproof trousers 42 70
|
||||
waterproof overclothes 43 75
|
||||
note-case 22 80
|
||||
sunglasses 7 20
|
||||
towel 18 12
|
||||
socks 4 50
|
||||
book 30 10
|
||||
TABLE
|
||||
|
||||
my (@name, @weight, @value);
|
||||
|
|
|
|||
51
Task/Knapsack-problem-0-1/Pluto/knapsack-problem-0-1.pluto
Normal file
51
Task/Knapsack-problem-0-1/Pluto/knapsack-problem-0-1.pluto
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
local fmt = require "fmt"
|
||||
|
||||
local wants = {
|
||||
{"map", 9, 150},
|
||||
{"compass", 13, 35},
|
||||
{"water", 153, 200},
|
||||
{"sandwich", 50, 160},
|
||||
{"glucose", 15, 60},
|
||||
{"tin", 68, 45},
|
||||
{"banana", 27, 60},
|
||||
{"apple", 39, 40},
|
||||
{"cheese", 23, 30},
|
||||
{"beer", 52, 10},
|
||||
{"suntan cream", 11, 70},
|
||||
{"camera", 32, 30},
|
||||
{"T-shirt", 24, 15},
|
||||
{"trousers", 48, 10},
|
||||
{"umbrella", 73, 40},
|
||||
{"waterproof trousers", 42, 70},
|
||||
{"waterproof overclothes", 43, 75},
|
||||
{"note-case", 22, 80},
|
||||
{"sunglasses", 7, 20},
|
||||
{"towel", 18, 12},
|
||||
{"socks", 4, 50},
|
||||
{"book", 30, 10}
|
||||
}
|
||||
|
||||
local function m(i, w)
|
||||
if i < 1 or w == 0 then return {}, 0, 0 end
|
||||
if wants[i][2] > w then return m(i - 1, w) end
|
||||
local i0, w0, v0 = m(i - 1, w)
|
||||
local i1, w1, v1 = m(i - 1, w - wants[i][2])
|
||||
v1 += wants[i][3]
|
||||
if v1 > v0 then
|
||||
i1:insert(wants[i])
|
||||
return i1, w1 + wants[i][2], v1
|
||||
end
|
||||
return i0, w0, v0
|
||||
end
|
||||
|
||||
local max_wt = 400
|
||||
local items, tw, tv = m(#wants, max_wt)
|
||||
print($"Max weight: {max_wt}\n")
|
||||
print("Item Weight Value")
|
||||
print("------------------------------------")
|
||||
for i = 1, #items do
|
||||
local [item, w, v] = items[i]
|
||||
fmt.print("%-22s %3d %4s", item, w, v)
|
||||
end
|
||||
print(" --- ----")
|
||||
fmt.print("totals %3d %4d", tw, tv)
|
||||
|
|
@ -1,51 +1,51 @@
|
|||
:- use_module(library(simplex)).
|
||||
|
||||
knapsack :-
|
||||
L = [
|
||||
(map, 9, 150),
|
||||
(compass, 13, 35),
|
||||
(water, 153, 200),
|
||||
(sandwich, 50, 160),
|
||||
(glucose, 15, 60),
|
||||
(tin, 68, 45),
|
||||
(banana, 27, 60),
|
||||
(apple, 39, 40),
|
||||
(cheese, 23, 30),
|
||||
(beer, 52, 10),
|
||||
('suntan cream', 11, 70),
|
||||
(camera, 32, 30),
|
||||
('t-shirt', 24, 15),
|
||||
(trousers, 48, 10),
|
||||
(umbrella, 73, 40),
|
||||
('waterproof trousers', 42, 70),
|
||||
('waterproof overclothes', 43, 75),
|
||||
('note-case',22, 80),
|
||||
(sunglasses, 7, 20),
|
||||
(towel, 18, 12),
|
||||
(socks, 4, 50),
|
||||
(book, 30, 10 )],
|
||||
gen_state(S0),
|
||||
length(L, N),
|
||||
numlist(1, N, LN),
|
||||
time(( create_constraint_N(LN, S0, S1),
|
||||
maplist(create_constraint_WV, LN, L, LW, LV),
|
||||
constraint(LW =< 400, S1, S2),
|
||||
maximize(LV, S2, S3)
|
||||
)),
|
||||
compute_lenword(L, 0, Len),
|
||||
sformat(A1, '~~w~~t~~~w|', [Len]),
|
||||
sformat(A2, '~~t~~w~~~w|', [4]),
|
||||
sformat(A3, '~~t~~w~~~w|', [5]),
|
||||
print_results(S3, A1,A2,A3, L, LN, 0, 0).
|
||||
L = [
|
||||
(map, 9, 150),
|
||||
(compass, 13, 35),
|
||||
(water, 153, 200),
|
||||
(sandwich, 50, 160),
|
||||
(glucose, 15, 60),
|
||||
(tin, 68, 45),
|
||||
(banana, 27, 60),
|
||||
(apple, 39, 40),
|
||||
(cheese, 23, 30),
|
||||
(beer, 52, 10),
|
||||
('suntan cream', 11, 70),
|
||||
(camera, 32, 30),
|
||||
('t-shirt', 24, 15),
|
||||
(trousers, 48, 10),
|
||||
(umbrella, 73, 40),
|
||||
('waterproof trousers', 42, 70),
|
||||
('waterproof overclothes', 43, 75),
|
||||
('note-case',22, 80),
|
||||
(sunglasses, 7, 20),
|
||||
(towel, 18, 12),
|
||||
(socks, 4, 50),
|
||||
(book, 30, 10 )],
|
||||
gen_state(S0),
|
||||
length(L, N),
|
||||
numlist(1, N, LN),
|
||||
time(( create_constraint_N(LN, S0, S1),
|
||||
maplist(create_constraint_WV, LN, L, LW, LV),
|
||||
constraint(LW =< 400, S1, S2),
|
||||
maximize(LV, S2, S3)
|
||||
)),
|
||||
compute_lenword(L, 0, Len),
|
||||
sformat(A1, '~~w~~t~~~w|', [Len]),
|
||||
sformat(A2, '~~t~~w~~~w|', [4]),
|
||||
sformat(A3, '~~t~~w~~~w|', [5]),
|
||||
print_results(S3, A1,A2,A3, L, LN, 0, 0).
|
||||
|
||||
|
||||
create_constraint_N([], S, S).
|
||||
|
||||
create_constraint_N([HN|TN], S1, SF) :-
|
||||
constraint(integral(x(HN)), S1, S2),
|
||||
constraint([x(HN)] =< 1, S2, S3),
|
||||
constraint([x(HN)] >= 0, S3, S4),
|
||||
create_constraint_N(TN, S4, SF).
|
||||
constraint(integral(x(HN)), S1, S2),
|
||||
constraint([x(HN)] =< 1, S2, S3),
|
||||
constraint([x(HN)] >= 0, S3, S4),
|
||||
create_constraint_N(TN, S4, SF).
|
||||
|
||||
create_constraint_WV(N, (_, W, V), W * x(N), V * x(N)).
|
||||
|
||||
|
|
@ -53,26 +53,26 @@ create_constraint_WV(N, (_, W, V), W * x(N), V * x(N)).
|
|||
%
|
||||
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, [W]),
|
||||
sformat(S3, A3, [V]),
|
||||
format('~w~w~w~n', [S1,S2,S3]),
|
||||
W2 is W1 + W,
|
||||
V2 is V1 + V),
|
||||
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, [W]),
|
||||
sformat(S3, A3, [V]),
|
||||
format('~w~w~w~n', [S1,S2,S3]),
|
||||
W2 is W1 + W,
|
||||
V2 is V1 + V),
|
||||
print_results(S, A1, A2, A3, T, TN, W2, V2).
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
n, G = 5, 5 # KNAPSACK 0-1 DANILIN
|
||||
n, G = 5, 5 # KNAPSACK 0-1 DANILIN
|
||||
N = n + 1 # rextester.com/BCKP19591
|
||||
a = 2 ** N
|
||||
L, C, j, q, s, d, e = [1]*n, [1]*n, [1]*n, [0]*a, [0]*a, [0]*a, [""]*a
|
||||
|
|
@ -26,5 +26,5 @@ print()
|
|||
max, m = 0, 1
|
||||
for i in range(a):
|
||||
if d[i] <= G and q[i] > max:
|
||||
max, m = q[i], i
|
||||
max, m = q[i], i
|
||||
print(d[m], q[m], e[m])
|
||||
|
|
|
|||
|
|
@ -11,68 +11,68 @@ Full_Data<-structure(list(item = c("map", "compass", "water", "sandwich",
|
|||
|
||||
Bounded_knapsack<-function(Data,W)
|
||||
{
|
||||
K<-matrix(NA,nrow=W+1,ncol=dim(Data)[1]+1)
|
||||
0->K[1,]->K[,1]
|
||||
matrix_item<-matrix('',nrow=W+1,ncol=dim(Data)[1]+1)
|
||||
for(j in 1:dim(Data)[1])
|
||||
{
|
||||
for(w in 1:W)
|
||||
{
|
||||
wj<-Data$weigth[j]
|
||||
item<-Data$item[j]
|
||||
value<-Data$value[j]
|
||||
if( wj > w )
|
||||
{
|
||||
K[w+1,j+1]<-K[w+1,j]
|
||||
matrix_item[w+1,j+1]<-matrix_item[w+1,j]
|
||||
}
|
||||
else
|
||||
{
|
||||
if( K[w+1,j] >= K[w+1-wj,j]+value )
|
||||
{
|
||||
K[w+1,j+1]<-K[w+1,j]
|
||||
matrix_item[w+1,j+1]<-matrix_item[w+1,j]
|
||||
}
|
||||
else
|
||||
{
|
||||
K[w+1,j+1]<-K[w+1-wj,j]+value
|
||||
matrix_item[w+1,j+1]<-item
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
K<-matrix(NA,nrow=W+1,ncol=dim(Data)[1]+1)
|
||||
0->K[1,]->K[,1]
|
||||
matrix_item<-matrix('',nrow=W+1,ncol=dim(Data)[1]+1)
|
||||
for(j in 1:dim(Data)[1])
|
||||
{
|
||||
for(w in 1:W)
|
||||
{
|
||||
wj<-Data$weigth[j]
|
||||
item<-Data$item[j]
|
||||
value<-Data$value[j]
|
||||
if( wj > w )
|
||||
{
|
||||
K[w+1,j+1]<-K[w+1,j]
|
||||
matrix_item[w+1,j+1]<-matrix_item[w+1,j]
|
||||
}
|
||||
else
|
||||
{
|
||||
if( K[w+1,j] >= K[w+1-wj,j]+value )
|
||||
{
|
||||
K[w+1,j+1]<-K[w+1,j]
|
||||
matrix_item[w+1,j+1]<-matrix_item[w+1,j]
|
||||
}
|
||||
else
|
||||
{
|
||||
K[w+1,j+1]<-K[w+1-wj,j]+value
|
||||
matrix_item[w+1,j+1]<-item
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(list(K=K,Item=matrix_item))
|
||||
}
|
||||
|
||||
backtracking<-function(knapsack, Data)
|
||||
{
|
||||
W<-dim(knapsack$K)[1]
|
||||
itens<-c()
|
||||
col<-dim(knapsack$K)[2]
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
while(selected_item!='')
|
||||
{
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
if(selected_item!='')
|
||||
{
|
||||
selected_item_value<-Data[Data$item == selected_item,]
|
||||
if(-knapsack$K[W - selected_item_value$weigth,col-1]+knapsack$K[W,col]==selected_item_value$value)
|
||||
{
|
||||
W <- W - selected_item_value$weigth
|
||||
itens<-c(itens,selected_item)
|
||||
}
|
||||
col <- col - 1
|
||||
}
|
||||
}
|
||||
W<-dim(knapsack$K)[1]
|
||||
itens<-c()
|
||||
col<-dim(knapsack$K)[2]
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
while(selected_item!='')
|
||||
{
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
if(selected_item!='')
|
||||
{
|
||||
selected_item_value<-Data[Data$item == selected_item,]
|
||||
if(-knapsack$K[W - selected_item_value$weigth,col-1]+knapsack$K[W,col]==selected_item_value$value)
|
||||
{
|
||||
W <- W - selected_item_value$weigth
|
||||
itens<-c(itens,selected_item)
|
||||
}
|
||||
col <- col - 1
|
||||
}
|
||||
}
|
||||
return(itens)
|
||||
}
|
||||
|
||||
print_output<-function(Data,W)
|
||||
{
|
||||
Bounded_knapsack(Data,W)->Knap
|
||||
backtracking(Knap, Data)->Items
|
||||
output<-paste('You must carry:', paste(Items, sep = ', '), sep=' ' )
|
||||
return(output)
|
||||
Bounded_knapsack(Data,W)->Knap
|
||||
backtracking(Knap, Data)->Items
|
||||
output<-paste('You must carry:', paste(Items, sep = ', '), sep=' ' )
|
||||
return(output)
|
||||
}
|
||||
|
||||
print_output(Full_Data, 400)
|
||||
|
|
|
|||
85
Task/Knapsack-problem-0-1/Rebol/knapsack-problem-0-1.rebol
Normal file
85
Task/Knapsack-problem-0-1/Rebol/knapsack-problem-0-1.rebol
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
Rebol [
|
||||
title: "Rosetta code: Knapsack problem/0-1"
|
||||
file: %Knapsack_problem-0-1.r3
|
||||
url: https://rosettacode.org/wiki/Knapsack_problem/0-1
|
||||
]
|
||||
|
||||
knapsack: function/with [
|
||||
"Solves the 0/1 knapsack problem via top-down dynamic programming."
|
||||
capacity [integer!] "remaining weight capacity"
|
||||
remaining [block!] "items not yet considered"
|
||||
][
|
||||
;;Each item may be taken at most once (unlike the bounded variant).
|
||||
;;Returns a 3-element block [value weight items] representing the
|
||||
;;optimal selection. Results are memoised in `cache` keyed by
|
||||
;;"capacity,item-count" so each sub-problem is solved at most once.
|
||||
|
||||
if empty? remaining [ return reduce [0 0 copy []] ] ;; base case: no items left
|
||||
|
||||
key: rejoin [capacity "," length? remaining]
|
||||
if cached: cache/:key [ return cached ] ;; memoisation hit
|
||||
|
||||
item: first remaining
|
||||
rest: next remaining
|
||||
name: item/1
|
||||
weight: item/2
|
||||
value: item/3
|
||||
|
||||
skip-it: knapsack capacity rest ;; best result without this item
|
||||
|
||||
result: either weight > capacity [
|
||||
skip-it ;; item too heavy: must skip
|
||||
][
|
||||
take-it: knapsack (capacity - weight) rest ;; best result with this item
|
||||
take-value: take-it/1 + value
|
||||
either take-value > skip-it/1 [
|
||||
reduce [
|
||||
take-value
|
||||
take-it/2 + weight
|
||||
append copy take-it/3 item
|
||||
]
|
||||
][
|
||||
skip-it ;; skipping is better
|
||||
]
|
||||
]
|
||||
|
||||
cache/:key: result
|
||||
result
|
||||
][
|
||||
cache: make map! 2000 ;; memoisation table
|
||||
]
|
||||
|
||||
items: [
|
||||
[map 9 150]
|
||||
[compass 13 35]
|
||||
[water 153 200]
|
||||
[sandwich 50 160]
|
||||
[glucose 15 60]
|
||||
[tin 68 45]
|
||||
[banana 27 60]
|
||||
[apple 39 40]
|
||||
[cheese 23 30]
|
||||
[beer 52 10]
|
||||
[cream 11 70]
|
||||
[camera 32 30]
|
||||
[t-shirt 24 15]
|
||||
[trousers 48 10]
|
||||
[umbrella 73 40]
|
||||
[trousers 42 70]
|
||||
[overclothes 43 75]
|
||||
[notecase 22 80]
|
||||
[glasses 7 20]
|
||||
[towel 18 12]
|
||||
[socks 4 50]
|
||||
[book 30 10]
|
||||
]
|
||||
|
||||
result: knapsack 400 items
|
||||
|
||||
print "Bagged the following items:"
|
||||
foreach [item weight value] result/3 [
|
||||
printf [" * " 12 -4 -4] reduce [item value weight]
|
||||
]
|
||||
print [
|
||||
"Total value :" as-green result/1 LF
|
||||
"Total weight :" as-green result/2]
|
||||
|
|
@ -55,9 +55,9 @@ fn test_dp_results() {
|
|||
}
|
||||
else {
|
||||
m(n)(w) = m(n-1)(w-wn)+vn
|
||||
plm(n)(w) = plm(n-1)(w-wn)+in
|
||||
}
|
||||
}
|
||||
plm(n)(w) = plm(n-1)(w-wn)+in
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
# The list of items to consider, as list of lists
|
||||
set items {
|
||||
{map 9 150}
|
||||
{compass 13 35}
|
||||
{water 153 200}
|
||||
{sandwich 50 160}
|
||||
{glucose 15 60}
|
||||
{tin 68 45}
|
||||
{banana 27 60}
|
||||
{apple 39 40}
|
||||
{cheese 23 30}
|
||||
{beer 52 10}
|
||||
{{suntan cream} 11 70}
|
||||
{camera 32 30}
|
||||
{t-shirt 24 15}
|
||||
{trousers 48 10}
|
||||
{umbrella 73 40}
|
||||
{{waterproof trousers} 42 70}
|
||||
{{waterproof overclothes} 43 75}
|
||||
{note-case 22 80}
|
||||
{sunglasses 7 20}
|
||||
{towel 18 12}
|
||||
{socks 4 50}
|
||||
{book 30 10}
|
||||
{map 9 150}
|
||||
{compass 13 35}
|
||||
{water 153 200}
|
||||
{sandwich 50 160}
|
||||
{glucose 15 60}
|
||||
{tin 68 45}
|
||||
{banana 27 60}
|
||||
{apple 39 40}
|
||||
{cheese 23 30}
|
||||
{beer 52 10}
|
||||
{{suntan cream} 11 70}
|
||||
{camera 32 30}
|
||||
{t-shirt 24 15}
|
||||
{trousers 48 10}
|
||||
{umbrella 73 40}
|
||||
{{waterproof trousers} 42 70}
|
||||
{{waterproof overclothes} 43 75}
|
||||
{note-case 22 80}
|
||||
{sunglasses 7 20}
|
||||
{towel 18 12}
|
||||
{socks 4 50}
|
||||
{book 30 10}
|
||||
}
|
||||
|
||||
# Simple extraction functions
|
||||
|
|
@ -45,18 +45,18 @@ proc value {chosen} {
|
|||
proc knapsackSearch {items {chosen {}}} {
|
||||
# If we've gone over the weight limit, stop now
|
||||
if {[weight $chosen] > 400} {
|
||||
return
|
||||
return
|
||||
}
|
||||
# If we've considered all of the items (i.e., leaf in search tree)
|
||||
# then see if we've got a new best choice.
|
||||
if {[llength $items] == 0} {
|
||||
global best max
|
||||
set v [value $chosen]
|
||||
if {$v > $max} {
|
||||
set max $v
|
||||
set best $chosen
|
||||
}
|
||||
return
|
||||
global best max
|
||||
set v [value $chosen]
|
||||
if {$v > $max} {
|
||||
set max $v
|
||||
set best $chosen
|
||||
}
|
||||
return
|
||||
}
|
||||
# Branch, so recurse for chosing the current item or not
|
||||
set this [lindex $items 0]
|
||||
|
|
|
|||
214
Task/Knapsack-problem-0-1/VBScript/knapsack-problem-0-1.vbs
Normal file
214
Task/Knapsack-problem-0-1/VBScript/knapsack-problem-0-1.vbs
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
' Knapsack problem/0-1 - 13/02/2017
|
||||
dim w(22),v(22),m(22)
|
||||
data=array( "map", 9, 150, "compass", 13, 35, "water", 153, 200, _
|
||||
"sandwich", 50, 160 , "glucose", 15, 60, "tin", 68, 45, _
|
||||
"banana", 27, 60, "apple", 39, 40 , "cheese", 23, 30, "beer", 52, 10, _
|
||||
"suntan cream", 11, 70, "camera", 32, 30 , "T-shirt", 24, 15, _
|
||||
"trousers", 48, 10, "umbrella", 73, 40, "book", 30, 10 , _
|
||||
"waterproof trousers", 42, 70, "waterproof overclothes", 43, 75 , _
|
||||
"note-case", 22, 80, "sunglasses", 7, 20, "towel", 18, 12, "socks", 4, 50)
|
||||
ww=400
|
||||
xw=0:iw=0:iv=0
|
||||
w(1)=iw:v(1)=iv
|
||||
for i1=0 to 1:m(1)=i1:j=0
|
||||
if i1=1 then
|
||||
iw=w(1)+data(j*3+1):iv=v(1)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i1
|
||||
if iw<=ww then
|
||||
w(2)=iw: v(2)=iv
|
||||
for i2=0 to 1:m(2)=i2:j=1
|
||||
if i2=1 then
|
||||
iw=w(2)+data(j*3+1):iv=v(2)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i2
|
||||
if iw<=ww then
|
||||
w(3)=iw: v(3)=iv
|
||||
for i3=0 to 1:m(3)=i3:j=2
|
||||
if i3=1 then
|
||||
iw=w(3)+data(j*3+1):iv=v(3)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i3
|
||||
if iw<=ww then
|
||||
w(4)=iw: v(4)=iv
|
||||
for i4=0 to 1:m(4)=i4:j=3
|
||||
if i4=1 then
|
||||
iw=w(4)+data(j*3+1):iv=v(4)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i4
|
||||
if iw<=ww then
|
||||
w(5)=iw: v(5)=iv
|
||||
for i5=0 to 1:m(5)=i5:j=4
|
||||
if i5=1 then
|
||||
iw=w(5)+data(j*3+1):iv=v(5)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i5
|
||||
if iw<=ww then
|
||||
w(6)=iw: v(6)=iv
|
||||
for i6=0 to 1:m(6)=i6:j=5
|
||||
if i6=1 then
|
||||
iw=w(6)+data(j*3+1):iv=v(6)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i6
|
||||
if iw<=ww then
|
||||
w(7)=iw: v(7)=iv
|
||||
for i7=0 to 1:m(7)=i7:j=6
|
||||
if i7=1 then
|
||||
iw=w(7)+data(j*3+1):iv=v(7)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i7
|
||||
if iw<=ww then
|
||||
w(8)=iw: v(8)=iv
|
||||
for i8=0 to 1:m(8)=i8:j=7
|
||||
if i8=1 then
|
||||
iw=w(8)+data(j*3+1):iv=v(8)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i8
|
||||
if iw<=ww then
|
||||
w(9)=iw: v(9)=iv
|
||||
for i9=0 to 1:m(9)=i9:j=8
|
||||
if i9=1 then
|
||||
iw=w(9)+data(j*3+1):iv=v(9)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i9
|
||||
if iw<=ww then
|
||||
w(10)=iw: v(10)=iv
|
||||
for i10=0 to 1:m(10)=i10:j=9
|
||||
if i10=1 then
|
||||
iw=w(10)+data(j*3+1):iv=v(10)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i10
|
||||
if iw<=ww then
|
||||
w(11)=iw: v(11)=iv
|
||||
for i11=0 to 1:m(11)=i11:j=10
|
||||
if i11=1 then
|
||||
iw=w(11)+data(j*3+1):iv=v(11)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i11
|
||||
if iw<=ww then
|
||||
w(12)=iw: v(12)=iv
|
||||
for i12=0 to 1:m(12)=i12:j=11
|
||||
if i12=1 then
|
||||
iw=w(12)+data(j*3+1):iv=v(12)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i12
|
||||
if iw<=ww then
|
||||
w(13)=iw: v(13)=iv
|
||||
for i13=0 to 1:m(13)=i13:j=12
|
||||
if i13=1 then
|
||||
iw=w(13)+data(j*3+1):iv=v(13)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i13
|
||||
if iw<=ww then
|
||||
w(14)=iw: v(14)=iv
|
||||
for i14=0 to 1:m(14)=i14:j=13
|
||||
if i14=1 then
|
||||
iw=w(14)+data(j*3+1):iv=v(14)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i14
|
||||
if iw<=ww then
|
||||
w(15)=iw: v(15)=iv
|
||||
for i15=0 to 1:m(15)=i15:j=14
|
||||
if i15=1 then
|
||||
iw=w(15)+data(j*3+1):iv=v(15)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i15
|
||||
if iw<=ww then
|
||||
w(16)=iw: v(16)=iv
|
||||
for i16=0 to 1:m(16)=i16:j=15
|
||||
if i16=1 then
|
||||
iw=w(16)+data(j*3+1):iv=v(16)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i16
|
||||
if iw<=ww then
|
||||
w(17)=iw: v(17)=iv
|
||||
for i17=0 to 1:m(17)=i17:j=16
|
||||
if i17=1 then
|
||||
iw=w(17)+data(j*3+1):iv=v(17)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i17
|
||||
if iw<=ww then
|
||||
w(18)=iw: v(18)=iv
|
||||
for i18=0 to 1:m(18)=i18:j=17
|
||||
if i18=1 then
|
||||
iw=w(18)+data(j*3+1):iv=v(18)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i18
|
||||
if iw<=ww then
|
||||
w(19)=iw: v(19)=iv
|
||||
for i19=0 to 1:m(19)=i19:j=18
|
||||
if i19=1 then
|
||||
iw=w(19)+data(j*3+1):iv=v(19)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i19
|
||||
if iw<=ww then
|
||||
w(20)=iw: v(20)=iv
|
||||
for i20=0 to 1:m(20)=i20:j=19
|
||||
if i20=1 then
|
||||
iw=w(20)+data(j*3+1):iv=v(20)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i20
|
||||
if iw<=ww then
|
||||
w(21)=iw: v(21)=iv
|
||||
for i21=0 to 1:m(21)=i21:j=20
|
||||
if i21=1 then
|
||||
iw=w(21)+data(j*3+1):iv=v(21)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i21
|
||||
if iw<=ww then
|
||||
w(22)=iw: v(22)=iv
|
||||
for i22=0 to 1:m(22)=i22:j=21
|
||||
nn=nn+1
|
||||
if i22=1 then
|
||||
iw=w(22)+data(j*3+1):iv=v(22)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i22
|
||||
if iw<=ww then
|
||||
end if 'i22
|
||||
next:m(22)=0
|
||||
end if 'i21
|
||||
next:m(21)=0
|
||||
end if 'i20
|
||||
next:m(20)=0
|
||||
end if 'i19
|
||||
next:m(19)=0
|
||||
end if 'i18
|
||||
next:m(18)=0
|
||||
end if 'i17
|
||||
next:m(17)=0
|
||||
end if 'i16
|
||||
next:m(16)=0
|
||||
end if 'i15
|
||||
next:m(15)=0
|
||||
end if 'i14
|
||||
next:m(14)=0
|
||||
end if 'i13
|
||||
next:m(13)=0
|
||||
end if 'i12
|
||||
next:m(12)=0
|
||||
end if 'i11
|
||||
next:m(11)=0
|
||||
end if 'i10
|
||||
next:m(10)=0
|
||||
end if 'i9
|
||||
next:m(9)=0
|
||||
end if 'i8
|
||||
next:m(8)=0
|
||||
end if 'i7
|
||||
next:m(7)=0
|
||||
end if 'i6
|
||||
next:m(6)=0
|
||||
end if 'i5
|
||||
next:m(5)=0
|
||||
end if 'i4
|
||||
next:m(4)=0
|
||||
end if 'i3
|
||||
next:m(3)=0
|
||||
end if 'i2
|
||||
next:m(2)=0
|
||||
end if 'i1
|
||||
next:m(1)=0
|
||||
for i=1 to 22
|
||||
if l(i)=1 then wlist=wlist&vbCrlf&data((i-1)*3)
|
||||
next
|
||||
Msgbox mid(wlist,3)&vbCrlf&vbCrlf&"weight="&xw&vbCrlf&"value="&xv,,"Knapsack - nn="&nn
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
items:=T(T("apple", 39, 40),T("banana", 27,60), // item: (name,weight,value)
|
||||
T("beer", 52, 10),T("book", 30,10),T("camera", 32, 30),
|
||||
T("cheese", 23, 30),T("compass", 13,35),T("glucose", 15, 60),
|
||||
T("map", 9,150),T("note-case",22,80),T("sandwich", 50,160),
|
||||
T("socks", 4, 50),T("sunglasses",7,20),T("suntan cream",11, 70),
|
||||
T("t-shirt", 24, 15),T("tin", 68,45),T("towel", 18, 12),
|
||||
T("trousers", 48, 10),T("umbrella", 73,40),T("water", 153,200),
|
||||
T("overclothes",43, 75),T("waterproof trousers",42,70) );
|
||||
T("cheese", 23, 30),T("compass", 13,35),T("glucose", 15, 60),
|
||||
T("map", 9,150),T("note-case",22,80),T("sandwich", 50,160),
|
||||
T("socks", 4, 50),T("sunglasses",7,20),T("suntan cream",11, 70),
|
||||
T("t-shirt", 24, 15),T("tin", 68,45),T("towel", 18, 12),
|
||||
T("trousers", 48, 10),T("umbrella", 73,40),T("water", 153,200),
|
||||
T("overclothes",43, 75),T("waterproof trousers",42,70) );
|
||||
const MAX_WEIGHT=400;
|
||||
knapsack:=items.reduce(addItem,
|
||||
(MAX_WEIGHT).pump(List,T(0,T).copy))[-1]; // nearest to max weight
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue