A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
65
Task/Knapsack-problem-0-1/0DESCRIPTION
Normal file
65
Task/Knapsack-problem-0-1/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
A tourist wants to make a good trip at the weekend with his friends. They will go to the mountains to see the wonders of nature, so he needs to pack well for the trip. He has a good knapsack for carrying things, but knows that he can carry a maximum of only 4kg in it and it will have to last the whole day. He creates a list of what he wants to bring for the trip but the total weight of all items is too much. He then decides to add columns to his initial list detailing their weights and a numerical value representing how important the item is for the trip.
|
||||
|
||||
Here is the list:
|
||||
|
||||
{| style="text-align: left; width: 80%;" border="4" cellpadding="2" cellspacing="2"
|
||||
|+ Table of potential knapsack items
|
||||
|- style="background-color: rgb(255, 204, 255);"
|
||||
! item !! weight (dag) !! 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
|
||||
|-
|
||||
| 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
|
||||
|- style="background-color: rgb(255, 204, 255);"
|
||||
| knapsack || ≤400 dag || ?
|
||||
|}
|
||||
|
||||
The tourist can choose to take any combination of items from the list, but only one of each item is available. He may not cut or diminish the items, so he can only take whole units of any item.
|
||||
|
||||
'''Which items does the tourist carry in his knapsack so that their total weight does not exceed 400 dag [4 kg], and their total value is maximised?'''
|
||||
|
||||
[dag = decagram = 10 grams]
|
||||
|
||||
;See also:
|
||||
* [[Knapsack problem/Unbounded]]
|
||||
* [[Knapsack problem/Bounded]]
|
||||
4
Task/Knapsack-problem-0-1/1META.yaml
Normal file
4
Task/Knapsack-problem-0-1/1META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Memoization
|
||||
note: Classic CS problems and programs
|
||||
13
Task/Knapsack-problem-0-1/APL/knapsack-problem-0-1.apl
Normal file
13
Task/Knapsack-problem-0-1/APL/knapsack-problem-0-1.apl
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
∇ ret←NapSack;sum;b;list;total
|
||||
[1] total←400
|
||||
[2] list←("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)
|
||||
[3] list←list[⍒3⊃¨list]
|
||||
[4]
|
||||
[5] ret←⍬
|
||||
[6] :while 0≠⍴list
|
||||
[7] ret←ret,(b←total>sum←+\2⊃¨list)/list
|
||||
[8] list←1↓(~b)/list
|
||||
[9] total←total-sum←¯1↑(total>sum)/sum
|
||||
[10] :end
|
||||
[11] ret←⊃ret,⊂'TOTALS:' (+/2⊃¨ret)(+/3⊃¨ret)
|
||||
∇
|
||||
109
Task/Knapsack-problem-0-1/Ada/knapsack-problem-0-1.ada
Normal file
109
Task/Knapsack-problem-0-1/Ada/knapsack-problem-0-1.ada
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;
|
||||
65
Task/Knapsack-problem-0-1/BBC-BASIC/knapsack-problem-0-1.bbc
Normal file
65
Task/Knapsack-problem-0-1/BBC-BASIC/knapsack-problem-0-1.bbc
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
HIMEM = PAGE + 8000000
|
||||
nItems% = 22
|
||||
maxWeight% = 400
|
||||
|
||||
DIM Tag{ivalue%, list%(nItems%-1), lp%}
|
||||
DIM items{(nItems%-1)name$, weight%, ivalue%}
|
||||
FOR item% = 0 TO nItems%-1
|
||||
READ items{(item%)}.name$, items{(item%)}.weight%, items{(item%)}.ivalue%
|
||||
NEXT
|
||||
|
||||
DATA "map", 9, 150, "compass", 13, 35, "water", 153, 200, "sandwich", 50, 160
|
||||
DATA "glucose", 15, 60, "tin", 68, 45, "banana", 27, 60, "apple", 39, 40
|
||||
DATA "cheese", 23, 30, "beer", 52, 10, "suntan cream", 11, 70, "camera", 32, 30
|
||||
DATA "t-shirt", 24, 15, "trousers", 48, 10, "umbrella", 73, 40, "book", 30, 10
|
||||
DATA "waterproof trousers", 42, 70, "waterproof overclothes", 43, 75
|
||||
DATA "note-case", 22, 80, "sunglasses", 7, 20, "towel", 18, 12, "socks", 4, 50
|
||||
|
||||
carry% = FN_Knapsack(items{()}, nItems% - 1, maxWeight%, cache{()})
|
||||
FOR i% = 0 TO cache{(carry%)}.lp%-1
|
||||
n% = cache{(carry%)}.list%(i%)
|
||||
TotalWeight% += items{(n%)}.weight%
|
||||
TotalValue% += items{(n%)}.ivalue%
|
||||
PRINT items{(n%)}.name$ " "
|
||||
NEXT
|
||||
PRINT '"Total weight = " ; TotalWeight%
|
||||
PRINT "Total value = " ; TotalValue%
|
||||
END
|
||||
|
||||
DEF FN_Knapsack(i{()}, i%, w%, RETURN m{()})
|
||||
LOCAL included{}, excluded{}, tmp%, index%
|
||||
DIM m{(16384)} = Tag{}, included{} = Tag{}, excluded{} = Tag{}
|
||||
|
||||
index% = i% << 9 OR w%
|
||||
IF m{(index%)}.ivalue% THEN = index%
|
||||
|
||||
IF i% = 0 THEN
|
||||
IF i{(0)}.weight% > w% THEN
|
||||
m{(index%)}.ivalue% = 0 : REM Item doesn't fit
|
||||
ELSE
|
||||
m{(index%)}.ivalue% = i{(0)}.ivalue%
|
||||
m{(index%)}.list%(m{(index%)}.lp%) = 0
|
||||
m{(index%)}.lp% += 1
|
||||
ENDIF
|
||||
= index%
|
||||
ENDIF
|
||||
|
||||
tmp% = FN_Knapsack(i{()}, i% - 1, w%, m{()})
|
||||
excluded{} = m{(tmp%)}
|
||||
IF i{(i%)}.weight% > w% THEN
|
||||
m{(index%)} = excluded{} : REM Item weighs too much
|
||||
= index%
|
||||
ELSE
|
||||
tmp% = FN_Knapsack(i{()}, i% - 1, w% - i{(i%)}.weight%, m{()})
|
||||
included{} = m{(tmp%)}
|
||||
included.ivalue% += i{(i%)}.ivalue%
|
||||
included.list%(included.lp%) = i%
|
||||
included.lp% += 1
|
||||
ENDIF
|
||||
|
||||
IF included.ivalue% > excluded.ivalue% THEN
|
||||
m{(index%)} = included{}
|
||||
ELSE
|
||||
m{(index%)} = excluded{}
|
||||
ENDIF
|
||||
= index%
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
(knapsack=
|
||||
( things
|
||||
= (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)
|
||||
)
|
||||
& 0:?maxvalue
|
||||
& :?sack
|
||||
& ( add
|
||||
= cumwght
|
||||
cumvalue
|
||||
cumsack
|
||||
name
|
||||
wght
|
||||
val
|
||||
tings
|
||||
n
|
||||
ncumwght
|
||||
ncumvalue
|
||||
. !arg
|
||||
: (?cumwght.?cumvalue.?cumsack.(?name.?wght.?val) ?tings)
|
||||
& -1:?n
|
||||
& whl
|
||||
' ( 1+!n:~>1:?n
|
||||
& !cumwght+!n*!wght:~>400:?ncumwght
|
||||
& !cumvalue+!n*!val:?ncumvalue
|
||||
& ( !tings:
|
||||
& ( !ncumvalue:>!maxvalue:?maxvalue
|
||||
& !cumsack
|
||||
(!n:0&|!name)
|
||||
: ?sack
|
||||
|
|
||||
)
|
||||
| add
|
||||
$ ( !ncumwght
|
||||
. !ncumvalue
|
||||
. !cumsack
|
||||
(!n:0&|!name)
|
||||
. !tings
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
& add$(0.0..!things)
|
||||
& out$(!maxvalue.!sack));
|
||||
|
||||
!knapsack;
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
1030
|
||||
. map
|
||||
compass
|
||||
water
|
||||
sandwich
|
||||
glucose
|
||||
banana
|
||||
suntan cream
|
||||
waterproof trousers
|
||||
waterproof overclothes
|
||||
note-case
|
||||
sunglasses
|
||||
socks
|
||||
98
Task/Knapsack-problem-0-1/C++/knapsack-problem-0-1.cpp
Normal file
98
Task/Knapsack-problem-0-1/C++/knapsack-problem-0-1.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <set>
|
||||
|
||||
int findBestPack( const std::vector<boost::tuple<std::string , int , int> > & ,
|
||||
std::set<int> & , const int ) ;
|
||||
|
||||
int main( ) {
|
||||
std::vector<boost::tuple<std::string , int , int> > items ;
|
||||
//===========fill the vector with data====================
|
||||
items.push_back( boost::make_tuple( "" , 0 , 0 ) ) ;
|
||||
items.push_back( boost::make_tuple( "map" , 9 , 150 ) ) ;
|
||||
items.push_back( boost::make_tuple( "compass" , 13 , 35 ) ) ;
|
||||
items.push_back( boost::make_tuple( "water" , 153 , 200 ) ) ;
|
||||
items.push_back( boost::make_tuple( "sandwich", 50 , 160 ) ) ;
|
||||
items.push_back( boost::make_tuple( "glucose" , 15 , 60 ) ) ;
|
||||
items.push_back( boost::make_tuple( "tin", 68 , 45 ) ) ;
|
||||
items.push_back( boost::make_tuple( "banana", 27 , 60 ) ) ;
|
||||
items.push_back( boost::make_tuple( "apple" , 39 , 40 ) ) ;
|
||||
items.push_back( boost::make_tuple( "cheese" , 23 , 30 ) ) ;
|
||||
items.push_back( boost::make_tuple( "beer" , 52 , 10 ) ) ;
|
||||
items.push_back( boost::make_tuple( "suntan creme" , 11 , 70 ) ) ;
|
||||
items.push_back( boost::make_tuple( "camera" , 32 , 30 ) ) ;
|
||||
items.push_back( boost::make_tuple( "T-shirt" , 24 , 15 ) ) ;
|
||||
items.push_back( boost::make_tuple( "trousers" , 48 , 10 ) ) ;
|
||||
items.push_back( boost::make_tuple( "umbrella" , 73 , 40 ) ) ;
|
||||
items.push_back( boost::make_tuple( "waterproof trousers" , 42 , 70 ) ) ;
|
||||
items.push_back( boost::make_tuple( "waterproof overclothes" , 43 , 75 ) ) ;
|
||||
items.push_back( boost::make_tuple( "note-case" , 22 , 80 ) ) ;
|
||||
items.push_back( boost::make_tuple( "sunglasses" , 7 , 20 ) ) ;
|
||||
items.push_back( boost::make_tuple( "towel" , 18 , 12 ) ) ;
|
||||
items.push_back( boost::make_tuple( "socks" , 4 , 50 ) ) ;
|
||||
items.push_back( boost::make_tuple( "book" , 30 , 10 ) ) ;
|
||||
const int maximumWeight = 400 ;
|
||||
std::set<int> bestItems ; //these items will make up the optimal value
|
||||
int bestValue = findBestPack( items , bestItems , maximumWeight ) ;
|
||||
std::cout << "The best value that can be packed in the given knapsack is " <<
|
||||
bestValue << " !\n" ;
|
||||
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++ ) {
|
||||
std::cout << (items.begin( ) + *si)->get<0>( ) << "\n" ;
|
||||
totalweight += (items.begin( ) + *si)->get<1>( ) ;
|
||||
}
|
||||
std::cout << "The total weight of all items is " << totalweight << " !\n" ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int findBestPack( const std::vector<boost::tuple<std::string , int , int> > & items ,std::set<int> & bestItems , const int weightlimit ) {
|
||||
//dynamic programming approach sacrificing storage space for execution
|
||||
//time , creating a table of optimal values for every weight and a
|
||||
//second table of sets with the items collected so far in the knapsack
|
||||
//the best value is in the bottom right corner of the values table,
|
||||
//the set of items in the bottom right corner of the sets' table.
|
||||
const int n = items.size( ) ;
|
||||
int bestValues [ n ][ weightlimit ] ;
|
||||
std::set<int> solutionSets[ n ][ weightlimit ] ;
|
||||
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 ;
|
||||
}
|
||||
}
|
||||
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 ] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bestItems.swap( solutionSets[ n - 1][ weightlimit - 1 ] ) ;
|
||||
return bestValues[ n - 1 ][ weightlimit - 1 ] ;
|
||||
}
|
||||
77
Task/Knapsack-problem-0-1/C/knapsack-problem-0-1.c
Normal file
77
Task/Knapsack-problem-0-1/C/knapsack-problem-0-1.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
const char * name;
|
||||
int weight, value;
|
||||
} item_t;
|
||||
|
||||
item_t item[] = {
|
||||
{"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}
|
||||
};
|
||||
|
||||
#define n_items (sizeof(item)/sizeof(item_t))
|
||||
|
||||
typedef struct {
|
||||
uint32_t bits; /* 32 bits, can solve up to 32 items */
|
||||
int value;
|
||||
} solution;
|
||||
|
||||
|
||||
void optimal(int weight, int idx, solution *s)
|
||||
{
|
||||
solution v1, v2;
|
||||
if (idx < 0) {
|
||||
s->bits = s->value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (weight < item[idx].weight)
|
||||
return optimal(weight, idx - 1, s);
|
||||
|
||||
optimal(weight, idx - 1, &v1);
|
||||
optimal(weight - item[idx].weight, idx - 1, &v2);
|
||||
|
||||
v2.value += item[idx].value;
|
||||
v2.bits |= (1 << idx);
|
||||
|
||||
*s = (v1.value >= v2.value) ? v1 : v2;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i = 0, w = 0;
|
||||
solution s = {0, 0};
|
||||
optimal(400, n_items - 1, &s);
|
||||
|
||||
for (i = 0; i < n_items; i++) {
|
||||
if (s.bits & (1 << i)) {
|
||||
printf("%s\n", item[i].name);
|
||||
w += item[i].weight;
|
||||
}
|
||||
}
|
||||
printf("Total value: %d; weight: %d\n", s.value, w);
|
||||
return 0;
|
||||
}
|
||||
27
Task/Knapsack-problem-0-1/Clojure/knapsack-problem-0-1-1.clj
Normal file
27
Task/Knapsack-problem-0-1/Clojure/knapsack-problem-0-1-1.clj
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
(def item-data
|
||||
[ "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])
|
||||
|
||||
(defstruct item :name :weight :value)
|
||||
|
||||
(def items (vec (map #(apply struct item %) (partition 3 item-data))))
|
||||
17
Task/Knapsack-problem-0-1/Clojure/knapsack-problem-0-1-2.clj
Normal file
17
Task/Knapsack-problem-0-1/Clojure/knapsack-problem-0-1-2.clj
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
(declare mm) ;forward decl for memoization function
|
||||
|
||||
(defn m [i w]
|
||||
(cond
|
||||
(< i 0) [0 []]
|
||||
(= w 0) [0 []]
|
||||
:else
|
||||
(let [{wi :weight vi :value} (get items i)]
|
||||
(if (> wi w)
|
||||
(mm (dec i) w)
|
||||
(let [[vn sn :as no] (mm (dec i) w)
|
||||
[vy sy :as yes] (mm (dec i) (- w wi))]
|
||||
(if (> (+ vy vi) vn)
|
||||
[(+ vy vi) (conj sy i)]
|
||||
no))))))
|
||||
|
||||
(def mm (memoize m))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(use '[clojure.string :only [join]])
|
||||
|
||||
(let [[value indexes] (m (-> items count dec) 400)
|
||||
names (map (comp :name items) indexes)]
|
||||
(println "items to pack:" (join ", " names))
|
||||
(println "total value:" value)
|
||||
(println "total weight:" (reduce + (map (comp :weight items) indexes))))
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
;;; memoize
|
||||
(defmacro mm-set (p v) `(if ,p ,p (setf ,p ,v)))
|
||||
|
||||
(defun knapsack (max-weight items)
|
||||
(let ((cache (make-array (list (1+ max-weight) (1+ (length items)))
|
||||
: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))))))))))
|
||||
|
||||
(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))))
|
||||
60
Task/Knapsack-problem-0-1/D/knapsack-problem-0-1.d
Normal file
60
Task/Knapsack-problem-0-1/D/knapsack-problem-0-1.d
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import std.stdio, std.algorithm, std.typecons, std.array;
|
||||
|
||||
struct Item {
|
||||
string name;
|
||||
int weight, value;
|
||||
}
|
||||
|
||||
Item[] knapsack01DinamicProg(in Item[] items, in int limit)
|
||||
pure nothrow {
|
||||
auto tab = new int[][](items.length + 1, limit + 1);
|
||||
|
||||
foreach (immutable i, immutable it; items)
|
||||
foreach (immutable w; 1 .. limit + 1)
|
||||
tab[i + 1][w] = (it.weight > w) ? tab[i][w] :
|
||||
max(tab[i][w], tab[i][w - it.weight] + it.value);
|
||||
|
||||
Item[] result;
|
||||
int w = limit;
|
||||
foreach_reverse (immutable i, immutable it; items)
|
||||
if (tab[i + 1][w] != tab[i][w]) {
|
||||
w -= it.weight;
|
||||
result ~= it;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
enum int limit = 400;
|
||||
immutable Item[] 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}];
|
||||
|
||||
auto bagged = knapsack01DinamicProg(items, limit);
|
||||
writeln("Items to pack:");
|
||||
bagged.map!q{ a.name }().array().sort().join("\n").writeln();
|
||||
const t = reduce!q{ a[] += [b.weight, b.value][] }([0, 0], bagged);
|
||||
const tot_wv = (t[0] <= limit) ? t : [0, 0];
|
||||
writefln("\nFor a total weight of %d and a total value of %d",
|
||||
tot_wv[0], tot_wv[1]);
|
||||
}
|
||||
104
Task/Knapsack-problem-0-1/Dart/knapsack-problem-0-1.dart
Normal file
104
Task/Knapsack-problem-0-1/Dart/knapsack-problem-0-1.dart
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
List solveKnapsack(items, maxWeight) {
|
||||
int MIN_VALUE=-100;
|
||||
int N = items.length; // number of items
|
||||
int W = maxWeight; // maximum weight of knapsack
|
||||
|
||||
List profit = new List(N+1);
|
||||
List weight = new List(N+1);
|
||||
|
||||
// generate random instance, items 1..N
|
||||
for(int n = 1; n<=N; n++) {
|
||||
profit[n] = items[n-1][2];
|
||||
weight[n] = items[n-1][1];
|
||||
|
||||
}
|
||||
|
||||
// opt[n][w] = max profit of packing items 1..n with weight limit w
|
||||
// sol[n][w] = does opt solution to pack items 1..n with weight limit w include item n?
|
||||
List<List<int>> opt = new List<List<int>>(N+1);
|
||||
for (int i=0; i<N+1; i++) {
|
||||
opt[i] = new List<int>(W+1);
|
||||
for(int j=0; j<W+1; j++) {
|
||||
opt[i][j] = MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
List<List<bool>> sol = new List<List<bool>>(N+1);
|
||||
for (int i=0; i<N+1; i++) {
|
||||
sol[i] = new List<bool>(W+1);
|
||||
for(int j=0; j<W+1; j++) {
|
||||
sol[i][j] = false;
|
||||
}
|
||||
}
|
||||
|
||||
for(int n=1; n<=N; n++) {
|
||||
for (int w=1; w <= W; w++) {
|
||||
// don't take item n
|
||||
int option1 = opt[n-1][w];
|
||||
|
||||
// take item n
|
||||
int option2 = MIN_VALUE;
|
||||
if (weight[n] <= w) {
|
||||
option2 = profit[n] + opt[n-1][w - weight[n]];
|
||||
}
|
||||
|
||||
// select better of two options
|
||||
opt[n][w] = Math.max(option1, option2);
|
||||
sol[n][w] = (option2 > option1);
|
||||
}
|
||||
}
|
||||
|
||||
// determine which items to take
|
||||
List<List> packItems = new List<List>();
|
||||
List<bool> take = new List(N+1);
|
||||
for (int n = N, w = W; n > 0; n--) {
|
||||
if (sol[n][w]) {
|
||||
take[n] = true;
|
||||
w = w - weight[n];
|
||||
packItems.add(items[n-1]);
|
||||
} else {
|
||||
take[n] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return packItems;
|
||||
|
||||
}
|
||||
|
||||
main() {
|
||||
List knapsackItems = [];
|
||||
knapsackItems.add(["map", 9, 150]);
|
||||
knapsackItems.add(["compass", 13, 35]);
|
||||
knapsackItems.add(["water", 153, 200]);
|
||||
knapsackItems.add(["sandwich", 50, 160]);
|
||||
knapsackItems.add(["glucose", 15, 60]);
|
||||
knapsackItems.add(["tin", 68, 45]);
|
||||
knapsackItems.add(["banana", 27, 60]);
|
||||
knapsackItems.add(["apple", 39, 40]);
|
||||
knapsackItems.add(["cheese", 23, 30]);
|
||||
knapsackItems.add(["beer", 52, 10]);
|
||||
knapsackItems.add(["suntan cream", 11, 70]);
|
||||
knapsackItems.add(["camera", 32, 30]);
|
||||
knapsackItems.add(["t-shirt", 24, 15]);
|
||||
knapsackItems.add(["trousers", 48, 10]);
|
||||
knapsackItems.add(["umbrella", 73, 40]);
|
||||
knapsackItems.add(["waterproof trousers", 42, 70]);
|
||||
knapsackItems.add(["waterproof overclothes", 43, 75]);
|
||||
knapsackItems.add(["note-case", 22, 80]);
|
||||
knapsackItems.add(["sunglasses", 7, 20]);
|
||||
knapsackItems.add(["towel", 18, 12]);
|
||||
knapsackItems.add(["socks", 4, 50]);
|
||||
knapsackItems.add(["book", 30, 10]);
|
||||
int maxWeight = 400;
|
||||
Stopwatch sw = new Stopwatch.start();
|
||||
List p = solveKnapsack(knapsackItems, maxWeight);
|
||||
sw.stop();
|
||||
int totalWeight = 0;
|
||||
int totalValue = 0;
|
||||
print(["item","profit","weight"]);
|
||||
p.forEach((var i) { print("${i}"); totalWeight+=i[1]; totalValue+=i[2]; });
|
||||
print("Total Value = ${totalValue}");
|
||||
print("Total Weight = ${totalWeight}");
|
||||
print("Elapsed Time = ${sw.elapsedInMs()}ms");
|
||||
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
>items=["map","compass","water","sandwich","glucose", ...
|
||||
> "tin","banana","apple","cheese","beer","suntan creame", ...
|
||||
> "camera","t-shirt","trousers","umbrella","waterproof trousers", ...
|
||||
> "waterproof overclothes","note-case","sunglasses", ...
|
||||
> "towel","socks","book"];
|
||||
>ws = [9,13,153,50,15,68,27,39,23,52,11, ...
|
||||
> 32,24,48,73,42,43,22,7,18,4,30];
|
||||
>vs = [150,35,200,160,60,45,60,40,30,10,70, ...
|
||||
> 30,15,10,40,70,75,80,20,12,50,10];
|
||||
>A=ws_id(cols(ws));
|
||||
>c=vs;
|
||||
>b=[400]_ones(cols(vs),1);
|
||||
>sol = intsimplex(A,b,c,eq=-1,>max,>check);
|
||||
>items[nonzeros(sol)]
|
||||
map
|
||||
compass
|
||||
water
|
||||
sandwich
|
||||
glucose
|
||||
banana
|
||||
suntan creame
|
||||
waterproof trousers
|
||||
waterproof overclothes
|
||||
note-case
|
||||
sunglasses
|
||||
socks
|
||||
77
Task/Knapsack-problem-0-1/Factor/knapsack-problem-0-1.factor
Normal file
77
Task/Knapsack-problem-0-1/Factor/knapsack-problem-0-1.factor
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
USING: accessors arrays fry io kernel locals make math
|
||||
math.order math.parser math.ranges sequences sorting ;
|
||||
IN: rosetta.knappsack.0-1
|
||||
|
||||
TUPLE: item
|
||||
name weight value ;
|
||||
|
||||
CONSTANT: items {
|
||||
T{ item f "map" 9 150 }
|
||||
T{ item f "compass" 13 35 }
|
||||
T{ item f "water" 153 200 }
|
||||
T{ item f "sandwich" 50 160 }
|
||||
T{ item f "glucose" 15 60 }
|
||||
T{ item f "tin" 68 45 }
|
||||
T{ item f "banana" 27 60 }
|
||||
T{ item f "apple" 39 40 }
|
||||
T{ item f "cheese" 23 30 }
|
||||
T{ item f "beer" 52 10 }
|
||||
T{ item f "suntan cream" 11 70 }
|
||||
T{ item f "camera" 32 30 }
|
||||
T{ item f "t-shirt" 24 15 }
|
||||
T{ item f "trousers" 48 10 }
|
||||
T{ item f "umbrella" 73 40 }
|
||||
T{ item f "waterproof trousers" 42 70 }
|
||||
T{ item f "waterproof overclothes" 43 75 }
|
||||
T{ item f "note-case" 22 80 }
|
||||
T{ item f "sunglasses" 7 20 }
|
||||
T{ item f "towel" 18 12 }
|
||||
T{ item f "socks" 4 50 }
|
||||
T{ item f "book" 30 10 }
|
||||
}
|
||||
|
||||
CONSTANT: limit 400
|
||||
|
||||
: make-table ( -- table )
|
||||
items length 1 + [ limit 1 + 0 <array> ] replicate ;
|
||||
|
||||
:: iterate ( item-no table -- )
|
||||
item-no table nth :> prev
|
||||
item-no 1 + table nth :> curr
|
||||
item-no items nth :> item
|
||||
limit [1,b] [| weight |
|
||||
weight prev nth
|
||||
weight item weight>> - dup 0 >=
|
||||
[ prev nth item value>> + max ]
|
||||
[ drop ] if
|
||||
weight curr set-nth
|
||||
] each ;
|
||||
|
||||
: fill-table ( table -- )
|
||||
[ items length iota ] dip
|
||||
'[ _ iterate ] each ;
|
||||
|
||||
:: extract-packed-items ( table -- items )
|
||||
[
|
||||
limit :> weight!
|
||||
items length iota <reversed> [| item-no |
|
||||
item-no table nth :> prev
|
||||
item-no 1 + table nth :> curr
|
||||
weight [ curr nth ] [ prev nth ] bi =
|
||||
[
|
||||
item-no items nth
|
||||
[ name>> , ] [ weight>> weight swap - weight! ] bi
|
||||
] unless
|
||||
] each
|
||||
] { } make ;
|
||||
|
||||
: solve-knappsack ( -- items value )
|
||||
make-table [ fill-table ]
|
||||
[ extract-packed-items ] [ last last ] tri ;
|
||||
|
||||
: main ( -- )
|
||||
solve-knappsack
|
||||
"Total value: " write number>string print
|
||||
"Items packed: " print
|
||||
natural-sort
|
||||
[ " " write print ] each ;
|
||||
55
Task/Knapsack-problem-0-1/Go/knapsack-problem-0-1.go
Normal file
55
Task/Knapsack-problem-0-1/Go/knapsack-problem-0-1.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type item struct {
|
||||
string
|
||||
w, v int
|
||||
}
|
||||
|
||||
var wants = []item{
|
||||
{"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},
|
||||
}
|
||||
|
||||
func main() {
|
||||
items, w, v := m(len(wants)-1, 400)
|
||||
fmt.Println(items)
|
||||
fmt.Println("weight:", w)
|
||||
fmt.Println("value:", v)
|
||||
}
|
||||
|
||||
func m(i, w int) ([]string, int, int) {
|
||||
if i < 0 || w == 0 {
|
||||
return nil, 0, 0
|
||||
} else if wants[i].w > w {
|
||||
return m(i-1, w)
|
||||
}
|
||||
i0, w0, v0 := m(i-1, w)
|
||||
i1, w1, v1 := m(i-1, w-wants[i].w)
|
||||
v1 += wants[i].v
|
||||
if v1 > v0 {
|
||||
return append(i1, wants[i].string), w1 + wants[i].w, v1
|
||||
}
|
||||
return i0, w0, v0
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
def totalWeight = { list -> list*.weight.sum() }
|
||||
def totalValue = { list -> list*.value.sum() }
|
||||
|
||||
def knapsack01bf = { possibleItems ->
|
||||
possibleItems.subsequences().findAll{ ss ->
|
||||
def w = totalWeight(ss)
|
||||
350 < w && w < 401
|
||||
}.max(totalValue)
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
def knapsack01dp = { possibleItems ->
|
||||
def n = possibleItems.size()
|
||||
def m = (0..n).collect{ i -> (0..400).collect{ w -> []} }
|
||||
(1..400).each { w ->
|
||||
(1..n).each { i ->
|
||||
def wi = possibleItems[i-1].weight
|
||||
m[i][w] = wi > w ? m[i-1][w] : ([m[i-1][w], m[i-1][w-wi] + [possibleItems[i-1]]].max(totalValue))
|
||||
}
|
||||
}
|
||||
m[n][400]
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
def items = [
|
||||
[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],
|
||||
]
|
||||
|
||||
[knapsack01bf, knapsack01dp].each { knapsack01 ->
|
||||
def start = System.currentTimeMillis()
|
||||
def packingList = knapsack01(items)
|
||||
def elapsed = System.currentTimeMillis() - start
|
||||
|
||||
println "\n\n\nElapsed Time: ${elapsed/1000.0} s"
|
||||
println "Total Weight: ${totalWeight(packingList)}"
|
||||
println " Total Value: ${totalValue(packingList)}"
|
||||
packingList.each {
|
||||
printf (" item: %-25s weight:%4d value:%4d\n", it.name, it.weight, it.value)
|
||||
}
|
||||
}
|
||||
17
Task/Knapsack-problem-0-1/Haskell/knapsack-problem-0-1-1.hs
Normal file
17
Task/Knapsack-problem-0-1/Haskell/knapsack-problem-0-1-1.hs
Normal file
|
|
@ -0,0 +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)]
|
||||
|
||||
-- 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)
|
||||
|
||||
main = do
|
||||
putStr "Total value: "; print value
|
||||
mapM_ print items
|
||||
where (value, items) = maximum $ combs inv 400
|
||||
15
Task/Knapsack-problem-0-1/Haskell/knapsack-problem-0-1-2.hs
Normal file
15
Task/Knapsack-problem-0-1/Haskell/knapsack-problem-0-1-2.hs
Normal file
|
|
@ -0,0 +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)]
|
||||
|
||||
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
|
||||
|
||||
main = do print $ combs inv 400
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
-- snipped the items list; same as above
|
||||
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
|
||||
|
||||
main = print $ (knapsack inv) !! 400
|
||||
76
Task/Knapsack-problem-0-1/Icon/knapsack-problem-0-1.icon
Normal file
76
Task/Knapsack-problem-0-1/Icon/knapsack-problem-0-1.icon
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
link printf
|
||||
|
||||
global wants # items wanted for knapsack
|
||||
|
||||
procedure main(A) # kanpsack 0-1
|
||||
if !A == ("--trace"|"-t") then &trace := -1 # trace everything (debug)
|
||||
if !A == ("--memoize"|"-m") then m :=: Memo_m # hook (swap) procedure
|
||||
|
||||
printf("Knapsack-0-1: with maximum weight allowed=%d.\n",maxw := 400)
|
||||
showwanted(wants := get_wants())
|
||||
showcontents(bag := m(*wants,maxw))
|
||||
printf("Performance: time=%d ms collections=%d\n",&time,&collections)
|
||||
end
|
||||
|
||||
record packing(items,weight,value)
|
||||
|
||||
procedure Memo_m(i,w) #: Hook procedure to memoize the knapsack
|
||||
static memoT
|
||||
initial memoT := table()
|
||||
return \memoT[k := i||","||w] | ( memoT[k] := Memo_m(i,w) )
|
||||
end
|
||||
|
||||
procedure m(i,w) #: Solve the Knapsack 0-1 as per Wikipedia
|
||||
static nil
|
||||
initial nil := packing([],0,0)
|
||||
if 0 = (i | w) then
|
||||
return nil
|
||||
else if wants[i].weight > w then
|
||||
return m(i-1, w)
|
||||
else {
|
||||
x0 := m(i-1,w)
|
||||
x1 := m(i-1,w-wants[i].weight)
|
||||
if ( x1.value + wants[i].value) > x0.value then
|
||||
return packing(x1.items ||| wants[i].items,
|
||||
x1.weight + wants[i].weight,
|
||||
x1.value + wants[i].value)
|
||||
else
|
||||
return x0
|
||||
}
|
||||
end
|
||||
|
||||
procedure showwanted(wants) #: show the list of wanted items
|
||||
every (tw := 0) +:= (!wants).weight
|
||||
printf("Packing list has total weight=%d and includes %d items [",tw,*wants)
|
||||
every printf(" %s",!(!wants).items|"]\n")
|
||||
end
|
||||
|
||||
procedure showcontents(bag) #: show the list of the packed bag
|
||||
printf("The bag weighs=%d holding %d items [",bag.weight,*bag.items)
|
||||
every printf(" %s",!bag.items|"]\n")
|
||||
end
|
||||
|
||||
procedure get_wants() #: setup list of wanted items
|
||||
return [ packing(["map"], 9, 150),
|
||||
packing(["compass"], 13, 35),
|
||||
packing(["water"], 153, 200),
|
||||
packing(["sandwich"], 50, 160),
|
||||
packing(["glucose"], 15, 60),
|
||||
packing(["tin"], 68, 45),
|
||||
packing(["banana"], 27, 60),
|
||||
packing(["apple"], 39, 40),
|
||||
packing(["cheese"], 23, 30),
|
||||
packing(["beer"], 52, 10),
|
||||
packing(["suntan cream"], 11, 70),
|
||||
packing(["camera"], 32, 30),
|
||||
packing(["T-shirt"], 24, 15),
|
||||
packing(["trousers"], 48, 10),
|
||||
packing(["umbrella"], 73, 40),
|
||||
packing(["waterproof trousers"], 42, 70),
|
||||
packing(["waterproof overclothes"], 43, 75),
|
||||
packing(["note-case"], 22, 80),
|
||||
packing(["sunglasses"], 7, 20),
|
||||
packing(["towel"], 18, 12),
|
||||
packing(["socks"], 4, 50),
|
||||
packing(["book"], 30, 10) ]
|
||||
end
|
||||
28
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-1.j
Normal file
28
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-1.j
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
'names values'=:|:".;._2]0 :0
|
||||
'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
|
||||
'tshirt'; 24 15
|
||||
'trousers'; 48 10
|
||||
'umbrella'; 73 40
|
||||
'waterproof trousers'; 42 70
|
||||
'waterproof overclothes'; 43 75
|
||||
'notecase'; 22 80
|
||||
'sunglasses'; 7 20
|
||||
'towel'; 18 12
|
||||
'socks'; 4 50
|
||||
'book'; 30 10
|
||||
)
|
||||
|
||||
X=: +/ .*"1
|
||||
plausible=: (] (] #~ 400 >: X) #:@i.@(2&^)@#)@:({."1)
|
||||
best=: (plausible ([ {~ [ (i. >./)@:X {:"1@]) ]) values
|
||||
15
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-2.j
Normal file
15
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-2.j
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
+/best#values NB. total weight and value
|
||||
396 1030
|
||||
best#names
|
||||
map
|
||||
compass
|
||||
water
|
||||
sandwich
|
||||
glucose
|
||||
banana
|
||||
suntan cream
|
||||
waterproof trousers
|
||||
waterproof overclothes
|
||||
notecase
|
||||
sunglasses
|
||||
socks
|
||||
84
Task/Knapsack-problem-0-1/Java/knapsack-problem-0-1-1.java
Normal file
84
Task/Knapsack-problem-0-1/Java/knapsack-problem-0-1-1.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
package hu.pj.alg.test;
|
||||
|
||||
import hu.pj.alg.ZeroOneKnapsack;
|
||||
import hu.pj.obj.Item;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
public class ZeroOneKnapsackForTourists {
|
||||
|
||||
public ZeroOneKnapsackForTourists() {
|
||||
ZeroOneKnapsack zok = new ZeroOneKnapsack(400); // 400 dkg = 400 dag = 4 kg
|
||||
|
||||
// making the list of items that you want to bring
|
||||
zok.add("map", 9, 150);
|
||||
zok.add("compass", 13, 35);
|
||||
zok.add("water", 153, 200);
|
||||
zok.add("sandwich", 50, 160);
|
||||
zok.add("glucose", 15, 60);
|
||||
zok.add("tin", 68, 45);
|
||||
zok.add("banana", 27, 60);
|
||||
zok.add("apple", 39, 40);
|
||||
zok.add("cheese", 23, 30);
|
||||
zok.add("beer", 52, 10);
|
||||
zok.add("suntan cream", 11, 70);
|
||||
zok.add("camera", 32, 30);
|
||||
zok.add("t-shirt", 24, 15);
|
||||
zok.add("trousers", 48, 10);
|
||||
zok.add("umbrella", 73, 40);
|
||||
zok.add("waterproof trousers", 42, 70);
|
||||
zok.add("waterproof overclothes", 43, 75);
|
||||
zok.add("note-case", 22, 80);
|
||||
zok.add("sunglasses", 7, 20);
|
||||
zok.add("towel", 18, 12);
|
||||
zok.add("socks", 4, 50);
|
||||
zok.add("book", 30, 10);
|
||||
|
||||
// calculate the solution:
|
||||
List<Item> itemList = zok.calcSolution();
|
||||
|
||||
// write out the solution in the standard output
|
||||
if (zok.isCalculated()) {
|
||||
NumberFormat nf = NumberFormat.getInstance();
|
||||
|
||||
System.out.println(
|
||||
"Maximal weight = " +
|
||||
nf.format(zok.getMaxWeight() / 100.0) + " kg"
|
||||
);
|
||||
System.out.println(
|
||||
"Total weight of solution = " +
|
||||
nf.format(zok.getSolutionWeight() / 100.0) + " kg"
|
||||
);
|
||||
System.out.println(
|
||||
"Total value = " +
|
||||
zok.getProfit()
|
||||
);
|
||||
System.out.println();
|
||||
System.out.println(
|
||||
"You can carry the following materials " +
|
||||
"in the knapsack:"
|
||||
);
|
||||
for (Item item : itemList) {
|
||||
if (item.getInKnapsack() == 1) {
|
||||
System.out.format(
|
||||
"%1$-23s %2$-3s %3$-5s %4$-15s \n",
|
||||
item.getName(),
|
||||
item.getWeight(), "dag ",
|
||||
"(value = " + item.getValue() + ")"
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println(
|
||||
"The problem is not solved. " +
|
||||
"Maybe you gave wrong data."
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new ZeroOneKnapsackForTourists();
|
||||
}
|
||||
|
||||
} // class
|
||||
154
Task/Knapsack-problem-0-1/Java/knapsack-problem-0-1-2.java
Normal file
154
Task/Knapsack-problem-0-1/Java/knapsack-problem-0-1-2.java
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
package hu.pj.alg;
|
||||
|
||||
import hu.pj.obj.Item;
|
||||
import java.util.*;
|
||||
|
||||
public class ZeroOneKnapsack {
|
||||
|
||||
protected List<Item> itemList = new ArrayList<Item>();
|
||||
protected int maxWeight = 0;
|
||||
protected int solutionWeight = 0;
|
||||
protected int profit = 0;
|
||||
protected boolean calculated = false;
|
||||
|
||||
public ZeroOneKnapsack() {}
|
||||
|
||||
public ZeroOneKnapsack(int _maxWeight) {
|
||||
setMaxWeight(_maxWeight);
|
||||
}
|
||||
|
||||
public ZeroOneKnapsack(List<Item> _itemList) {
|
||||
setItemList(_itemList);
|
||||
}
|
||||
|
||||
public ZeroOneKnapsack(List<Item> _itemList, int _maxWeight) {
|
||||
setItemList(_itemList);
|
||||
setMaxWeight(_maxWeight);
|
||||
}
|
||||
|
||||
// calculte the solution of 0-1 knapsack problem with dynamic method:
|
||||
public List<Item> calcSolution() {
|
||||
int n = itemList.size();
|
||||
|
||||
setInitialStateForCalculation();
|
||||
if (n > 0 && maxWeight > 0) {
|
||||
List< List<Integer> > c = new ArrayList< List<Integer> >();
|
||||
List<Integer> curr = new ArrayList<Integer>();
|
||||
|
||||
c.add(curr);
|
||||
for (int j = 0; j <= maxWeight; j++)
|
||||
curr.add(0);
|
||||
for (int i = 1; i <= n; i++) {
|
||||
List<Integer> prev = curr;
|
||||
c.add(curr = new ArrayList<Integer>());
|
||||
for (int j = 0; j <= maxWeight; j++) {
|
||||
if (j > 0) {
|
||||
int wH = itemList.get(i-1).getWeight();
|
||||
curr.add(
|
||||
(wH > j)
|
||||
?
|
||||
prev.get(j)
|
||||
:
|
||||
Math.max(
|
||||
prev.get(j),
|
||||
itemList.get(i-1).getValue() + prev.get(j-wH)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
curr.add(0);
|
||||
}
|
||||
} // for (j...)
|
||||
} // for (i...)
|
||||
profit = curr.get(maxWeight);
|
||||
|
||||
for (int i = n, j = maxWeight; i > 0 && j >= 0; i--) {
|
||||
int tempI = c.get(i).get(j);
|
||||
int tempI_1 = c.get(i-1).get(j);
|
||||
if (
|
||||
(i == 0 && tempI > 0)
|
||||
||
|
||||
(i > 0 && tempI != tempI_1)
|
||||
)
|
||||
{
|
||||
Item iH = itemList.get(i-1);
|
||||
int wH = iH.getWeight();
|
||||
iH.setInKnapsack(1);
|
||||
j -= wH;
|
||||
solutionWeight += wH;
|
||||
}
|
||||
} // for()
|
||||
calculated = true;
|
||||
} // if()
|
||||
return itemList;
|
||||
}
|
||||
|
||||
// add an item to the item list
|
||||
public void add(String name, int weight, int value) {
|
||||
if (name.equals(""))
|
||||
name = "" + (itemList.size() + 1);
|
||||
itemList.add(new Item(name, weight, value));
|
||||
setInitialStateForCalculation();
|
||||
}
|
||||
|
||||
// add an item to the item list
|
||||
public void add(int weight, int value) {
|
||||
add("", weight, value); // the name will be "itemList.size() + 1"!
|
||||
}
|
||||
|
||||
// remove an item from the item list
|
||||
public void remove(String name) {
|
||||
for (Iterator<Item> it = itemList.iterator(); it.hasNext(); ) {
|
||||
if (name.equals(it.next().getName())) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
setInitialStateForCalculation();
|
||||
}
|
||||
|
||||
// remove all items from the item list
|
||||
public void removeAllItems() {
|
||||
itemList.clear();
|
||||
setInitialStateForCalculation();
|
||||
}
|
||||
|
||||
public int getProfit() {
|
||||
if (!calculated)
|
||||
calcSolution();
|
||||
return profit;
|
||||
}
|
||||
|
||||
public int getSolutionWeight() {return solutionWeight;}
|
||||
public boolean isCalculated() {return calculated;}
|
||||
public int getMaxWeight() {return maxWeight;}
|
||||
|
||||
public void setMaxWeight(int _maxWeight) {
|
||||
maxWeight = Math.max(_maxWeight, 0);
|
||||
}
|
||||
|
||||
public void setItemList(List<Item> _itemList) {
|
||||
if (_itemList != null) {
|
||||
itemList = _itemList;
|
||||
for (Item item : _itemList) {
|
||||
item.checkMembers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set the member with name "inKnapsack" by all items:
|
||||
private void setInKnapsackByAll(int inKnapsack) {
|
||||
for (Item item : itemList)
|
||||
if (inKnapsack > 0)
|
||||
item.setInKnapsack(1);
|
||||
else
|
||||
item.setInKnapsack(0);
|
||||
}
|
||||
|
||||
// set the data members of class in the state of starting the calculation:
|
||||
protected void setInitialStateForCalculation() {
|
||||
setInKnapsackByAll(0);
|
||||
calculated = false;
|
||||
profit = 0;
|
||||
solutionWeight = 0;
|
||||
}
|
||||
|
||||
} // class
|
||||
71
Task/Knapsack-problem-0-1/Java/knapsack-problem-0-1-3.java
Normal file
71
Task/Knapsack-problem-0-1/Java/knapsack-problem-0-1-3.java
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
package hu.pj.obj;
|
||||
|
||||
public class Item {
|
||||
|
||||
protected String name = "";
|
||||
protected int weight = 0;
|
||||
protected int value = 0;
|
||||
protected int bounding = 1; // the maximal limit of item's pieces
|
||||
protected int inKnapsack = 0; // the pieces of item in solution
|
||||
|
||||
public Item() {}
|
||||
|
||||
public Item(Item item) {
|
||||
setName(item.name);
|
||||
setWeight(item.weight);
|
||||
setValue(item.value);
|
||||
setBounding(item.bounding);
|
||||
}
|
||||
|
||||
public Item(int _weight, int _value) {
|
||||
setWeight(_weight);
|
||||
setValue(_value);
|
||||
}
|
||||
|
||||
public Item(int _weight, int _value, int _bounding) {
|
||||
setWeight(_weight);
|
||||
setValue(_value);
|
||||
setBounding(_bounding);
|
||||
}
|
||||
|
||||
public Item(String _name, int _weight, int _value) {
|
||||
setName(_name);
|
||||
setWeight(_weight);
|
||||
setValue(_value);
|
||||
}
|
||||
|
||||
public Item(String _name, int _weight, int _value, int _bounding) {
|
||||
setName(_name);
|
||||
setWeight(_weight);
|
||||
setValue(_value);
|
||||
setBounding(_bounding);
|
||||
}
|
||||
|
||||
public void setName(String _name) {name = _name;}
|
||||
public void setWeight(int _weight) {weight = Math.max(_weight, 0);}
|
||||
public void setValue(int _value) {value = Math.max(_value, 0);}
|
||||
|
||||
public void setInKnapsack(int _inKnapsack) {
|
||||
inKnapsack = Math.min(getBounding(), Math.max(_inKnapsack, 0));
|
||||
}
|
||||
|
||||
public void setBounding(int _bounding) {
|
||||
bounding = Math.max(_bounding, 0);
|
||||
if (bounding == 0)
|
||||
inKnapsack = 0;
|
||||
}
|
||||
|
||||
public void checkMembers() {
|
||||
setWeight(weight);
|
||||
setValue(value);
|
||||
setBounding(bounding);
|
||||
setInKnapsack(inKnapsack);
|
||||
}
|
||||
|
||||
public String getName() {return name;}
|
||||
public int getWeight() {return weight;}
|
||||
public int getValue() {return value;}
|
||||
public int getInKnapsack() {return inKnapsack;}
|
||||
public int getBounding() {return bounding;}
|
||||
|
||||
} // class
|
||||
50
Task/Knapsack-problem-0-1/LSL/knapsack-problem-0-1.lsl
Normal file
50
Task/Knapsack-problem-0-1/LSL/knapsack-problem-0-1.lsl
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
string sNOTECARD = "Knapsack_Problem_0_1_Data.txt";
|
||||
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));
|
||||
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#[[Flatten@
|
||||
Position[LinearProgramming[-#[[;; , 3]], -{#[[;; , 2]]}, -{400},
|
||||
{0, 1} & /@ #, Integers], 1], 1]] &@
|
||||
{{"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}}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*Knapsack
|
||||
|
||||
This model finds the integer optimal packing of a knapsack
|
||||
|
||||
Nigel_Galloway
|
||||
January 9th., 2012
|
||||
*/
|
||||
|
||||
set Items;
|
||||
param weight{t in Items};
|
||||
param value{t in Items};
|
||||
|
||||
var take{t in Items}, binary;
|
||||
|
||||
knap_weight : sum{t in Items} take[t] * weight[t] <= 400;
|
||||
|
||||
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
|
||||
;
|
||||
|
||||
end;
|
||||
101
Task/Knapsack-problem-0-1/PHP/knapsack-problem-0-1-1.php
Normal file
101
Task/Knapsack-problem-0-1/PHP/knapsack-problem-0-1-1.php
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#########################################################
|
||||
# 0-1 Knapsack Problem Solve with memoization optimize and index returns
|
||||
# $w = weight of item
|
||||
# $v = value of item
|
||||
# $i = index
|
||||
# $aW = Available Weight
|
||||
# $m = Memo items array
|
||||
# PHP Translation from Python, Memoization,
|
||||
# and index return functionality added by Brian Berneker
|
||||
#
|
||||
#It works uncorrectly! For examle if $aw=4. Max value is true, but no "Array Indices" and its parameters are displayed
|
||||
#
|
||||
#########################################################
|
||||
|
||||
function knapSolveFast2($w,$v,$i,$aW,&$m) {
|
||||
|
||||
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 {
|
||||
|
||||
// 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,$pickedItems);
|
||||
|
||||
if ($w[$i] > $aW) { // Does it return too many?
|
||||
|
||||
$m[$i][$aW] = $without_i; // Memo without including this one
|
||||
$m['picked'][$i][$aW] = array(); // and a blank array entry...
|
||||
return array($without_i,array()); // 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,$pickedItems);
|
||||
$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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$items4 = array("map","compass","water","sandwich","glucose","tin","banana","apple","cheese","beer","suntan cream","camera","t-shirt","trousers","umbrella","waterproof trousers","waterproof overclothes","note-case","sunglasses","towel","socks","book");
|
||||
$w4 = array(9,13,153,50,15,68,27,39,23,52,11,32,24,48,73,42,43,22,7,18,4,30);
|
||||
$v4 = array(150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,50,10);
|
||||
|
||||
## Initialize
|
||||
$numcalls = 0; $m = array(); $pickedItems = array();
|
||||
|
||||
## Solve
|
||||
list ($m4,$pickedItems) = knapSolveFast2($w4, $v4, sizeof($v4) -1, 400,$m,$pickedItems);
|
||||
|
||||
# Display Result
|
||||
echo "<b>Items:</b><br>".join(", ",$items4)."<br>";
|
||||
echo "<b>Max Value Found:</b><br>$m4 (in $numcalls calls)<br>";
|
||||
echo "<b>Array Indices:</b><br>".join(",",$pickedItems)."<br>";
|
||||
|
||||
|
||||
echo "<b>Chosen Items:</b><br>";
|
||||
echo "<table border cellspacing=0>";
|
||||
echo "<tr><td>Item</td><td>Value</td><td>Weight</td></tr>";
|
||||
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>";
|
||||
}
|
||||
echo "<tr><td align=right><b>Totals</b></td><td>$totalVal</td><td>$totalWt</td></tr>";
|
||||
echo "</table><hr>";
|
||||
94
Task/Knapsack-problem-0-1/PHP/knapsack-problem-0-1-2.php
Normal file
94
Task/Knapsack-problem-0-1/PHP/knapsack-problem-0-1-2.php
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#########################################################
|
||||
# 0-1 Knapsack Problem Solve
|
||||
# $w = weight of item
|
||||
# $v = value of item
|
||||
# $i = index
|
||||
# $aW = Available Weight
|
||||
# PHP Translation by Brian Berneker
|
||||
#########################################################
|
||||
|
||||
function knapSolve($w,$v,$i,$aW) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#########################################################
|
||||
# 0-1 Knapsack Problem Solve (with "memo"-ization optimization)
|
||||
# $w = weight of item
|
||||
# $v = value of item
|
||||
# $i = index
|
||||
# $aW = Available Weight
|
||||
# $m = 'memo' array
|
||||
# PHP Translation by Brian Berneker
|
||||
#########################################################
|
||||
|
||||
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>";
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$w3 = array(1, 1, 1, 2, 2, 2, 4, 4, 4, 44, 96, 96, 96);
|
||||
$v3 = array(1, 1, 1, 2, 2, 2, 4, 4, 4, 44, 96, 96, 96);
|
||||
|
||||
$numcalls = 0;
|
||||
$m = array();
|
||||
$m3 = knapSolveFast($w3, $v3, sizeof($v3) -1, 54,$m);
|
||||
print_r($w3); echo "<br>FAST: ";
|
||||
echo "<b>Max: $m3</b> ($numcalls calls)<br><br>";
|
||||
|
||||
|
||||
$numcalls = 0;
|
||||
$m = array();
|
||||
$m3 = knapSolve($w3, $v3, sizeof($v3) -1, 54 );
|
||||
print_r($w3); echo "<br>";
|
||||
echo "<b>Max: $m3</b> ($numcalls calls)<br><br>";
|
||||
65
Task/Knapsack-problem-0-1/Perl/knapsack-problem-0-1.pl
Normal file
65
Task/Knapsack-problem-0-1/Perl/knapsack-problem-0-1.pl
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
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
|
||||
TABLE
|
||||
|
||||
my (@name, @weight, @value);
|
||||
for (split "\n", $raw) {
|
||||
for ([ split /\t+/ ]) {
|
||||
push @name, $_->[0];
|
||||
push @weight, $_->[1];
|
||||
push @value, $_->[2];
|
||||
}
|
||||
}
|
||||
|
||||
my $max_weight = 400;
|
||||
my @p = (map([[0, []], map undef, 0 .. $max_weight], 0 .. $#name),
|
||||
[ map([0, []], 0 .. $max_weight + 1)]);
|
||||
|
||||
sub optimal {
|
||||
my ($i, $w) = @_;
|
||||
|
||||
if (!defined $p[$i][$w]) {
|
||||
if ($weight[$i] > $w) {
|
||||
$p[$i][$w] = optimal($i - 1, $w)
|
||||
} else {
|
||||
my $x = optimal($i - 1, $w);
|
||||
my $y = optimal($i - 1, $w - $weight[$i]);
|
||||
|
||||
if ($x->[0] > $y->[0] + $value[$i]) {
|
||||
$p[$i][$w] = $x
|
||||
} else {
|
||||
$p[$i][$w] = [ $y->[0] + $value[$i],
|
||||
[ @{$y->[1]}, $name[$i] ]]
|
||||
}
|
||||
}
|
||||
}
|
||||
return $p[$i][$w]
|
||||
}
|
||||
|
||||
my $sol = optimal($#name, $max_weight);
|
||||
print "$sol->[0]: @{$sol->[1]}\n";
|
||||
|
||||
# prints:
|
||||
# 1030: map compass water sandwich glucose banana suntancream waterproof trousers
|
||||
# waterproof overclothes note-case sunglasses socks
|
||||
27
Task/Knapsack-problem-0-1/PicoLisp/knapsack-problem-0-1.l
Normal file
27
Task/Knapsack-problem-0-1/PicoLisp/knapsack-problem-0-1.l
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
(de *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) )
|
||||
|
||||
# Dynamic programming solution
|
||||
(de knapsack (Lst W)
|
||||
(when Lst
|
||||
(cache '*KnapCache (pack (length Lst) ":" W)
|
||||
(let X (knapsack (cdr Lst) W)
|
||||
(if (ge0 (- W (cadar Lst)))
|
||||
(let Y (cons (car Lst) (knapsack (cdr Lst) @))
|
||||
(if (> (sum caddr X) (sum caddr Y)) X Y) )
|
||||
X ) ) ) ) )
|
||||
|
||||
(let K (knapsack *Items 400)
|
||||
(for I K
|
||||
(apply tab I (3 -24 6 6) NIL) )
|
||||
(tab (27 6 6) NIL (sum cadr K) (sum caddr K)) )
|
||||
70
Task/Knapsack-problem-0-1/Prolog/knapsack-problem-0-1-1.pro
Normal file
70
Task/Knapsack-problem-0-1/Prolog/knapsack-problem-0-1-1.pro
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
:- use_module(library(clpfd)).
|
||||
|
||||
knapsack :-
|
||||
L = [
|
||||
item(map, 9, 150),
|
||||
item(compass, 13, 35),
|
||||
item(water, 153, 200),
|
||||
item(sandwich, 50, 160),
|
||||
item(glucose, 15, 60),
|
||||
item(tin, 68, 45),
|
||||
item(banana, 27, 60),
|
||||
item(apple, 39, 40),
|
||||
item(cheese, 23, 30),
|
||||
item(beer, 52, 10),
|
||||
item('suntan cream', 11, 70),
|
||||
item(camera, 32, 30),
|
||||
item('t-shirt', 24, 15),
|
||||
item(trousers, 48, 10),
|
||||
item(umbrella, 73, 40),
|
||||
item('waterproof trousers', 42, 70),
|
||||
item('waterproof overclothes', 43, 75),
|
||||
item('note-case',22, 80),
|
||||
item(sunglasses, 7, 20),
|
||||
item(towel, 18, 12),
|
||||
item(socks, 4, 50),
|
||||
item(book, 30, 10 )],
|
||||
length(L, N),
|
||||
length(R, N),
|
||||
R ins 0..1,
|
||||
maplist(arg(2), L, LW),
|
||||
maplist(arg(3), L, LV),
|
||||
scalar_product(LW, R, #=<, 400),
|
||||
scalar_product(LV, R, #=, VM),
|
||||
labeling([max(VM)], R),
|
||||
scalar_product(LW, R, #=, WM),
|
||||
%% affichage des résultats
|
||||
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(A1,A2,A3, L, R, WM, VM).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% to show the results in a good way
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
compute_lenword([], N, N).
|
||||
compute_lenword([item(Name, _, _)|T], N, NF):-
|
||||
atom_length(Name, L),
|
||||
( L > N -> N1 = L; N1 = N),
|
||||
compute_lenword(T, N1, NF).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
print_results(A1,A2,A3, [], [], WM, WR) :-
|
||||
sformat(W1, A1, [' ']),
|
||||
sformat(W2, A2, [WM]),
|
||||
sformat(W3, A3, [WR]),
|
||||
format('~w~w~w~n', [W1,W2,W3]).
|
||||
|
||||
|
||||
print_results(A1,A2,A3, [_H|T], [0|TR], WM, VM) :-
|
||||
print_results(A1,A2,A3, T, TR, WM, VM).
|
||||
|
||||
print_results(A1, A2, A3, [item(Name, W, V)|T], [1|TR], WM, VM) :-
|
||||
sformat(W1, A1, [Name]),
|
||||
sformat(W2, A2, [W]),
|
||||
sformat(W3, A3, [V]),
|
||||
format('~w~w~w~n', [W1,W2,W3]),
|
||||
print_results(A1, A2, A3, T, TR, WM, VM).
|
||||
78
Task/Knapsack-problem-0-1/Prolog/knapsack-problem-0-1-2.pro
Normal file
78
Task/Knapsack-problem-0-1/Prolog/knapsack-problem-0-1-2.pro
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
:- 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).
|
||||
|
||||
|
||||
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).
|
||||
|
||||
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).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
print_results(_S, A1, A2, A3, [], [], WM, VM) :-
|
||||
sformat(W1, A1, [' ']),
|
||||
sformat(W2, A2, [WM]),
|
||||
sformat(W3, A3, [VM]),
|
||||
format('~w~w~w~n', [W1,W2,W3]).
|
||||
|
||||
|
||||
print_results(S, A1, A2, A3, [(Name, W, V)|T], [N|TN], W1, V1) :-
|
||||
variable_value(S, x(N), X),
|
||||
( X = 0 -> W1 = W2, V1 = V2
|
||||
; sformat(S1, A1, [Name]),
|
||||
sformat(S2, A2, [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).
|
||||
31
Task/Knapsack-problem-0-1/Python/knapsack-problem-0-1-1.py
Normal file
31
Task/Knapsack-problem-0-1/Python/knapsack-problem-0-1-1.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
from itertools import combinations
|
||||
|
||||
def anycomb(items):
|
||||
' return combinations of any length from the items '
|
||||
return ( comb
|
||||
for r in range(1, len(items)+1)
|
||||
for comb in combinations(items, r)
|
||||
)
|
||||
|
||||
def totalvalue(comb):
|
||||
' Totalise a particular combination of items'
|
||||
totwt = totval = 0
|
||||
for item, wt, val in comb:
|
||||
totwt += wt
|
||||
totval += val
|
||||
return (totval, -totwt) if totwt <= 400 else (0, 0)
|
||||
|
||||
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),
|
||||
)
|
||||
bagged = max( anycomb(items), key=totalvalue) # max val or min wt if values equal
|
||||
print("Bagged the following items\n " +
|
||||
'\n '.join(sorted(item for item,_,_ in bagged)))
|
||||
val, wt = totalvalue(bagged)
|
||||
print("for a total value of %i and a total weight of %i" % (val, -wt))
|
||||
53
Task/Knapsack-problem-0-1/Python/knapsack-problem-0-1-2.py
Normal file
53
Task/Knapsack-problem-0-1/Python/knapsack-problem-0-1-2.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
try:
|
||||
xrange
|
||||
except:
|
||||
xrange = range
|
||||
|
||||
def totalvalue(comb):
|
||||
' Totalise a particular combination of items'
|
||||
totwt = totval = 0
|
||||
for item, wt, val in comb:
|
||||
totwt += wt
|
||||
totval += val
|
||||
return (totval, -totwt) if totwt <= 400 else (0, 0)
|
||||
|
||||
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),
|
||||
)
|
||||
|
||||
def knapsack01_dp(items, limit):
|
||||
table = [[0 for w in range(limit + 1)] for j in xrange(len(items) + 1)]
|
||||
|
||||
for j in xrange(1, len(items) + 1):
|
||||
item, wt, val = items[j-1]
|
||||
for w in xrange(1, limit + 1):
|
||||
if wt > w:
|
||||
table[j][w] = table[j-1][w]
|
||||
else:
|
||||
table[j][w] = max(table[j-1][w],
|
||||
table[j-1][w-wt] + val)
|
||||
|
||||
result = []
|
||||
w = limit
|
||||
for j in range(len(items), 0, -1):
|
||||
was_added = table[j][w] != table[j-1][w]
|
||||
|
||||
if was_added:
|
||||
item, wt, val = items[j-1]
|
||||
result.append(items[j-1])
|
||||
w -= wt
|
||||
|
||||
return result
|
||||
|
||||
|
||||
bagged = knapsack01_dp(items, 400)
|
||||
print("Bagged the following items\n " +
|
||||
'\n '.join(sorted(item for item,_,_ in bagged)))
|
||||
val, wt = totalvalue(bagged)
|
||||
print("for a total value of %i and a total weight of %i" % (val, -wt))
|
||||
171
Task/Knapsack-problem-0-1/REXX/knapsack-problem-0-1.rexx
Normal file
171
Task/Knapsack-problem-0-1/REXX/knapsack-problem-0-1.rexx
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/*REXX pgm solves a knapsack problem (22 items with weight restriction).*/
|
||||
@.=
|
||||
@.1 = 'map 9 150'
|
||||
@.2 = 'compass 13 35'
|
||||
@.3 = 'water 153 200'
|
||||
@.4 = 'sandwich 50 160'
|
||||
@.5 = 'glucose 15 60'
|
||||
@.6 = 'tin 68 45'
|
||||
@.7 = 'banana 27 60'
|
||||
@.8 = 'apple 39 40'
|
||||
@.9 = 'cheese 23 30'
|
||||
@.10 = 'beer 52 10'
|
||||
@.11 = 'suntan_cream 11 70'
|
||||
@.12 = 'camera 32 30'
|
||||
@.13 = 'T-shirt 24 15'
|
||||
@.14 = 'trousers 48 10'
|
||||
@.15 = 'umbrella 73 40'
|
||||
@.16 = 'waterproof_trousers 42 70'
|
||||
@.17 = 'waterproof_overclothes 43 75'
|
||||
@.18 = 'note-case 22 80'
|
||||
@.19 = 'sunglasses 7 20'
|
||||
@.20 = 'towel 18 12'
|
||||
@.21 = 'socks 4 50'
|
||||
@.22 = 'book 30 10'
|
||||
maxWeight=400 /*the maximum weight for knapsack*/
|
||||
say; say 'maximum weight allowed for a knapsack:' comma(maxWeight); say
|
||||
maxL=length('item') /*maximum width for table names. */
|
||||
maxL=length('knapsack items') /*maximum width for table names. */
|
||||
maxW=length('weight') /* " " " " weights*/
|
||||
maxV=length('value') /* " " " " values.*/
|
||||
maxQ=length('pieces') /* " " " " quant. */
|
||||
highQ=0 /*max quantity specified (if any)*/
|
||||
items=0; i.=; w.=0; v.=0; q.=0; Tw=0; Tv=0; Tq=0 /*initialize stuff.*/
|
||||
/*────────────────────────────────sort the choices by decreasing weight.*/
|
||||
/*this minimizes # combinations. */
|
||||
do j=1 while @.j\=='' /*process each choice and sort. */
|
||||
_=@.j; _wt=word(_,2) /*choose first item (arbitrary). */
|
||||
_wt=word(_,2)
|
||||
do k=j+1 while @.k\=='' /*find a possible heavier item. */
|
||||
?wt=word(@.k,2)
|
||||
if ?wt>_wt then do; _=@.k; @.k=@.j; @.j=_; _wt=?wt; end
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
obj=j-1 /*adjust for the DO loop index. */
|
||||
/*────────────────────────────────build list of choices.────────────────*/
|
||||
do j=1 for obj /*build a list of choices. */
|
||||
_=space(@.j) /*remove superfluous blanks. */
|
||||
parse var _ item w v q . /*parse original choice for table*/
|
||||
if w>maxWeight then iterate /*if the weight > maximum, ignore*/
|
||||
Tw=Tw+w; Tv=Tv+v; Tq=Tq+1 /*add totals up (for alignment). */
|
||||
maxL=max(maxL,length(item)) /*find maximum width for item. */
|
||||
if q=='' then q=1
|
||||
highQ=max(highQ,q)
|
||||
items=items+1 /*bump the item counter. */
|
||||
i.items=item; w.items=w; v.items=v; q.items=q
|
||||
do k=2 to q; items=items+1 /*bump the item counter. */
|
||||
i.items=item; w.items=w; v.items=v; q.items=q
|
||||
Tw=Tw+w; Tv=Tv+v; Tq=Tq+1
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
|
||||
maxW=max(maxW,length(comma(Tw))) /*find maximum width for weight. */
|
||||
maxV=max(maxV,length(comma(Tv))) /* " " " " value. */
|
||||
maxQ=max(maxQ,length(comma(Tq))) /* " " " " quantity*/
|
||||
maxL=maxL+maxL%4+4 /*extend width of name for table.*/
|
||||
/*────────────────────────────────show the list of choices.─────────────*/
|
||||
call hdr 'item'; do j=1 for obj /*show all choices, nice format. */
|
||||
parse var @.j item weight value q .
|
||||
if highq==1 then q=
|
||||
else if q=='' then q=1
|
||||
call show item,weight,value,q
|
||||
end /*j*/
|
||||
|
||||
say; say 'number of items:' items; say
|
||||
/*─────────────────────────────────────examine the possible choices. */
|
||||
h=items; ho=h+1; m=maxWeight; $=0; call sim22
|
||||
/*─────────────────────────────────────show the best choice (weight,val)*/
|
||||
do h-1; ?=strip(strip(?),"L",0); end
|
||||
bestC=?; bestW=0; bestV=$; highQ=0; totP=words(bestC)
|
||||
call hdr 'best choice'
|
||||
do j=1 to totP /*J is modified within DO loop. */
|
||||
_=word(bestC,j); _w=w._; _v=v._; q=1
|
||||
if _==0 then iterate
|
||||
do k=j+1 to totP
|
||||
__=word(bestC,k); if i._\==i.__ then leave
|
||||
j=j+1; w._=w._+_w; v._=v._+_v; q=q+1
|
||||
end /*k*/
|
||||
call show i._,w._,v._,q; bestW=bestw+w._
|
||||
end /*j*/
|
||||
call hdr2; say
|
||||
call show 'best weight' ,bestW /*show a nicely formatted winnerW*/
|
||||
call show 'best value' ,,bestV /*show a nicely formatted winnerV*/
|
||||
call show 'knapsack items',,,totP /*show a nicely formatted pieces.*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*────────────────────────────────COMMA subroutine──────────────────────*/
|
||||
comma: procedure; parse arg _,c,p,t;arg ,cu;c=word(c ",",1)
|
||||
if cu=='BLANK' then c=' ';o=word(p 3,1);p=abs(o);t=word(t 999999999,1)
|
||||
if \datatype(p,'W')|\datatype(t,'W')|p==0|arg()>4 then return _;n=_'.9'
|
||||
#=123456789;k=0;if o<0 then do;b=verify(_,' ');if b==0 then return _
|
||||
e=length(_)-verify(reverse(_),' ')+1;end;else do;b=verify(n,#,"M")
|
||||
e=verify(n,#'0',,verify(n,#"0.",'M'))-p-1;end
|
||||
do j=e to b by -p while k<t;_=insert(c,_,j);k=k+1;end;return _
|
||||
/*────────────────────────────────HDR subroutine────────────────────────*/
|
||||
hdr: parse arg _item_,_; if highq\==1 then _=center('pieces',maxq)
|
||||
call show center( _item_ ,maxL),,
|
||||
center('weight',maxW),,
|
||||
center('value' ,maxV),,
|
||||
center(_ ,maxQ)
|
||||
call hdr2
|
||||
return
|
||||
/*────────────────────────────────HDR2 subroutine───────────────────────*/
|
||||
hdr2: _=maxQ; if highq==1 then _=0; call show copies('=' ,maxL),,
|
||||
copies('=' ,maxW),,
|
||||
copies('=' ,maxV),,
|
||||
copies('=' ,_ )
|
||||
return
|
||||
/*────────────────────────────────J? subroutine─────────────────────────*/
|
||||
j?: parse arg _,?; $=value('V'_); do j=1 for _; ?=? value('J'j); end; return
|
||||
/*────────────────────────────────SHOW subroutine───────────────────────*/
|
||||
show: parse arg _item,_weight,_value,_quant
|
||||
say translate(left(_item,maxL,'─'),,'_'),
|
||||
right(comma(_weight),maxW),
|
||||
right(comma(_value ),maxV),
|
||||
right(comma(_quant ),maxQ)
|
||||
return
|
||||
/*────────────────────────────────SIM22 subroutine──────────────────────*/
|
||||
sim22: do j1=0 for h+1; w1=w.j1;v1=v.j1;if v1>$ then call j? 1
|
||||
do j2=j1+(j1\==0) to h
|
||||
if w.j2+w1>m then iterate j1;w2=w1+w.j2;v2=v1+v.j2;if v2>$ then call j? 2
|
||||
do j3=j2+(j2\==0) to h
|
||||
if w.j3+w2>m then iterate j2;w3=w2+w.j3;v3=v2+v.j3;if v3>$ then call j? 3
|
||||
do j4=j3+(j3\==0) to h
|
||||
if w.j4+w3>m then iterate j3;w4=w3+w.j4;v4=v3+v.j4;if v4>$ then call j? 4
|
||||
do j5=j4+(j4\==0) to h
|
||||
if w.j5+w4>m then iterate j4;w5=w4+w.j5;v5=v4+v.j5;if v5>$ then call j? 5
|
||||
do j6=j5+(j5\==0) to h
|
||||
if w.j6+w5>m then iterate j5;w6=w5+w.j6;v6=v5+v.j6;if v6>$ then call j? 6
|
||||
do j7=j6+(j6\==0) to h
|
||||
if w.j7+w6>m then iterate j6;w7=w6+w.j7;v7=v6+v.j7;if v7>$ then call j? 7
|
||||
do j8=j7+(j7\==0) to h
|
||||
if w.j8+w7>m then iterate j7;w8=w7+w.j8;v8=v7+v.j8;if v8>$ then call j? 8
|
||||
do j9=j8+(j8\==0) to h
|
||||
if w.j9+w8>m then iterate j8;w9=w8+w.j9;v9=v8+v.j9;if v9>$ then call j? 9
|
||||
do j10=j9+(j9\==0) to h
|
||||
if w.j10+w9>m then iterate j9;w10=w9+w.j10;v10=v9+v.j10;if v10>$ then call j? 10
|
||||
do j11=j10+(j10\==0) to h
|
||||
if w.j11+w10>m then iterate j10;w11=w10+w.j11;v11=v10+v.j11;if v11>$ then call j? 11
|
||||
do j12=j11+(j11\==0) to h
|
||||
if w.j12+w11>m then iterate j11;w12=w11+w.j12;v12=v11+v.j12;if v12>$ then call j? 12
|
||||
do j13=j12+(j12\==0) to h
|
||||
if w.j13+w12>m then iterate j12;w13=w12+w.j13;v13=v12+v.j13;if v13>$ then call j? 13
|
||||
do j14=j13+(j13\==0) to h
|
||||
if w.j14+w13>m then iterate j13;w14=w13+w.j14;v14=v13+v.j14;if v14>$ then call j? 14
|
||||
do j15=j14+(j14\==0) to h
|
||||
if w.j15+w14>m then iterate j14;w15=w14+w.j15;v15=v14+v.j15;if v15>$ then call j? 15
|
||||
do j16=j15+(j15\==0) to h
|
||||
if w.j16+w15>m then iterate j15;w16=w15+w.j16;v16=v15+v.j16;if v16>$ then call j? 16
|
||||
do j17=j16+(j16\==0) to h
|
||||
if w.j17+w16>m then iterate j16;w17=w16+w.j17;v17=v16+v.j17;if v17>$ then call j? 17
|
||||
do j18=j17+(j17\==0) to h
|
||||
if w.j18+w17>m then iterate j17;w18=w17+w.j18;v18=v17+v.j18;if v18>$ then call j? 18
|
||||
do j19=j18+(j18\==0) to h
|
||||
if w.j19+w18>m then iterate j18;w19=w18+w.j19;v19=v18+v.j19;if v19>$ then call j? 19
|
||||
do j20=j19+(j19\==0) to h
|
||||
if w.j20+w19>m then iterate j19;w20=w19+w.j20;v20=v19+v.j20;if v20>$ then call j? 20
|
||||
do j21=j20+(j20\==0) to h
|
||||
if w.j21+w20>m then iterate j20;w21=w20+w.j21;v21=v20+v.j21;if v21>$ then call j? 21
|
||||
do j22=j21+(j21\==0) to h
|
||||
if w.j22+w21>m then iterate j21;w22=w21+w.j22;v22=v21+v.j22;if v22>$ then call j? 22
|
||||
end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end
|
||||
return
|
||||
57
Task/Knapsack-problem-0-1/Ruby/knapsack-problem-0-1-1.rb
Normal file
57
Task/Knapsack-problem-0-1/Ruby/knapsack-problem-0-1-1.rb
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
KnapsackItem = Struct.new(:name, :weight, :value)
|
||||
potential_items = [
|
||||
KnapsackItem.new('map', 9, 150), KnapsackItem.new('compass', 13, 35),
|
||||
KnapsackItem.new('water', 153, 200), KnapsackItem.new('sandwich', 50, 160),
|
||||
KnapsackItem.new('glucose', 15, 60), KnapsackItem.new('tin', 68, 45),
|
||||
KnapsackItem.new('banana', 27, 60), KnapsackItem.new('apple', 39, 40),
|
||||
KnapsackItem.new('cheese', 23, 30), KnapsackItem.new('beer', 52, 10),
|
||||
KnapsackItem.new('suntan cream', 11, 70), KnapsackItem.new('camera', 32, 30),
|
||||
KnapsackItem.new('t-shirt', 24, 15), KnapsackItem.new('trousers', 48, 10),
|
||||
KnapsackItem.new('umbrella', 73, 40), KnapsackItem.new('waterproof trousers', 42, 70),
|
||||
KnapsackItem.new('waterproof overclothes', 43, 75), KnapsackItem.new('note-case', 22, 80),
|
||||
KnapsackItem.new('sunglasses', 7, 20), KnapsackItem.new('towel', 18, 12),
|
||||
KnapsackItem.new('socks', 4, 50), KnapsackItem.new('book', 30, 10),
|
||||
]
|
||||
knapsack_capacity = 400
|
||||
|
||||
class Array
|
||||
# do something for each element of the array's power set
|
||||
def power_set
|
||||
yield [] if block_given?
|
||||
self.inject([[]]) do |ps, elem|
|
||||
r = []
|
||||
ps.each do |i|
|
||||
r << i
|
||||
new_subset = i + [elem]
|
||||
yield new_subset if block_given?
|
||||
r << new_subset
|
||||
end
|
||||
r
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
maxval = 0
|
||||
solutions = []
|
||||
|
||||
potential_items.power_set do |subset|
|
||||
weight = subset.inject(0) {|w, elem| w += elem.weight}
|
||||
next if weight > knapsack_capacity
|
||||
|
||||
value = subset.inject(0) {|v, elem| v += elem.value}
|
||||
if value == maxval
|
||||
solutions << subset
|
||||
elsif value > maxval
|
||||
maxval = value
|
||||
solutions = [subset]
|
||||
end
|
||||
end
|
||||
|
||||
puts "value: #{maxval}"
|
||||
solutions.each do |set|
|
||||
items = []
|
||||
wt = 0
|
||||
set.each {|elem| wt += elem.weight; items << elem.name}
|
||||
puts "weight: #{wt}"
|
||||
puts "items: #{items.sort.join(',')}"
|
||||
end
|
||||
84
Task/Knapsack-problem-0-1/Ruby/knapsack-problem-0-1-2.rb
Normal file
84
Task/Knapsack-problem-0-1/Ruby/knapsack-problem-0-1-2.rb
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
KnapsackItem = Struct.new(:name, :cost, :value)
|
||||
KnapsackProblem = Struct.new(:items, :max_cost)
|
||||
|
||||
def dynamic_programming_knapsack(problem)
|
||||
num_items = problem.items.size
|
||||
items = problem.items
|
||||
max_cost = problem.max_cost
|
||||
|
||||
cost_matrix = zeros(num_items, max_cost+1)
|
||||
|
||||
num_items.times do |i|
|
||||
(max_cost + 1).times do |j|
|
||||
if(items[i].cost > j)
|
||||
cost_matrix[i][j] = cost_matrix[i-1][j]
|
||||
else
|
||||
cost_matrix[i][j] = [cost_matrix[i-1][j], items[i].value + cost_matrix[i-1][j-items[i].cost]].max
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cost_matrix
|
||||
end
|
||||
|
||||
def get_used_items(problem, cost_matrix)
|
||||
i = cost_matrix.size - 1
|
||||
currentCost = cost_matrix[0].size - 1
|
||||
marked = Array.new(cost_matrix.size, 0)
|
||||
|
||||
while(i >= 0 && currentCost >= 0)
|
||||
if(i == 0 && cost_matrix[i][currentCost] > 0 ) || (cost_matrix[i][currentCost] != cost_matrix[i-1][currentCost])
|
||||
marked[i] = 1
|
||||
currentCost -= problem.items[i].cost
|
||||
end
|
||||
i -= 1
|
||||
end
|
||||
marked
|
||||
end
|
||||
|
||||
def get_list_of_used_items_names(problem, cost_matrix)
|
||||
items = problem.items
|
||||
used_items = get_used_items(problem, cost_matrix)
|
||||
|
||||
result = []
|
||||
|
||||
used_items.each_with_index do |item,i|
|
||||
if item > 0
|
||||
result << items[i].name
|
||||
end
|
||||
end
|
||||
|
||||
result.sort.join(', ')
|
||||
end
|
||||
|
||||
def zeros(rows, cols)
|
||||
Array.new(rows) do |row|
|
||||
Array.new(cols, 0)
|
||||
end
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
|
||||
items = [
|
||||
KnapsackItem.new('map' , 9 , 150) , KnapsackItem.new('compass' , 13 , 35) ,
|
||||
KnapsackItem.new('water' , 153 , 200) , KnapsackItem.new('sandwich' , 50 , 160) ,
|
||||
KnapsackItem.new('glucose' , 15 , 60) , KnapsackItem.new('tin' , 68 , 45) ,
|
||||
KnapsackItem.new('banana' , 27 , 60) , KnapsackItem.new('apple' , 39 , 40) ,
|
||||
KnapsackItem.new('cheese' , 23 , 30) , KnapsackItem.new('beer' , 52 , 10) ,
|
||||
KnapsackItem.new('suntan cream' , 11 , 70) , KnapsackItem.new('camera' , 32 , 30) ,
|
||||
KnapsackItem.new('t-shirt' , 24 , 15) , KnapsackItem.new('trousers' , 48 , 10) ,
|
||||
KnapsackItem.new('umbrella' , 73 , 40) , KnapsackItem.new('waterproof trousers' , 42 , 70) ,
|
||||
KnapsackItem.new('waterproof overclothes' , 43 , 75) , KnapsackItem.new('note-case' , 22 , 80) ,
|
||||
KnapsackItem.new('sunglasses' , 7 , 20) , KnapsackItem.new('towel' , 18 , 12) ,
|
||||
KnapsackItem.new('socks' , 4 , 50) , KnapsackItem.new('book' , 30 , 10)
|
||||
]
|
||||
|
||||
problem = KnapsackProblem.new(items, 400)
|
||||
|
||||
cost_matrix = dynamic_programming_knapsack problem
|
||||
puts
|
||||
puts 'Dynamic Programming:'
|
||||
puts
|
||||
puts 'Found solution: ' + get_list_of_used_items_names(problem, cost_matrix)
|
||||
puts 'With value: ' + cost_matrix.last.last.to_s
|
||||
end
|
||||
92
Task/Knapsack-problem-0-1/Scala/knapsack-problem-0-1.scala
Normal file
92
Task/Knapsack-problem-0-1/Scala/knapsack-problem-0-1.scala
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
object Knapsack extends App {
|
||||
|
||||
case class Item(name: String, weight: Int, value: Int)
|
||||
|
||||
val elapsed: (=> Unit) => Long = f => {val s = System.currentTimeMillis; f; (System.currentTimeMillis - s)/1000}
|
||||
|
||||
//===== brute force (caution: increase the heap!) ====================================
|
||||
val ks01b: List[Item] => Unit = loi => {
|
||||
val tw:Set[Item]=>Int=ps=>(ps:\0)((a,b)=>a.weight+b) //total weight
|
||||
val tv:Set[Item]=>Int=ps=>(ps:\0)((a,b)=>a.value+b) //total value
|
||||
val pis = (loi.toSet.subsets).toList.filterNot(_==Set())
|
||||
|
||||
val res = pis.map(ss=>Pair(ss,tw(ss)))
|
||||
.filter(p=>p._2>350 && p._2<401).map(p=>Pair(p,tv(p._1)))
|
||||
.sortWith((s,t)=>s._2.compareTo(t._2) < 0)
|
||||
.last
|
||||
println{val h = "packing list of items (brute force):"; h+"\n"+"="*h.size}
|
||||
res._1._1.foreach{p=>print(" "+p.name+": weight="+p.weight+" value="+p.value+"\n")}
|
||||
println("\n"+" resulting items: "+res._1._1.size+" of "+loi.size)
|
||||
println(" total weight: "+res._1._2+", total value: "+res._2)
|
||||
}
|
||||
|
||||
//===== dynamic programming ==========================================================
|
||||
val ks01d: List[Item] => Unit = loi => {
|
||||
val W = 400
|
||||
val N = loi.size
|
||||
|
||||
val m = Array.ofDim[Int](N+1,W+1)
|
||||
val plm = (List((for {w <- 0 to W} yield Set[Item]()).toArray)++(
|
||||
for {
|
||||
n <- 0 to N-1
|
||||
colN = (for {w <- 0 to W} yield Set[Item](loi(n))).toArray
|
||||
} yield colN)).toArray
|
||||
|
||||
1 to N foreach {n =>
|
||||
0 to W foreach {w =>
|
||||
def in = loi(n-1)
|
||||
def wn = loi(n-1).weight
|
||||
def vn = loi(n-1).value
|
||||
if (w<wn) {
|
||||
m(n)(w) = m(n-1)(w)
|
||||
plm(n)(w) = plm(n-1)(w)
|
||||
}
|
||||
else {
|
||||
if (m(n-1)(w)>=m(n-1)(w-wn)+vn) {
|
||||
m(n)(w) = m(n-1)(w)
|
||||
plm(n)(w) = plm(n-1)(w)
|
||||
}
|
||||
else {
|
||||
m(n)(w) = m(n-1)(w-wn)+vn
|
||||
plm(n)(w) = plm(n-1)(w-wn)+in
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println{val h = "packing list of items (dynamic programming):"; h+"\n"+"="*h.size}
|
||||
plm(N)(W).foreach{p=>print(" "+p.name+": weight="+p.weight+" value="+p.value+"\n")}
|
||||
println("\n"+" resulting items: "+plm(N)(W).size+" of "+loi.size)
|
||||
println(" total weight: "+(0/:plm(N)(W).map{item=>item.weight})(_+_)+", total value: "+m(N)(W))
|
||||
}
|
||||
|
||||
val items = List(
|
||||
Item("map", 9, 150)
|
||||
,Item("compass", 13, 35)
|
||||
,Item("water", 153, 200)
|
||||
,Item("sandwich", 50, 160)
|
||||
,Item("glucose", 15, 60)
|
||||
,Item("tin", 68, 45)
|
||||
,Item("banana", 27, 60)
|
||||
,Item("apple", 39, 40)
|
||||
,Item("cheese", 23, 30)
|
||||
,Item("beer", 52, 10)
|
||||
,Item("suntan cream", 11, 70)
|
||||
,Item("camera", 32, 30)
|
||||
,Item("t-shirt", 24, 15)
|
||||
,Item("trousers", 48, 10)
|
||||
,Item("umbrella", 73, 40)
|
||||
,Item("waterproof trousers", 42, 70)
|
||||
,Item("waterproof overclothes", 43, 75)
|
||||
,Item("note-case", 22, 80)
|
||||
,Item("sunglasses", 7, 20)
|
||||
,Item("towel", 18, 12)
|
||||
,Item("socks", 4, 50)
|
||||
,Item("book", 30, 10)
|
||||
)
|
||||
|
||||
List(ks01b, ks01d).foreach{f=>
|
||||
val t = elapsed{f(items)}
|
||||
println(" elapsed time: "+t+" sec"+"\n")
|
||||
}
|
||||
}
|
||||
75
Task/Knapsack-problem-0-1/Tcl/knapsack-problem-0-1.tcl
Normal file
75
Task/Knapsack-problem-0-1/Tcl/knapsack-problem-0-1.tcl
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# 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}
|
||||
}
|
||||
|
||||
# Simple extraction functions
|
||||
proc names {chosen} {
|
||||
set names {}
|
||||
foreach item $chosen {lappend names [lindex $item 0]}
|
||||
return $names
|
||||
}
|
||||
proc weight {chosen} {
|
||||
set weight 0
|
||||
foreach item $chosen {incr weight [lindex $item 1]}
|
||||
return $weight
|
||||
}
|
||||
proc value {chosen} {
|
||||
set value 0
|
||||
foreach item $chosen {incr value [lindex $item 2]}
|
||||
return $value
|
||||
}
|
||||
|
||||
# Recursive function for searching over all possible choices of items
|
||||
proc knapsackSearch {items {chosen {}}} {
|
||||
# If we've gone over the weight limit, stop now
|
||||
if {[weight $chosen] > 400} {
|
||||
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
|
||||
}
|
||||
# Branch, so recurse for chosing the current item or not
|
||||
set this [lindex $items 0]
|
||||
set rest [lrange $items 1 end]
|
||||
knapsackSearch $rest $chosen
|
||||
knapsackSearch $rest [lappend chosen $this]
|
||||
}
|
||||
|
||||
# Initialize a few global variables
|
||||
set best {}
|
||||
set max 0
|
||||
# Do the brute-force search
|
||||
knapsackSearch $items
|
||||
# Pretty-print the results
|
||||
puts "Best filling has weight of [expr {[weight $best]/100.0}]kg and score [value $best]"
|
||||
puts "Best items:\n\t[join [lsort [names $best]] \n\t]"
|
||||
Loading…
Add table
Add a link
Reference in a new issue