Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
6
Task/Knapsack-problem-0-1/00-META.yaml
Normal file
6
Task/Knapsack-problem-0-1/00-META.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
category:
|
||||
- Memoization
|
||||
- Puzzles
|
||||
from: http://rosettacode.org/wiki/Knapsack_problem/0-1
|
||||
note: Classic CS problems and programs
|
||||
85
Task/Knapsack-problem-0-1/00-TASK.txt
Normal file
85
Task/Knapsack-problem-0-1/00-TASK.txt
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
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: 40%;" 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 || ?
|
||||
|}
|
||||
|
||||
<br>
|
||||
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.
|
||||
|
||||
|
||||
;Task:
|
||||
Show which items the tourist can carry in his knapsack so that their total weight does not
|
||||
exceed 400 dag [4 kg], and their total value is maximized.
|
||||
|
||||
[dag = decagram = 10 grams]
|
||||
|
||||
|
||||
;Related tasks:
|
||||
* [[Knapsack problem/Bounded]]
|
||||
* [[Knapsack problem/Unbounded]]
|
||||
* [[Knapsack problem/Continuous]]
|
||||
* [[A* search algorithm]]
|
||||
<br><br>
|
||||
|
||||
42
Task/Knapsack-problem-0-1/11l/knapsack-problem-0-1.11l
Normal file
42
Task/Knapsack-problem-0-1/11l/knapsack-problem-0-1.11l
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
F totalvalue(comb)
|
||||
V totwt = 0
|
||||
V totval = 0
|
||||
L(item, wt, val) comb
|
||||
totwt += wt
|
||||
totval += val
|
||||
R I totwt <= 400 {(totval, -totwt)} E (0, 0)
|
||||
|
||||
V 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)
|
||||
]
|
||||
|
||||
F knapsack01_dp(items, limit)
|
||||
V table = [[0] * (limit + 1)] * (items.len + 1)
|
||||
|
||||
L(j) 1 .. items.len
|
||||
V (item, wt, val) = items[j - 1]
|
||||
L(w) 1 .. limit
|
||||
I wt > w
|
||||
table[j][w] = table[j - 1][w]
|
||||
E
|
||||
table[j][w] = max(table[j - 1][w], table[j - 1][w - wt] + val)
|
||||
|
||||
[(String, Int, Int)] result
|
||||
V w = limit
|
||||
L(j) (items.len .< 0).step(-1)
|
||||
I table[j][w] != table[j - 1][w]
|
||||
V (item, wt, val) = items[j - 1]
|
||||
result.append(items[j - 1])
|
||||
w -= wt
|
||||
R result
|
||||
|
||||
V bagged = knapsack01_dp(items, 400)
|
||||
print("Bagged the following items\n "sorted(bagged.map((item, _, _2) -> item)).join("\n "))
|
||||
V (val, wt) = totalvalue(bagged)
|
||||
print(‘for a total value of #. and a total weight of #.’.format(val, -wt))
|
||||
124
Task/Knapsack-problem-0-1/360-Assembly/knapsack-problem-0-1.360
Normal file
124
Task/Knapsack-problem-0-1/360-Assembly/knapsack-problem-0-1.360
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
* Knapsack problem/0-1 16/02/2017
|
||||
KNAPSA01 CSECT
|
||||
USING KNAPSA01,R13
|
||||
B 72(R15)
|
||||
DC 17F'0'
|
||||
STM R14,R12,12(R13)
|
||||
ST R13,4(R15)
|
||||
ST R15,8(R13)
|
||||
LR R13,R15 end of prolog
|
||||
L R0,N n
|
||||
LA R1,1
|
||||
POWER MH R1,=H'2' *2
|
||||
BCT R0,POWER
|
||||
BCTR R1,0 -1
|
||||
ST R1,IMAX imax=2**n-1
|
||||
SR R6,R6 i=0
|
||||
DO WHILE=(C,R6,LE,IMAX) do i=0 to imax
|
||||
SR R10,R10 im=0
|
||||
SR R8,R8 iw=0
|
||||
SR R9,R9 iv=0
|
||||
LA R7,1 j=1
|
||||
DO WHILE=(C,R7,LE,N) do j=1 to n
|
||||
LR R1,R6 i
|
||||
LR R2,R7 j
|
||||
BAL R14,TSTBIT call tstbit(i,j)
|
||||
IF C,R0,EQ,=F'1' THEN if tstbit(i,j)=1 then
|
||||
LA R10,1(R10) im=im+1
|
||||
LR R3,R7 j
|
||||
BCTR R3,0
|
||||
SLA R3,5
|
||||
LA R1,24(R3)
|
||||
A R8,DATA(R1) iw=iw+data(j).w
|
||||
LA R1,28(R3)
|
||||
A R9,DATA(R1) iv=iv+data(j).v
|
||||
ENDIF , endif
|
||||
LA R7,1(R7) j=j+1
|
||||
ENDDO , enddo j
|
||||
IF C,R8,LE,MAXW,AND,C,R9,GT,XV THEN if w<=maxw and iv>xv then
|
||||
ST R6,XB xb=i
|
||||
ST R10,XM xm=im
|
||||
ST R8,XW xw=iw
|
||||
ST R9,XV xv=iv
|
||||
ENDIF , endif
|
||||
LA R6,1(R6) i=i+1
|
||||
ENDDO , enddo i
|
||||
MVC PG(2),=C'n='
|
||||
L R1,N n
|
||||
XDECO R1,XDEC edit n
|
||||
MVC PG+2(2),XDEC+10
|
||||
XPRNT PG,L'PG print buffer
|
||||
LA R6,1
|
||||
DO WHILE=(C,R6,LE,N) do i=1 to n
|
||||
L R1,XB xb
|
||||
LR R2,R6 i
|
||||
BAL R14,TSTBIT call tstbit(xb,i)
|
||||
IF C,R0,EQ,=F'1' THEN if tstbit(xb,i)=1 then
|
||||
LR R1,R6 i
|
||||
BCTR R1,0
|
||||
SLA R1,5
|
||||
LA R2,DATA(R1) @data(i).n
|
||||
MVC PG(24),0(R2)
|
||||
XPRNT PG,24 print item
|
||||
ENDIF , endif
|
||||
LA R6,1(R6) i=i+1
|
||||
ENDDO , enddo i
|
||||
L R1,XM xm
|
||||
XDECO R1,XDEC edit xm
|
||||
MVC PGT+6(2),XDEC+10
|
||||
L R1,XW xw
|
||||
XDECO R1,XDEC edit xw
|
||||
MVC PGT+16(3),XDEC+9
|
||||
L R1,XV xv
|
||||
XDECO R1,XDEC edit xv
|
||||
MVC PGT+26(4),XDEC+8
|
||||
XPRNT PGT,L'PGT print buffer
|
||||
L R13,4(0,R13) epilog
|
||||
LM R14,R12,12(R13)
|
||||
XR R15,R15
|
||||
BR R14 exit
|
||||
TSTBIT EQU * R1 value to test the R2 bit
|
||||
LA R3,32 32
|
||||
SR R3,R2 (32-i)
|
||||
STC R3,XSLL+3
|
||||
LR R0,R1 n
|
||||
EX 0,XSLL SLL R0,(32-i)
|
||||
SRL R0,31
|
||||
BR R14 return R0
|
||||
XSLL SLL R0,0 shift left logical
|
||||
*
|
||||
MAXW DC F'400' maximum weight
|
||||
N DC A((DATAE-DATA)/32)
|
||||
IMAX DS F number of combinations
|
||||
XB DS F max vector
|
||||
XM DS F max items
|
||||
XW DS F max weight
|
||||
XV DS F max value
|
||||
PG DC CL80' '
|
||||
PGT DC CL32'items=.. weight=... value=....'
|
||||
XDEC DS CL12
|
||||
DATA DC CL24'map',F'9',F'150'
|
||||
DC CL24'compass',F'13',F'35'
|
||||
DC CL24'water',F'153',F'200'
|
||||
DC CL24'sandwich',F'50',F'160'
|
||||
DC CL24'glucose',F'15',F'60'
|
||||
DC CL24'tin',F'68',F'45'
|
||||
DC CL24'banana',F'27',F'60'
|
||||
DC CL24'apple',F'39',F'40'
|
||||
DC CL24'cheese',F'23',F'30'
|
||||
DC CL24'beer',F'52',F'10'
|
||||
DC CL24'suntan cream',F'11',F'70'
|
||||
DC CL24'camera',F'32',F'30'
|
||||
DC CL24'T-shirt',F'24',F'15'
|
||||
DC CL24'trousers',F'48',F'10'
|
||||
DC CL24'umbrella',F'73',F'40'
|
||||
DC CL24'book',F'30',F'10'
|
||||
DC CL24'waterproof trousers',F'42',F'70'
|
||||
DC CL24'waterproof overclothes',F'43',F'75'
|
||||
DC CL24'note-case',F'22',F'80'
|
||||
DC CL24'sunglasses',F'7',F'20'
|
||||
DC CL24'towel',F'18',F'12'
|
||||
DC CL24'socks',F'4',F'50'
|
||||
DATAE DC 0C
|
||||
YREGS
|
||||
END KNAPSA01
|
||||
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)
|
||||
∇
|
||||
43
Task/Knapsack-problem-0-1/AWK/knapsack-problem-0-1.awk
Normal file
43
Task/Knapsack-problem-0-1/AWK/knapsack-problem-0-1.awk
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# syntax: GAWK -f KNAPSACK_PROBLEM_0-1.AWK
|
||||
BEGIN {
|
||||
# arr["item,weight"] = value
|
||||
arr["map,9"] = 150
|
||||
arr["compass,13"] = 35
|
||||
arr["water,153"] = 200
|
||||
arr["sandwich,50"] = 160
|
||||
arr["glucose,15"] = 60
|
||||
arr["tin,68"] = 45
|
||||
arr["banana,27"] = 60
|
||||
arr["apple,39"] = 40
|
||||
arr["cheese,23"] = 30
|
||||
arr["beer,52"] = 10
|
||||
arr["suntan cream,11"] = 70
|
||||
arr["camera,32"] = 30
|
||||
arr["T-shirt,24"] = 15
|
||||
arr["trousers,48"] = 10
|
||||
arr["umbrella,73"] = 40
|
||||
arr["waterproof trousers,42"] = 70
|
||||
arr["waterproof overclothes,43"] = 75
|
||||
arr["note-case,22"] = 80
|
||||
arr["sunglasses,7"] = 20
|
||||
arr["towel,18"] = 12
|
||||
arr["socks,4"] = 50
|
||||
arr["book,30"] = 10
|
||||
sack_size = 400 # dag
|
||||
PROCINFO["sorted_in"] = "@val_num_desc"
|
||||
for (i in arr) {
|
||||
if (total_weight >= sack_size) {
|
||||
break
|
||||
}
|
||||
split(i,tmp,",")
|
||||
weight = tmp[2]
|
||||
if (total_weight + weight <= sack_size) {
|
||||
printf("%s\n",tmp[1])
|
||||
total_items++
|
||||
total_value += arr[i]
|
||||
total_weight += weight
|
||||
}
|
||||
}
|
||||
printf("items=%d (out of %d) weight=%d value=%d\n",total_items,length(arr),total_weight,total_value)
|
||||
exit(0)
|
||||
}
|
||||
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;
|
||||
|
|
@ -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 @@
|
|||
:: Initiate command line environment
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
:: Establish arrays we'll be using
|
||||
set items=map compass water sandwich glucose tin banana apple cheese beer suntancream camera tshirt trousers umbrella waterprooftrousers waterproofoverclothes notecase sunglasses towel socks book
|
||||
set weight=9 13 153 50 15 68 27 39 23 52 11 32 24 48 73 42 43 22 7 18 4 30
|
||||
set importance=150 35 200 160 60 45 60 40 30 10 70 30 15 10 40 70 75 80 20 12 50 10
|
||||
|
||||
:: Put the above 3 arrays into their own variables with the form of "item[]", "w[]" and "i[]"
|
||||
set tempnum=0
|
||||
for %%i in (%items%) do (
|
||||
set /a tempnum+=1
|
||||
set item!tempnum!=%%i
|
||||
)
|
||||
set tempnum=0
|
||||
for %%i in (%weight%) do (
|
||||
set /a tempnum+=1
|
||||
set w!tempnum!=%%i
|
||||
)
|
||||
set tempnum=0
|
||||
for %%i in (%importance%) do (
|
||||
set /a tempnum+=1
|
||||
set i!tempnum!=%%i
|
||||
)
|
||||
:: Define the array "r[]" as the ratio between the importance ("i[]") and the weight ("w[]").
|
||||
for /l %%i in (1,1,22) do set /a r%%i=!i%%i!*100/!w%%i! & rem batch doesn't support decimals, so the numerator is multiplied by 100 to get past this
|
||||
|
||||
set totalimportance=0
|
||||
set totalweight=0
|
||||
set amount=0
|
||||
|
||||
:: Find the largest number in "r[]" and define some temp variables based off it
|
||||
:load
|
||||
set tempr=0
|
||||
set tempitem=0
|
||||
for /l %%i in (1,1,22) do (
|
||||
if !r%%i! gtr !tempr! (
|
||||
set tempr=!r%%i!
|
||||
set tempitem=%%i
|
||||
set /a testweight=%totalweight%+!w%%i!
|
||||
if !tempr!==0 goto end
|
||||
if !testweight! geq 400 goto end
|
||||
)
|
||||
)
|
||||
|
||||
:: Do basic error checking using the temp variables from above and either output and end the program or send back to load
|
||||
set /a totaltempweight=%totalweight%+!w%tempitem%!
|
||||
|
||||
if %totaltempweight% gtr 400 (
|
||||
set !r%tempitem%!=0
|
||||
goto load
|
||||
)
|
||||
|
||||
set totalweight=%totaltempweight%
|
||||
set /a totalimportance+=!i%tempitem%!
|
||||
set taken=%taken% !item%tempitem%!
|
||||
set /a amount+=1
|
||||
set r%tempitem%=0 & rem set the ratio variable of the item we just added to the knapsack as 0 to stop it repeat
|
||||
|
||||
goto load
|
||||
|
||||
:end
|
||||
echo List of things taken [%amount%]: %taken%
|
||||
echo Total Value: %totalimportance% Total Weight: %totalweight%
|
||||
pause>nul
|
||||
|
|
@ -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-1.cpp
Normal file
98
Task/Knapsack-problem-0-1/C++/knapsack-problem-0-1-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 ] ;
|
||||
}
|
||||
76
Task/Knapsack-problem-0-1/C++/knapsack-problem-0-1-2.cpp
Normal file
76
Task/Knapsack-problem-0-1/C++/knapsack-problem-0-1-2.cpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
std::tuple<std::set<int>, int> findBestPack(const std::vector<std::tuple<std::string, int, int> > &items, const int weightlimit) {
|
||||
const auto n = items.size();
|
||||
int bestValues[n][weightlimit] = { 0 };
|
||||
std::set<int> solutionSets[n][weightlimit];
|
||||
std::set<int> bestItems;
|
||||
for (auto i = 0u; i < n; i++)
|
||||
for (auto weight = 0; weight < weightlimit; weight++) {
|
||||
if (i == 0)
|
||||
bestValues[i][weight] = 0;
|
||||
else {
|
||||
auto [_, itemweight, value] = *(items.begin() + i);
|
||||
if (weight < itemweight) {
|
||||
bestValues[i][weight] = bestValues[i - 1][weight];
|
||||
solutionSets[i][weight] = solutionSets[i - 1][weight];
|
||||
} else {
|
||||
if (bestValues[i - 1][weight - itemweight] + value > bestValues[i - 1][weight]) {
|
||||
bestValues[i][weight] = bestValues[i - 1][weight - itemweight] + value;
|
||||
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 { bestItems, bestValues[n - 1][weightlimit - 1] };
|
||||
}
|
||||
|
||||
int main() {
|
||||
const std::vector<std::tuple<std::string, int, int>> items = {
|
||||
{ "", 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 creme", 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 } };
|
||||
|
||||
const int maximumWeight = 400;
|
||||
const auto &[bestItems, bestValue] = findBestPack(items, maximumWeight);
|
||||
int totalweight = 0;
|
||||
std::cout << std::setw(24) << "best knapsack:" << std::endl;
|
||||
for (auto si = bestItems.begin(); si != bestItems.end(); si++) {
|
||||
auto [name, weight, value] = *(items.begin() + *si);
|
||||
std::cout << std::setw(24) << name << std::setw(6) << weight << std::setw(6) << value << std::endl;
|
||||
totalweight += weight;
|
||||
}
|
||||
std::cout << std::endl << std::setw(24) << "total:" << std::setw(6) << totalweight << std::setw(6) << bestValue << std::endl;
|
||||
return 0;
|
||||
}
|
||||
51
Task/Knapsack-problem-0-1/C-sharp/knapsack-problem-0-1-1.cs
Normal file
51
Task/Knapsack-problem-0-1/C-sharp/knapsack-problem-0-1-1.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using System; // 4790@3.6
|
||||
using System.Threading.Tasks;
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
Console.Write(knapSack(400) + "\n" + sw.Elapsed); // 60 ms
|
||||
Console.Read();
|
||||
}
|
||||
|
||||
static string knapSack(uint w1)
|
||||
{
|
||||
uint sol = 0, v1 = 0;
|
||||
Parallel.For(1, 9, t =>
|
||||
{
|
||||
uint j, wi, k, vi, i1 = 1u << w.Length;
|
||||
for (uint i = (uint)t; i < i1; i += 8)
|
||||
{
|
||||
k = wi = vi = 0;
|
||||
for (j = i; j > 0; j >>= 1, k++)
|
||||
if ((j & 1) > 0)
|
||||
{
|
||||
if ((wi += w[k]) > w1) break;
|
||||
vi += v[k];
|
||||
}
|
||||
if (wi <= w1 && v1 < vi)
|
||||
lock (locker)
|
||||
if (v1 < vi) { v1 = vi; sol = i; }
|
||||
}
|
||||
});
|
||||
string str = "";
|
||||
for (uint k = 0; sol > 0; sol >>= 1, k++)
|
||||
if ((sol & 1) > 0) str += items[k] + "\n";
|
||||
return str;
|
||||
}
|
||||
|
||||
static readonly object locker = new object();
|
||||
|
||||
static byte[] w = { 9, 13, 153, 50, 15, 68, 27, 39, 23, 52, 11,
|
||||
32, 24, 48, 73, 42, 43, 22, 7, 18, 4, 30 },
|
||||
|
||||
v = { 150, 35, 200, 160, 60, 45, 60, 40, 30, 10, 70,
|
||||
30, 15, 10, 40, 70, 75, 80, 20, 12, 50, 10 };
|
||||
|
||||
static string[] items = {"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"};
|
||||
}
|
||||
44
Task/Knapsack-problem-0-1/C-sharp/knapsack-problem-0-1-2.cs
Normal file
44
Task/Knapsack-problem-0-1/C-sharp/knapsack-problem-0-1-2.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using System
|
||||
class program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
knapSack(40);
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
Console.Write(knapSack(400) + "\n" + sw.Elapsed); // 31 µs
|
||||
Console.Read();
|
||||
}
|
||||
|
||||
static string knapSack(uint w1)
|
||||
{
|
||||
uint n = (uint)w.Length; var K = new uint[n + 1, w1 + 1];
|
||||
for (uint vi, wi, w0, x, i = 0; i < n; i++)
|
||||
for (vi = v[i], wi = w[i], w0 = 1; w0 <= w1; w0++)
|
||||
{
|
||||
x = K[i, w0];
|
||||
if (wi <= w0) x = max(vi + K[i, w0 - wi], x);
|
||||
K[i + 1, w0] = x;
|
||||
}
|
||||
string str = "";
|
||||
for (uint v1 = K[n, w1]; v1 > 0; n--)
|
||||
if (v1 != K[n - 1, w1])
|
||||
{
|
||||
v1 -= v[n - 1]; w1 -= w[n - 1]; str += items[n - 1] + "\n";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static uint max(uint a, uint b) { return a > b ? a : b; }
|
||||
|
||||
static byte[] w = { 9, 13, 153, 50, 15, 68, 27, 39, 23, 52, 11,
|
||||
32, 24, 48, 73, 42, 43, 22, 7, 18, 4, 30 },
|
||||
|
||||
v = { 150, 35, 200, 160, 60, 45, 60, 40, 30, 10, 70,
|
||||
30, 15, 10, 40, 70, 75, 80, 20, 12, 50, 10 };
|
||||
|
||||
static string[] items = {"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"};
|
||||
}
|
||||
78
Task/Knapsack-problem-0-1/C/knapsack-problem-0-1.c
Normal file
78
Task/Knapsack-problem-0-1/C/knapsack-problem-0-1.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int weight;
|
||||
int value;
|
||||
} item_t;
|
||||
|
||||
item_t 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},
|
||||
};
|
||||
|
||||
int *knapsack (item_t *items, int n, int w) {
|
||||
int i, j, a, b, *mm, **m, *s;
|
||||
mm = calloc((n + 1) * (w + 1), sizeof (int));
|
||||
m = malloc((n + 1) * sizeof (int *));
|
||||
m[0] = mm;
|
||||
for (i = 1; i <= n; i++) {
|
||||
m[i] = &mm[i * (w + 1)];
|
||||
for (j = 0; j <= w; j++) {
|
||||
if (items[i - 1].weight > j) {
|
||||
m[i][j] = m[i - 1][j];
|
||||
}
|
||||
else {
|
||||
a = m[i - 1][j];
|
||||
b = m[i - 1][j - items[i - 1].weight] + items[i - 1].value;
|
||||
m[i][j] = a > b ? a : b;
|
||||
}
|
||||
}
|
||||
}
|
||||
s = calloc(n, sizeof (int));
|
||||
for (i = n, j = w; i > 0; i--) {
|
||||
if (m[i][j] > m[i - 1][j]) {
|
||||
s[i - 1] = 1;
|
||||
j -= items[i - 1].weight;
|
||||
}
|
||||
}
|
||||
free(mm);
|
||||
free(m);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main () {
|
||||
int i, n, tw = 0, tv = 0, *s;
|
||||
n = sizeof (items) / sizeof (item_t);
|
||||
s = knapsack(items, n, 400);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (s[i]) {
|
||||
printf("%-22s %5d %5d\n", items[i].name, items[i].weight, items[i].value);
|
||||
tw += items[i].weight;
|
||||
tv += items[i].value;
|
||||
}
|
||||
}
|
||||
printf("%-22s %5d %5d\n", "totals:", tw, tv);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
module knapsack "1.0.0" {
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
shared void run() {
|
||||
value knapsack = pack(items, empty(400));
|
||||
|
||||
print(knapsack);
|
||||
}
|
||||
|
||||
class Item(name,weight,theValue) {
|
||||
String name;
|
||||
shared Integer weight;
|
||||
shared Float theValue;
|
||||
|
||||
shared actual String string = "item(``name``, ``weight``, ``theValue``)";
|
||||
}
|
||||
|
||||
class Knapsack(items,theValue,weight,available) {
|
||||
shared Item[] items;
|
||||
shared Float theValue;
|
||||
shared Integer weight;
|
||||
shared Integer available;
|
||||
|
||||
shared Boolean canAccept(Item item)
|
||||
=> item.weight <= available;
|
||||
|
||||
String itemsString = items.fold("")((total, remaining) => "``total``\t\n``remaining.string``" );
|
||||
|
||||
shared actual String string = "Total value: ``theValue``\nTotal weight: ``weight``\nItems:\n``itemsString``";
|
||||
}
|
||||
|
||||
Knapsack empty(Integer capacity)
|
||||
=> Knapsack([], 0.0, 0, capacity);
|
||||
|
||||
|
||||
Item[] items =
|
||||
[
|
||||
Item("map", 9, 150.0),
|
||||
Item("compass", 13, 35.0),
|
||||
Item("water", 153, 200.0),
|
||||
Item("sandwich", 50, 160.0),
|
||||
Item("glucose", 15, 60.0),
|
||||
Item("tin", 68, 45.0),
|
||||
Item("banana", 27, 60.0),
|
||||
Item("apple", 39, 40.0),
|
||||
Item("cheese", 23, 30.0),
|
||||
Item("beer", 52, 10.0),
|
||||
Item("cream", 11, 70.0),
|
||||
Item("camera", 32, 30.0),
|
||||
Item("tshirt", 24, 15.0),
|
||||
Item("trousers", 48, 10.0),
|
||||
Item("umbrella", 73, 40.0),
|
||||
Item("trousers", 42, 70.0),
|
||||
Item("overclothes", 43, 75.0),
|
||||
Item("notecase", 22, 80.0),
|
||||
Item("sunglasses", 7, 20.0),
|
||||
Item("towel", 18, 12.0),
|
||||
Item("socks", 4, 50.0),
|
||||
Item("book", 30, 10.0)
|
||||
];
|
||||
|
||||
|
||||
Knapsack add(Item item, Knapsack knapsack)
|
||||
=> Knapsack { items = knapsack.items.withTrailing(item);
|
||||
theValue = knapsack.theValue + item.theValue;
|
||||
weight = knapsack.weight + item.weight;
|
||||
available = knapsack.available - item.weight; };
|
||||
|
||||
Float rating(Item item) => item.theValue / item.weight.float;
|
||||
|
||||
Knapsack pack(Item[] items, Knapsack knapsack)
|
||||
// Sort the items by decreasing rating, that is, value divided by weight
|
||||
=> let (itemsSorted =
|
||||
items.group(rating)
|
||||
.sort(byDecreasing((Float->[Item+] entry) => entry.key))
|
||||
.map(Entry.item)
|
||||
.flatMap((element) => element)
|
||||
.sequence())
|
||||
|
||||
packRecursive(itemsSorted,knapsack);
|
||||
|
||||
Knapsack packRecursive(Item[] sortedItems, Knapsack knapsack)
|
||||
=> if (exists firstItem=sortedItems.first, knapsack.canAccept(firstItem))
|
||||
then packRecursive(sortedItems.rest, add(firstItem,knapsack))
|
||||
else knapsack;
|
||||
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))))
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
require "bit_array"
|
||||
|
||||
struct BitArray
|
||||
def clone
|
||||
BitArray.new(size).tap { |new| new.to_slice.copy_from (to_slice) }
|
||||
end
|
||||
end
|
||||
|
||||
record Item, name : String, weight : Int32, value : Int32
|
||||
|
||||
record Selection, mask : BitArray, cur_index : Int32, total_value : Int32
|
||||
|
||||
class Knapsack
|
||||
@threshold_value = 0
|
||||
@threshold_choice : Selection?
|
||||
getter checked_nodes = 0
|
||||
|
||||
def knapsack_step(taken, items, remaining_weight)
|
||||
if taken.total_value > @threshold_value
|
||||
@threshold_value = taken.total_value
|
||||
@threshold_choice = taken
|
||||
end
|
||||
candidate_index = items.index(taken.cur_index) { |item| item.weight <= remaining_weight }
|
||||
return nil unless candidate_index
|
||||
@checked_nodes += 1
|
||||
candidate = items[candidate_index]
|
||||
# candidate is a best of available items, so if we fill remaining value with it
|
||||
# and still don't reach the threshold, the branch is wrong
|
||||
return nil if taken.total_value + 1.0 * candidate.value / candidate.weight * remaining_weight < @threshold_value
|
||||
# now recursively check both variants
|
||||
mask = taken.mask.clone
|
||||
mask[candidate_index] = true
|
||||
knapsack_step Selection.new(mask, candidate_index + 1, taken.total_value + candidate.value), items, remaining_weight - candidate.weight
|
||||
mask = taken.mask.clone
|
||||
mask[candidate_index] = false
|
||||
knapsack_step Selection.new(mask, candidate_index + 1, taken.total_value), items, remaining_weight
|
||||
end
|
||||
|
||||
def select(items, max_weight)
|
||||
@checked_variants = 0
|
||||
# sort by descending relative value
|
||||
list = items.sort_by { |item| -1.0 * item.value / item.weight }
|
||||
# use heuristic of relative value as an initial estimate for branch&bounds
|
||||
w = max_weight
|
||||
heur_list = list.take_while { |item| w -= item.weight; w > 0 }
|
||||
nothing = Selection.new(BitArray.new(items.size), 0, 0)
|
||||
@threshold_value = heur_list.sum(&.value) - 1
|
||||
@threshold_choice = nothing
|
||||
knapsack_step(nothing, list, max_weight)
|
||||
selected = @threshold_choice.not_nil!
|
||||
result = [] of Item
|
||||
selected.mask.each_with_index { |v, i| result << list[i] if v }
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
possible = [
|
||||
Item.new("map", 9, 150),
|
||||
Item.new("compass", 13, 35),
|
||||
Item.new("water", 153, 200),
|
||||
Item.new("sandwich", 50, 160),
|
||||
Item.new("glucose", 15, 60),
|
||||
Item.new("tin", 68, 45),
|
||||
Item.new("banana", 27, 60),
|
||||
Item.new("apple", 39, 40),
|
||||
Item.new("cheese", 23, 30),
|
||||
Item.new("beer", 52, 10),
|
||||
Item.new("suntan cream", 11, 70),
|
||||
Item.new("camera", 32, 30),
|
||||
Item.new("T-shirt", 24, 15),
|
||||
Item.new("trousers", 48, 10),
|
||||
Item.new("umbrella", 73, 40),
|
||||
Item.new("waterproof trousers", 42, 70),
|
||||
Item.new("waterproof overclothes", 43, 75),
|
||||
Item.new("note-case", 22, 80),
|
||||
Item.new("sunglasses", 7, 20),
|
||||
Item.new("towel", 18, 12),
|
||||
Item.new("socks", 4, 50),
|
||||
Item.new("book", 30, 10),
|
||||
]
|
||||
|
||||
solver = Knapsack.new
|
||||
used = solver.select(possible, 400)
|
||||
puts "optimal choice: #{used.map(&.name)}"
|
||||
puts "total weight #{used.sum(&.weight)}, total value #{used.sum(&.value)}"
|
||||
puts "checked nodes: #{solver.checked_nodes}"
|
||||
45
Task/Knapsack-problem-0-1/D/knapsack-problem-0-1-1.d
Normal file
45
Task/Knapsack-problem-0-1/D/knapsack-problem-0-1-1.d
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import std.stdio, std.algorithm, std.typecons, std.array, std.range;
|
||||
|
||||
struct Item { string name; int weight, value; }
|
||||
|
||||
Item[] knapsack01DinamicProgramming(immutable Item[] items, in int limit)
|
||||
pure nothrow @safe {
|
||||
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);
|
||||
|
||||
typeof(return) 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() @safe {
|
||||
enum int limit = 400;
|
||||
immutable Item[] items = [
|
||||
{"apple", 39, 40}, {"banana", 27, 60},
|
||||
{"beer", 52, 10}, {"book", 30, 10},
|
||||
{"camera", 32, 30}, {"cheese", 23, 30},
|
||||
{"compass", 13, 35}, {"glucose", 15, 60},
|
||||
{"map", 9, 150}, {"note-case", 22, 80},
|
||||
{"sandwich", 50, 160}, {"socks", 4, 50},
|
||||
{"sunglasses", 7, 20}, {"suntan cream", 11, 70},
|
||||
{"t-shirt", 24, 15}, {"tin", 68, 45},
|
||||
{"towel", 18, 12}, {"trousers", 48, 10},
|
||||
{"umbrella", 73, 40}, {"water", 153, 200},
|
||||
{"waterproof overclothes", 43, 75},
|
||||
{"waterproof trousers", 42, 70}];
|
||||
|
||||
immutable bag = knapsack01DinamicProgramming(items, limit);
|
||||
writefln("Items:\n%-( %s\n%)", bag.map!q{ a.name }.retro);
|
||||
const t = reduce!q{ a[] += [b.weight, b.value] }([0, 0], bag);
|
||||
writeln("\nTotal weight and value: ", t[0] <= limit ? t : [0, 0]);
|
||||
}
|
||||
56
Task/Knapsack-problem-0-1/D/knapsack-problem-0-1-2.d
Normal file
56
Task/Knapsack-problem-0-1/D/knapsack-problem-0-1-2.d
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
struct Item { string name; int weight, value; }
|
||||
|
||||
immutable Item[] items = [
|
||||
{"apple", 39, 40}, {"banana", 27, 60},
|
||||
{"beer", 52, 10}, {"book", 30, 10},
|
||||
{"camera", 32, 30}, {"cheese", 23, 30},
|
||||
{"compass", 13, 35}, {"glucose", 15, 60},
|
||||
{"map", 9, 150}, {"note-case", 22, 80},
|
||||
{"sandwich", 50, 160}, {"socks", 4, 50},
|
||||
{"sunglasses", 7, 20}, {"suntan cream", 11, 70},
|
||||
{"t-shirt", 24, 15}, {"tin", 68, 45},
|
||||
{"towel", 18, 12}, {"trousers", 48, 10},
|
||||
{"umbrella", 73, 40}, {"water", 153, 200},
|
||||
{"waterproof overclothes", 43, 75},
|
||||
{"waterproof trousers", 42, 70}];
|
||||
|
||||
struct Solution { uint bits; int value; }
|
||||
static assert(items.length <= Solution.bits.sizeof * 8);
|
||||
|
||||
void solve(in int weight, in int idx, ref Solution s)
|
||||
pure nothrow @nogc @safe {
|
||||
if (idx < 0) {
|
||||
s.bits = s.value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (weight < items[idx].weight) {
|
||||
solve(weight, idx - 1, s);
|
||||
return;
|
||||
}
|
||||
|
||||
Solution v1, v2;
|
||||
solve(weight, idx - 1, v1);
|
||||
solve(weight - items[idx].weight, idx - 1, v2);
|
||||
|
||||
v2.value += items[idx].value;
|
||||
v2.bits |= (1 << idx);
|
||||
|
||||
s = (v1.value >= v2.value) ? v1 : v2;
|
||||
}
|
||||
|
||||
void main() @safe {
|
||||
import std.stdio;
|
||||
|
||||
auto s = Solution(0, 0);
|
||||
solve(400, items.length - 1, s);
|
||||
|
||||
writeln("Items:");
|
||||
int w = 0;
|
||||
foreach (immutable i, immutable it; items)
|
||||
if (s.bits & (1 << i)) {
|
||||
writeln(" ", it.name);
|
||||
w += it.weight;
|
||||
}
|
||||
writefln("\nTotal value: %d; weight: %d", s.value, w);
|
||||
}
|
||||
22
Task/Knapsack-problem-0-1/D/knapsack-problem-0-1-3.d
Normal file
22
Task/Knapsack-problem-0-1/D/knapsack-problem-0-1-3.d
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import std.stdio, std.algorithm, std.typecons, std.array, std.range;
|
||||
|
||||
struct Item { string name; int w, v; }
|
||||
alias Pair = Tuple!(int,"tot", string[],"names");
|
||||
|
||||
immutable Item[] items = [{"apple",39,40}, {"banana", 27, 60},
|
||||
{"beer", 52, 10}, {"book", 30, 10}, {"camera", 32, 30},
|
||||
{"cheese", 23, 30}, {"compass", 13, 35}, {"glucose", 15, 60},
|
||||
{"map", 9, 150}, {"note-case", 22, 80}, {"sandwich", 50, 160},
|
||||
{"socks", 4, 50}, {"sunglasses", 7, 20}, {"suntan cream", 11, 70},
|
||||
{"t-shirt", 24, 15}, {"tin", 68, 45}, {"towel", 18, 12},
|
||||
{"trousers", 48, 10}, {"umbrella", 73, 40}, {"water", 153, 200},
|
||||
{"overclothes", 43, 75}, {"waterproof trousers", 42, 70}];
|
||||
|
||||
auto addItem(Pair[] lst, in Item it) pure /*nothrow*/ {
|
||||
auto aux = lst.map!(vn => Pair(vn.tot + it.v, vn.names ~ it.name));
|
||||
return lst[0..it.w] ~ lst[it.w..$].zip(aux).map!q{ a[].max }.array;
|
||||
}
|
||||
|
||||
void main() {
|
||||
reduce!addItem(Pair().repeat.take(400).array, items).back.writeln;
|
||||
}
|
||||
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");
|
||||
|
||||
}
|
||||
137
Task/Knapsack-problem-0-1/Delphi/knapsack-problem-0-1.delphi
Normal file
137
Task/Knapsack-problem-0-1/Delphi/knapsack-problem-0-1.delphi
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
{Item to store data in}
|
||||
|
||||
type TPackItem = record
|
||||
Name: string;
|
||||
Weight,Value: integer;
|
||||
end;
|
||||
|
||||
{List of items, weights and values}
|
||||
|
||||
const ItemsList: array [0..21] of TPackItem = (
|
||||
(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));
|
||||
|
||||
{Iterater object to step through all the indices
|
||||
{ corresponding to the bits in "N". This is used }
|
||||
{ step through all the combinations of items }
|
||||
|
||||
type TBitIterator = class(TObject)
|
||||
private
|
||||
FNumber,FIndex: integer;
|
||||
public
|
||||
procedure Start(StartNumber: integer);
|
||||
function Next(var Index: integer): boolean;
|
||||
end;
|
||||
|
||||
procedure TBitIterator.Start(StartNumber: integer);
|
||||
{Set the starting value of the number }
|
||||
begin
|
||||
FNumber:=StartNumber;
|
||||
end;
|
||||
|
||||
|
||||
function TBitIterator.Next(var Index: integer): boolean;
|
||||
{Return the next available index}
|
||||
begin
|
||||
Result:=False;
|
||||
while FNumber>0 do
|
||||
begin
|
||||
Result:=(FNumber and 1)=1;
|
||||
if Result then Index:=FIndex;
|
||||
FNumber:=FNumber shr 1;
|
||||
Inc(FIndex);
|
||||
if Result then break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{=============================================================================}
|
||||
|
||||
|
||||
procedure GetSums(N: integer; var Weight,Value: integer);
|
||||
{Iterate through all indices corresponding to N}
|
||||
{Get get the sum of their values}
|
||||
var Inx: integer;
|
||||
var BI: TBitIterator;
|
||||
begin
|
||||
BI:=TBitIterator.Create;
|
||||
try
|
||||
BI.Start(N);
|
||||
Weight:=0; Value:=0;
|
||||
while BI.Next(Inx) do
|
||||
begin
|
||||
Weight:=Weight+ItemsList[Inx].Weight;
|
||||
Value:=Value+ItemsList[Inx].Value;
|
||||
end;
|
||||
finally BI.Free; end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure DoKnapsackProblem(Memo: TMemo);
|
||||
{Find optimized solution to Knapsack problem}
|
||||
{By iterating through all binary combinations}
|
||||
var I,J,Inx: integer;
|
||||
var Max: integer;
|
||||
var WeightSum,ValueSum: integer;
|
||||
var BestValue,BestIndex,BestWeight: integer;
|
||||
var S: string;
|
||||
var BI: TBitIterator;
|
||||
begin
|
||||
BI:=TBitIterator.Create;
|
||||
try
|
||||
{Get value that will cover all binary combinations}
|
||||
Max:=1 shl Length(ItemsList)-1;
|
||||
BestValue:=0;
|
||||
{Iterate through all combinations of bits}
|
||||
for I:=1 to Max do
|
||||
begin
|
||||
{Get the sum of the weights and values}
|
||||
GetSums(I,WeightSum,ValueSum);
|
||||
{Ignore any weight greater than 400}
|
||||
if WeightSum>400 then continue;
|
||||
{Test if this is the best value so far}
|
||||
if ValueSum>BestValue then
|
||||
begin
|
||||
BestValue:=ValueSum;
|
||||
BestWeight:=WeightSum;
|
||||
BestIndex:=I;
|
||||
end;
|
||||
end;
|
||||
{Display the best result}
|
||||
Memo.Lines.Add(' Item Weight Value');
|
||||
Memo.Lines.Add('---------------------------------------');
|
||||
BI.Start(BestIndex);
|
||||
while BI.Next(Inx) do
|
||||
begin
|
||||
S:=' '+Format('%-25s',[ItemsList[Inx].Name]);
|
||||
S:=S+Format('%5d',[ItemsList[Inx].Weight]);
|
||||
S:=S+Format('%7d',[ItemsList[Inx].Value]);
|
||||
Memo.Lines.Add(S);
|
||||
end;
|
||||
Memo.Lines.Add('---------------------------------------');
|
||||
Memo.Lines.Add(Format('Total %6d %6d',[BestWeight,BestValue]));
|
||||
Memo.Lines.Add('Best Inx: '+IntToStr(BestIndex));
|
||||
Memo.Lines.Add('Best Value: '+IntToStr(BestValue));
|
||||
Memo.Lines.Add('Best Weight: '+IntToStr(BestWeight));
|
||||
finally BI.Free; end;
|
||||
end;
|
||||
31
Task/Knapsack-problem-0-1/EasyLang/knapsack-problem-0-1.easy
Normal file
31
Task/Knapsack-problem-0-1/EasyLang/knapsack-problem-0-1.easy
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
name$[] = [ "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" ]
|
||||
weight[] = [ 9 13 153 50 15 68 27 39 23 52 11 32 24 48 73 42 43 22 7 18 4 30 ]
|
||||
value[] = [ 150 35 200 160 60 45 60 40 30 10 70 30 15 10 40 70 75 80 20 12 50 10 ]
|
||||
max_w = 400
|
||||
#
|
||||
proc solve i maxw . items[] wres vres .
|
||||
if i <= 0
|
||||
wres = 0
|
||||
vres = 0
|
||||
items[] = [ ]
|
||||
elif weight[i] > maxw
|
||||
call solve i - 1 maxw items[] wres vres
|
||||
else
|
||||
call solve i - 1 maxw items[] wres vres
|
||||
call solve i - 1 maxw - weight[i] items1[] w1 v1
|
||||
v1 += value[i]
|
||||
if v1 > vres
|
||||
swap items[] items1[]
|
||||
items[] &= i
|
||||
wres = w1 + weight[i]
|
||||
vres = v1
|
||||
.
|
||||
.
|
||||
.
|
||||
call solve len weight[] max_w items[] w v
|
||||
print "weight: " & w
|
||||
print "value: " & v
|
||||
print "items:"
|
||||
for i = 1 to len items[]
|
||||
print " " & name$[items[i]]
|
||||
.
|
||||
34
Task/Knapsack-problem-0-1/EchoLisp/knapsack-problem-0-1-1.l
Normal file
34
Task/Knapsack-problem-0-1/EchoLisp/knapsack-problem-0-1-1.l
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
(require 'struct)
|
||||
(require 'hash)
|
||||
(require 'sql)
|
||||
|
||||
(define H (make-hash))
|
||||
(define T (make-table (struct goodies (name poids valeur ))))
|
||||
(define-syntax-rule (name i) (table-xref T i 0))
|
||||
(define-syntax-rule (poids i) (table-xref T i 1))
|
||||
(define-syntax-rule (valeur i) (table-xref T i 2))
|
||||
|
||||
;; make an unique hash-key from (i rest)
|
||||
(define (t-idx i r) (string-append i "|" r))
|
||||
;; retrieve best score for item i, remaining r availbble weight
|
||||
(define (t-get i r) (or (hash-ref H (t-idx i r)) 0))
|
||||
|
||||
;; compute best score (i), assuming best (i-1 rest) is known
|
||||
(define (score i restant)
|
||||
(if (< i 0) 0
|
||||
(hash-ref! H (t-idx i restant)
|
||||
(if ( >= restant (poids i))
|
||||
(max
|
||||
(score (1- i) restant)
|
||||
(+ (score (1- i) (- restant (poids i))) (valeur i)))
|
||||
(score (1- i) restant)))))
|
||||
|
||||
;; compute best scores, starting from last item
|
||||
(define (task W)
|
||||
(define restant W)
|
||||
(define N (1- (table-count T)))
|
||||
(writeln 'total-value (score N W))
|
||||
(for/list ((i (in-range N -1 -1)))
|
||||
#:continue (= (t-get i restant) (t-get (1- i) restant))
|
||||
(set! restant (- restant (poids i)))
|
||||
(name i)))
|
||||
20
Task/Knapsack-problem-0-1/EchoLisp/knapsack-problem-0-1-2.l
Normal file
20
Task/Knapsack-problem-0-1/EchoLisp/knapsack-problem-0-1-2.l
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
;; init table
|
||||
(define goodies
|
||||
'((map 9 150) ; 9 is weight, 150 is value
|
||||
(compass 13 35) (water 153 200) (sandwich 50 160)
|
||||
(glucose 15 60) (tin 68 45)(banana 27 60) (apple 39 40)
|
||||
(fromage 23 30) (beer 52 10) (🌞-suntan-cream 11 70) (camera 32 30)
|
||||
(T-shirt 24 15) (pantalons 48 10) (umbrella 73 40)
|
||||
(☔️-trousers 42 70) (☔️-overclothes 43 75) (note-case 22 80)
|
||||
(🌞-sun-glasses 7 20) (towel 18 12) (socks 4 50) (book 30 10)))
|
||||
(list->table goodies T)
|
||||
|
||||
|
||||
(task 400)
|
||||
total-value 1030
|
||||
→ (socks 🌞-sun-glasses note-case ☔️-overclothes ☔️-trousers 🌞-suntan-cream banana
|
||||
glucose sandwich water compass map)
|
||||
|
||||
|
||||
(length (hash-keys H))
|
||||
→ 4939 ;; number of entries "i | weight" in hash table
|
||||
40
Task/Knapsack-problem-0-1/Eiffel/knapsack-problem-0-1-1.e
Normal file
40
Task/Knapsack-problem-0-1/Eiffel/knapsack-problem-0-1-1.e
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
class
|
||||
APPLICATION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
local
|
||||
knapsack: KNAPSACKZEROONE
|
||||
do
|
||||
create knapsack.make (400)
|
||||
knapsack.add_item (create {ITEM}.make ("", 0, 0))
|
||||
knapsack.add_item (create {ITEM}.make ("map", 9, 150))
|
||||
knapsack.add_item (create {ITEM}.make ("compass", 13, 35))
|
||||
knapsack.add_item (create {ITEM}.make ("water", 153, 200))
|
||||
knapsack.add_item (create {ITEM}.make ("sandwich", 50, 160))
|
||||
knapsack.add_item (create {ITEM}.make ("glucose", 15, 60))
|
||||
knapsack.add_item (create {ITEM}.make ("tin", 68, 45))
|
||||
knapsack.add_item (create {ITEM}.make ("banana", 27, 60))
|
||||
knapsack.add_item (create {ITEM}.make ("apple", 39, 40))
|
||||
knapsack.add_item (create {ITEM}.make ("cheese", 23, 30))
|
||||
knapsack.add_item (create {ITEM}.make ("beer", 52, 10))
|
||||
knapsack.add_item (create {ITEM}.make ("suntan cream", 11, 70))
|
||||
knapsack.add_item (create {ITEM}.make ("camera", 32, 30))
|
||||
knapsack.add_item (create {ITEM}.make ("T-shirt", 24, 15))
|
||||
knapsack.add_item (create {ITEM}.make ("trousers", 48, 10))
|
||||
knapsack.add_item (create {ITEM}.make ("umbrella, ella ella", 73, 40))
|
||||
knapsack.add_item (create {ITEM}.make ("waterproof trousers", 42, 70))
|
||||
knapsack.add_item (create {ITEM}.make ("waterproof overclothes", 43, 75))
|
||||
knapsack.add_item (create {ITEM}.make ("note-case", 22, 80))
|
||||
knapsack.add_item (create {ITEM}.make ("sunglasses", 7, 20))
|
||||
knapsack.add_item (create {ITEM}.make ("towel", 18, 12))
|
||||
knapsack.add_item (create {ITEM}.make ("socks", 4, 50))
|
||||
knapsack.add_item (create {ITEM}.make ("book", 30, 10))
|
||||
knapsack.compute_solution
|
||||
end
|
||||
|
||||
end
|
||||
35
Task/Knapsack-problem-0-1/Eiffel/knapsack-problem-0-1-2.e
Normal file
35
Task/Knapsack-problem-0-1/Eiffel/knapsack-problem-0-1-2.e
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
class
|
||||
ITEM
|
||||
|
||||
create
|
||||
make, make_from_other
|
||||
|
||||
feature
|
||||
|
||||
name: STRING
|
||||
|
||||
weight: INTEGER
|
||||
|
||||
value: INTEGER
|
||||
|
||||
make_from_other (other: ITEM)
|
||||
-- Item with name, weight and value set to 'other's name, weight and value.
|
||||
do
|
||||
name := other.name
|
||||
weight := other.weight
|
||||
value := other.value
|
||||
end
|
||||
|
||||
make (a_name: String; a_weight, a_value: INTEGER)
|
||||
-- Item with name, weight and value set to 'a_name', 'a_weight' and 'a_value'.
|
||||
require
|
||||
a_name /= Void
|
||||
a_weight >= 0
|
||||
a_value >= 0
|
||||
do
|
||||
name := a_name
|
||||
weight := a_weight
|
||||
value := a_value
|
||||
end
|
||||
|
||||
end
|
||||
106
Task/Knapsack-problem-0-1/Eiffel/knapsack-problem-0-1-3.e
Normal file
106
Task/Knapsack-problem-0-1/Eiffel/knapsack-problem-0-1-3.e
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
class
|
||||
KNAPSACKZEROONE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature
|
||||
|
||||
items: ARRAY [ITEM]
|
||||
|
||||
max_weight: INTEGER
|
||||
|
||||
feature
|
||||
|
||||
make (a_max_weight: INTEGER)
|
||||
-- Make an empty knapsack.
|
||||
require
|
||||
a_max_weight >= 0
|
||||
do
|
||||
create items.make_empty
|
||||
max_weight := a_max_weight
|
||||
end
|
||||
|
||||
add_item (item: ITEM)
|
||||
-- Add 'item' to knapsack.
|
||||
local
|
||||
temp: ITEM
|
||||
do
|
||||
create temp.make_from_other (item)
|
||||
items.force (item, items.count + 1)
|
||||
end
|
||||
|
||||
compute_solution
|
||||
local
|
||||
M: ARRAY [INTEGER]
|
||||
n: INTEGER
|
||||
i, j: INTEGER
|
||||
w_i, v_i: INTEGER
|
||||
item_i: ITEM
|
||||
final_items: LINKED_LIST [ITEM]
|
||||
do
|
||||
n := items.count
|
||||
create M.make_filled (0, 1, n * max_weight)
|
||||
from
|
||||
i := 2
|
||||
until
|
||||
(i > n)
|
||||
loop
|
||||
from
|
||||
j := 1
|
||||
until
|
||||
j > max_weight
|
||||
loop
|
||||
item_i := items [i]
|
||||
w_i := item_i.weight
|
||||
if w_i <= j then
|
||||
v_i := item_i.value
|
||||
M [(i - 1) * max_weight + j] := max (M [(i - 2) * max_weight + j], M [(i - 2) * max_weight + j - w_i + 1] + v_i)
|
||||
else
|
||||
M [(i - 1) * max_weight + j] := M [(i - 2) * max_weight + j]
|
||||
end
|
||||
j := j + 1
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
io.put_string ("The final value of the knapsack will be: ")
|
||||
io.put_integer (M [(n - 1) * max_weight + max_weight]);
|
||||
io.new_line
|
||||
--compute the items that fit into the knapsack
|
||||
create final_items.make
|
||||
io.put_string ("We'll take the following items: %N");
|
||||
from
|
||||
i := n
|
||||
j := max_weight
|
||||
until
|
||||
i <= 1 or j <= 1
|
||||
loop
|
||||
item_i := items [i]
|
||||
w_i := item_i.weight
|
||||
if w_i <= j then
|
||||
v_i := item_i.value
|
||||
if M [(i - 1) * max_weight + j] = M [(i - 2) * max_weight + j] then
|
||||
else
|
||||
final_items.extend (item_i)
|
||||
io.put_string (item_i.name)
|
||||
io.new_line
|
||||
j := j - w_i
|
||||
end
|
||||
else
|
||||
end
|
||||
i := i - 1
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE}
|
||||
|
||||
max (a, b: INTEGER): INTEGER
|
||||
-- Max of 'a' and 'b'.
|
||||
do
|
||||
Result := a
|
||||
if a < b then
|
||||
Result := b
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
61
Task/Knapsack-problem-0-1/Elixir/knapsack-problem-0-1.elixir
Normal file
61
Task/Knapsack-problem-0-1/Elixir/knapsack-problem-0-1.elixir
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
defmodule Knapsack do
|
||||
def solve([], _total_weight, item_acc, value_acc, weight_acc), do:
|
||||
{item_acc, value_acc, weight_acc}
|
||||
def solve([{_item, item_weight, _item_value} | t],
|
||||
total_weight,
|
||||
item_acc,
|
||||
value_acc,
|
||||
weight_acc) when item_weight > total_weight, do:
|
||||
solve(t, total_weight, item_acc, value_acc, weight_acc)
|
||||
def solve([{item_name, item_weight, item_value} | t],
|
||||
total_weight,
|
||||
item_acc,
|
||||
value_acc,
|
||||
weight_acc) do
|
||||
{_tail_item_acc, tail_value_acc, _tail_weight_acc} = tail_res =
|
||||
solve(t, total_weight, item_acc, value_acc, weight_acc)
|
||||
{_head_item_acc, head_value_acc, _head_weight_acc} = head_res =
|
||||
solve(t,
|
||||
total_weight - item_weight,
|
||||
[item_name | item_acc],
|
||||
value_acc + item_value,
|
||||
weight_acc + item_weight)
|
||||
if tail_value_acc > head_value_acc, do: tail_res, else: head_res
|
||||
end
|
||||
end
|
||||
|
||||
stuff = [{"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}]
|
||||
max_weight = 400
|
||||
|
||||
go = fn (stuff, max_weight) ->
|
||||
{time, {item_list, total_value, total_weight}} = :timer.tc(fn ->
|
||||
Knapsack.solve(stuff, max_weight, [], 0, 0)
|
||||
end)
|
||||
IO.puts "Items:"
|
||||
Enum.each(item_list, fn item -> IO.inspect item end)
|
||||
IO.puts "Total value: #{total_value}"
|
||||
IO.puts "Total weight: #{total_weight}"
|
||||
IO.puts "Time elapsed in milliseconds: #{time/1000}"
|
||||
end
|
||||
go.(stuff, max_weight)
|
||||
|
|
@ -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)
|
||||
71
Task/Knapsack-problem-0-1/Erlang/knapsack-problem-0-1.erl
Normal file
71
Task/Knapsack-problem-0-1/Erlang/knapsack-problem-0-1.erl
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
-module(knapsack_0_1).
|
||||
|
||||
-export([go/0,
|
||||
solve/5]).
|
||||
|
||||
-define(STUFF,
|
||||
[{"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}
|
||||
]).
|
||||
|
||||
-define(MAX_WEIGHT, 400).
|
||||
|
||||
go() ->
|
||||
StartTime = os:timestamp(),
|
||||
{ItemList, TotalValue, TotalWeight} =
|
||||
solve(?STUFF, ?MAX_WEIGHT, [], 0, 0),
|
||||
TimeElapsed = timer:now_diff(os:timestamp(), StartTime),
|
||||
io:format("Items: ~n"),
|
||||
[io:format("~p~n", [Item]) || Item <- ItemList],
|
||||
io:format(
|
||||
"Total value: ~p~nTotal weight: ~p~nTime elapsed in milliseconds: ~p~n",
|
||||
[TotalValue, TotalWeight, TimeElapsed/1000]).
|
||||
|
||||
solve([], _TotalWeight, ItemAcc, ValueAcc, WeightAcc) ->
|
||||
{ItemAcc, ValueAcc, WeightAcc};
|
||||
solve([{_Item, ItemWeight, _ItemValue} | T],
|
||||
TotalWeight,
|
||||
ItemAcc,
|
||||
ValueAcc,
|
||||
WeightAcc) when ItemWeight > TotalWeight ->
|
||||
solve(T, TotalWeight, ItemAcc, ValueAcc, WeightAcc);
|
||||
solve([{ItemName, ItemWeight, ItemValue} | T],
|
||||
TotalWeight,
|
||||
ItemAcc,
|
||||
ValueAcc,
|
||||
WeightAcc) ->
|
||||
{_TailItemAcc, TailValueAcc, _TailWeightAcc} = TailRes =
|
||||
solve(T, TotalWeight, ItemAcc, ValueAcc, WeightAcc),
|
||||
{_HeadItemAcc, HeadValueAcc, _HeadWeightAcc} = HeadRes =
|
||||
solve(T,
|
||||
TotalWeight - ItemWeight,
|
||||
[ItemName | ItemAcc],
|
||||
ValueAcc + ItemValue,
|
||||
WeightAcc + ItemWeight),
|
||||
|
||||
case TailValueAcc > HeadValueAcc of
|
||||
true ->
|
||||
TailRes;
|
||||
false ->
|
||||
HeadRes
|
||||
end.
|
||||
26
Task/Knapsack-problem-0-1/Euler/knapsack-problem-0-1.euler
Normal file
26
Task/Knapsack-problem-0-1/Euler/knapsack-problem-0-1.euler
Normal file
|
|
@ -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
|
||||
22
Task/Knapsack-problem-0-1/F-Sharp/knapsack-problem-0-1-1.fs
Normal file
22
Task/Knapsack-problem-0-1/F-Sharp/knapsack-problem-0-1-1.fs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//Solve Knapsack 0-1 using A* algorithm
|
||||
//Nigel Galloway, August 3rd., 2018
|
||||
let knapStar items maxW=
|
||||
let l=List.length items
|
||||
let p=System.Collections.Generic.SortedSet<float*int*float*float*list<int>>() //H*; level; value of items taken so far; weight so far
|
||||
p.Add (0.0,0,0.0,0.0,[])|>ignore
|
||||
let H items maxW=let rec H n g a=match g with |(_,w,v)::e->let t=n+w
|
||||
if t<=maxW then H t e (a+v) else a+(v/w)*(maxW-n)
|
||||
|_->a
|
||||
H 0.0 items 0.0
|
||||
let pAdd ((h,_,_,_,_) as n) bv=if h>bv then p.Add n |> ignore
|
||||
let fH n (bv,t) w' v' t'=let _,w,v=List.item n items
|
||||
let e=max bv (if w<=(maxW-w') then v'+v else bv)
|
||||
let rt=n::t'
|
||||
if n+1<l then pAdd ((v'+H (List.skip (n+1) items) maxW),n+1,v',w',t') bv
|
||||
if w<=(maxW-w') then pAdd ((v'+v+H (List.skip (n+1) items) (maxW-w')),n+1,v'+v,w'+w,rt) bv
|
||||
if e>bv then (e,rt) else (bv,t)
|
||||
let rec fN (bv,t)=
|
||||
let h,zl,zv,zw,zt as r=p.Max
|
||||
p.Remove r |> ignore
|
||||
if bv>=h then t else fN (fH zl (bv,t) zw zv zt)
|
||||
fN (fH 0 (0.0,[]) 0.0 0.0 [])
|
||||
23
Task/Knapsack-problem-0-1/F-Sharp/knapsack-problem-0-1-2.fs
Normal file
23
Task/Knapsack-problem-0-1/F-Sharp/knapsack-problem-0-1-2.fs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
let itemsf = [
|
||||
"map", 9.0, 150.0;
|
||||
"compass", 13.0, 35.0;
|
||||
"water", 153.0, 200.0;
|
||||
"sandwich", 50.0, 160.0;
|
||||
"glucose", 15.0, 60.0;
|
||||
"tin", 68.0, 45.0;
|
||||
"banana", 27.0, 60.0;
|
||||
"apple", 39.0, 40.0;
|
||||
"cheese", 23.0, 30.0;
|
||||
"beer", 52.0, 10.0;
|
||||
"suntan cream", 11.0, 70.0;
|
||||
"camera", 32.0, 30.0;
|
||||
"t-shirt", 24.0, 15.0;
|
||||
"trousers", 48.0, 10.0;
|
||||
"umbrella", 73.0, 40.0;
|
||||
"waterproof trousers", 42.0, 70.0;
|
||||
"waterproof overclothes", 43.0, 75.0;
|
||||
"note-case", 22.0, 80.0;
|
||||
"sunglasses", 7.0, 20.0;
|
||||
"towel", 18.0, 12.0;
|
||||
"socks", 4.0, 50.0;
|
||||
"book", 30.0, 10.0;]|> List.sortBy(fun(_,n,g)->n/g)
|
||||
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 ;
|
||||
70
Task/Knapsack-problem-0-1/Forth/knapsack-problem-0-1.fth
Normal file
70
Task/Knapsack-problem-0-1/Forth/knapsack-problem-0-1.fth
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
\ Rosetta Code Knapp-sack 0-1 problem. Tested under GForth 0.7.3.
|
||||
\ 22 items. On current processors a set fits nicely in one CELL (32 or 64 bits).
|
||||
\ Brute force approach: for every possible set of 22 items,
|
||||
\ check for admissible solution then for optimal set.
|
||||
|
||||
: offs HERE over - ;
|
||||
400 VALUE WLIMIT
|
||||
0 VALUE ITEM
|
||||
0 VALUE VAL
|
||||
0 VALUE /ITEM
|
||||
0 VALUE ITEMS#
|
||||
Create Sack
|
||||
HERE
|
||||
9 , offs TO VAL
|
||||
150 , offs TO ITEM
|
||||
s" map " s, offs TO /ITEM
|
||||
DROP
|
||||
13 , 35 , s" compass " s,
|
||||
153 , 200 , s" water " s,
|
||||
50 , 160 , s" sandwich " s,
|
||||
15 , 60 , s" glucose " s,
|
||||
68 , 45 , s" tin " s,
|
||||
27 , 60 , s" banana " s,
|
||||
39 , 40 , s" apple " s,
|
||||
23 , 30 , s" cheese " s,
|
||||
52 , 10 , s" beer " s,
|
||||
11 , 70 , s" suntan cream " s,
|
||||
32 , 30 , s" camera " s,
|
||||
24 , 15 , s" T-shirt " s,
|
||||
48 , 10 , s" trousers " s,
|
||||
73 , 40 , s" umbrella " s,
|
||||
42 , 70 , s" wp trousers " s,
|
||||
43 , 75 , s" wp overclothes " s,
|
||||
22 , 80 , s" note-case " s,
|
||||
7 , 20 , s" sunglasses " s,
|
||||
18 , 12 , s" towel " s,
|
||||
4 , 50 , s" socks " s,
|
||||
30 , 10 , s" book " s,
|
||||
HERE VALUE END-SACK
|
||||
VARIABLE Sol \ Solution Set
|
||||
VARIABLE Vmax \ Temporary Maximum Value
|
||||
VARIABLE Sum \ Temporary Sum (for speed-up)
|
||||
: ]sum ( Rtime: set -- sum ;Ctime: hilimit.a start.a -- )
|
||||
\ Loop unwinding & precomputing addresses
|
||||
]
|
||||
]] Sum OFF [[
|
||||
DO ]] dup [[ 1 ]] LITERAL AND IF [[ I ]] LITERAL @ Sum +! THEN 2/ [[
|
||||
/ITEM +LOOP ]] drop Sum @ [[
|
||||
; IMMEDIATE
|
||||
: solve ( -- )
|
||||
Vmax OFF
|
||||
[ 1 END-SACK Sack - /ITEM / lshift 1- ]L 0
|
||||
DO
|
||||
I [ END-SACK Sack ]sum ( by weight ) WLIMIT <
|
||||
IF
|
||||
I [ END-SACK VAL + Sack VAL + ]sum ( by value )
|
||||
dup Vmax @ >
|
||||
IF Vmax ! I Sol ! ELSE drop THEN
|
||||
THEN
|
||||
LOOP
|
||||
;
|
||||
: .solution ( -- )
|
||||
Sol @ END-SACK ITEM + Sack ITEM +
|
||||
DO
|
||||
dup 1 AND IF I count type cr THEN
|
||||
2/
|
||||
/ITEM +LOOP
|
||||
drop
|
||||
." Weight: " Sol @ [ END-SACK Sack ]sum . ." Value: " Sol @ [ END-SACK VAL + Sack VAL + ]sum .
|
||||
;
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
program Knapsack01;
|
||||
{$mode objfpc}{$j-}
|
||||
uses
|
||||
Math;
|
||||
|
||||
type
|
||||
TItem = record
|
||||
Name: string;
|
||||
Weight, Value: Integer;
|
||||
end;
|
||||
|
||||
const
|
||||
NUM_ITEMS = 22;
|
||||
ITEMS: array[0..NUM_ITEMS-1] of TItem = (
|
||||
(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)
|
||||
);
|
||||
MAX_WEIGHT = 400;
|
||||
|
||||
var
|
||||
D: array of array of Integer;
|
||||
I, W, V, MaxWeight: Integer;
|
||||
begin
|
||||
SetLength(D, NUM_ITEMS + 1, MAX_WEIGHT + 1);
|
||||
for I := 0 to High(ITEMS) do
|
||||
for W := 0 to MAX_WEIGHT do
|
||||
if ITEMS[I].Weight > W then
|
||||
D[I+1, W] := D[I, W]
|
||||
else
|
||||
D[I+1, W] := Max(D[I, W], D[I, W - ITEMS[I].Weight] + ITEMS[I].Value);
|
||||
|
||||
W := MAX_WEIGHT;
|
||||
V := D[NUM_ITEMS, W];
|
||||
MaxWeight := 0;
|
||||
WriteLn('bagged:');
|
||||
for I := High(ITEMS) downto 0 do
|
||||
if (D[I+1, W] = V)and(D[I, W - ITEMS[I].Weight] = V - ITEMS[I].Value)then begin
|
||||
WriteLn(' ', ITEMS[I].Name);
|
||||
Inc(MaxWeight, ITEMS[I].Weight);
|
||||
Dec(W, ITEMS[I].Weight);
|
||||
Dec(V, ITEMS[I].Value);
|
||||
end;
|
||||
WriteLn('value = ', D[NUM_ITEMS, MAX_WEIGHT]);
|
||||
WriteLn('weight = ', MaxWeight);
|
||||
end.
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#define Tabu = Chr(9)
|
||||
Dim As Integer i, A, P, V, N
|
||||
Dim As Integer MejorArticulo, MejorValor = 0
|
||||
Type Knapsack
|
||||
articulo As String*22
|
||||
peso As Integer
|
||||
valor As Integer
|
||||
End Type
|
||||
Dim item(1 To 22) As Knapsack => { _
|
||||
("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)}
|
||||
|
||||
For i = 1 To (1 Shl 22)-1
|
||||
A = i : P = 0 : V = 0 : N = 1
|
||||
While A
|
||||
If A And 1 Then
|
||||
P += item(N).peso
|
||||
V += item(N).valor
|
||||
End If
|
||||
A Shr= 1
|
||||
N += 1
|
||||
Wend
|
||||
If V > MejorValor And P <= 400 Then
|
||||
MejorValor = V
|
||||
MejorArticulo = i
|
||||
End If
|
||||
Next
|
||||
|
||||
A = MejorArticulo : P = 0 : V = 0 : N = 1
|
||||
While A
|
||||
If A And 1 Then
|
||||
Print " "; item(N).articulo; Tabu;
|
||||
Print item(N).peso; Tabu; item(N).valor
|
||||
P += item(N).peso
|
||||
V += item(N).valor
|
||||
End If
|
||||
A Shr= 1 : N += 1
|
||||
Wend
|
||||
Print "Totals:"; Spc(25); P; Tabu; V
|
||||
Sleep
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
window 1, @"Knapsack Problem", (0,0,480,270)
|
||||
|
||||
_maxWeight = 400
|
||||
|
||||
void local fn FillKnapsack
|
||||
long totalWeight = 0, totalValue = 0, itemWeight, unusedWeight
|
||||
CFDictionaryRef item, extraItem = NULL
|
||||
SortDescriptorRef sd
|
||||
CFMutableArrayRef packedItems
|
||||
|
||||
CFArrayRef items = @[
|
||||
@{@"item":@"map", @"weight":@9, @"value":@150},
|
||||
@{@"item":@"compass", @"weight":@13, @"value":@35 },
|
||||
@{@"item":@"water", @"weight":@153, @"value":@200},
|
||||
@{@"item":@"sandwich", @"weight":@50, @"value":@160},
|
||||
@{@"item":@"glucose", @"weight":@15, @"value":@60 },
|
||||
@{@"item":@"tin", @"weight":@68, @"value":@45 },
|
||||
@{@"item":@"banana", @"weight":@27, @"value":@60 },
|
||||
@{@"item":@"apple", @"weight":@39, @"value":@40 },
|
||||
@{@"item":@"cheese", @"weight":@23, @"value":@30 },
|
||||
@{@"item":@"beer", @"weight":@52, @"value":@10 },
|
||||
@{@"item":@"suntan cream", @"weight":@11, @"value":@70 },
|
||||
@{@"item":@"camera", @"weight":@32, @"value":@30 },
|
||||
@{@"item":@"T-shirt", @"weight":@24, @"value":@15 },
|
||||
@{@"item":@"trousers", @"weight":@48, @"value":@10 },
|
||||
@{@"item":@"umbrella", @"weight":@73, @"value":@40 },
|
||||
@{@"item":@"waterproof trousers", @"weight":@42, @"value":@70 },
|
||||
@{@"item":@"waterproof overclothes", @"weight":@43, @"value":@75 },
|
||||
@{@"item":@"note-case", @"weight":@22, @"value":@80 },
|
||||
@{@"item":@"sunglasses", @"weight":@7, @"value":@20 },
|
||||
@{@"item":@"towel", @"weight":@18, @"value":@12 },
|
||||
@{@"item":@"socks", @"weight":@4, @"value":@50 },
|
||||
@{@"item":@"book", @"weight":@30, @"value":@10 }
|
||||
]
|
||||
|
||||
sd = fn SortDescriptorWithKey( @"value", NO )
|
||||
items = fn ArraySortedArrayUsingDescriptors( items, @[sd] )
|
||||
packedItems = fn MutableArrayWithCapacity(0)
|
||||
for item in items
|
||||
itemWeight = fn NumberIntegerValue(item[@"weight"])
|
||||
if ( totalWeight + itemWeight <= _maxWeight )
|
||||
MutableArrayAddObject( packedItems, item )
|
||||
totalWeight += itemWeight
|
||||
totalValue += fn NumberIntegerValue(item[@"value"])
|
||||
end if
|
||||
next
|
||||
|
||||
text @"Menlo-Bold",,, fn ColorWithRGB(1.0,0.0,1.0,0.25),, 170
|
||||
print @"Item",@"Weight",@"Value"
|
||||
text @"Menlo",,, fn ColorClear
|
||||
for item in packedItems
|
||||
printf @"%@\t%6ld\t%5ld",item[@"item"],fn NumberIntegerValue(item[@"weight"]),fn NumberIntegerValue(item[@"value"])
|
||||
next
|
||||
text ,,, fn ColorWithRGB(1.0,0.0,1.0,0.25)
|
||||
printf @"knapsack\t%6ld\t%5ld",totalWeight,totalValue
|
||||
|
||||
text
|
||||
print
|
||||
|
||||
unusedWeight = _maxWeight - totalWeight
|
||||
|
||||
for item in items
|
||||
if ( fn NumberIntegerValue(item[@"weight"]) <= unusedWeight )
|
||||
extraItem = item : break
|
||||
end if
|
||||
next
|
||||
|
||||
if ( extraItem ) then printf @"There's just enough room for extra %@!", extraItem[@"item"]
|
||||
end fn
|
||||
|
||||
fn FillKnapsack
|
||||
|
||||
HandleEvents
|
||||
57
Task/Knapsack-problem-0-1/Go/knapsack-problem-0-1-1.go
Normal file
57
Task/Knapsack-problem-0-1/Go/knapsack-problem-0-1-1.go
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
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},
|
||||
}
|
||||
|
||||
const maxWt = 400
|
||||
|
||||
func main() {
|
||||
items, w, v := m(len(wants)-1, maxWt)
|
||||
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
|
||||
}
|
||||
7
Task/Knapsack-problem-0-1/Go/knapsack-problem-0-1-2.go
Normal file
7
Task/Knapsack-problem-0-1/Go/knapsack-problem-0-1-2.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
var wants = []item{
|
||||
{"sunscreen", 15, 2},
|
||||
{"GPS", 25, 2},
|
||||
{"beer", 35, 3},
|
||||
}
|
||||
|
||||
const maxWt = 40
|
||||
|
|
@ -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
|
||||
13
Task/Knapsack-problem-0-1/Haskell/knapsack-problem-0-1-3.hs
Normal file
13
Task/Knapsack-problem-0-1/Haskell/knapsack-problem-0-1-3.hs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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),
|
||||
("waterproof trousers",42,70), ("overclothes",43,75), ("notecase",22,80),
|
||||
("sunglasses",7,20), ("towel",18,12), ("socks",4,50), ("book",30,10)]
|
||||
|
||||
knapsack = foldr addItem (repeat (0,[])) where
|
||||
addItem (name,w,v) list = left ++ zipWith max right newlist where
|
||||
newlist = map (\(val, names)->(val + v, name:names)) list
|
||||
(left,right) = splitAt w list
|
||||
|
||||
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
|
||||
9
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-3.j
Normal file
9
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-3.j
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
'names values'=:|:".;._2]0 :0
|
||||
'sunscreen'; 15 2
|
||||
'GPS'; 25 2
|
||||
'beer'; 35 3
|
||||
)
|
||||
|
||||
X=: +/ .*"1
|
||||
plausible=: (] (] #~ 40 >: X) #:@i.@(2&^)@#)@:({."1)
|
||||
best=: (plausible ([ {~ [ (i. >./)@:X {:"1@]) ]) values
|
||||
5
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-4.j
Normal file
5
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-4.j
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
+/best#values
|
||||
40 4
|
||||
best#names
|
||||
sunscreen
|
||||
GPS
|
||||
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
|
||||
68
Task/Knapsack-problem-0-1/JavaScript/knapsack-problem-0-1.js
Normal file
68
Task/Knapsack-problem-0-1/JavaScript/knapsack-problem-0-1.js
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>KNAPSACK 22 JavaScript</title> </head> <body> <noscript>Vkluch JS</noscript>
|
||||
|
||||
https://jdoodle.com/h/2Ut
|
||||
|
||||
rextester.com/BQYV50962
|
||||
|
||||
<script>
|
||||
|
||||
var n=22; G=400; a = Math.pow(2,n+1); // KNAPSACKj.js
|
||||
var dec, i, h, k, max, m, s;
|
||||
var L=[n], C=[n], j=[n], q=[a], d=[a]; e=[a];
|
||||
|
||||
document.write("<br><br># Kol Cena<br>")
|
||||
document.write("# Amo Price<br><br>")
|
||||
|
||||
L=[ 9,13,153,50,15,68,27,39,23,52,11,32,24,48,73,42,43,22,7,18,4,30 ]
|
||||
C=[ 150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,50,10 ]
|
||||
|
||||
for (i=0; i<n; i++)
|
||||
{ // L[i]=1+Math.floor(Math.random()*3)
|
||||
// C[i]=10+Math.floor(Math.random()*9);
|
||||
j[i]=0;
|
||||
document.write( (i+1) +" "+ L[i] +" "+ C[i] +"<br>")
|
||||
}
|
||||
for (i=0; i<a; i++) { q[i]=0; d[i]=0;}
|
||||
document.write("<br>")
|
||||
|
||||
document.write("Mx Kol St-st Schifr<br>")
|
||||
document.write("Mx Amo Price Cipher<br>")
|
||||
|
||||
for (h = a-1; h>(a-1)/2; h--)
|
||||
{ dec=h; e[h]=""
|
||||
|
||||
while (dec > 0)
|
||||
{ s = Math.floor(dec % 2);
|
||||
e[h] = s + e[h]; dec = Math.floor(dec/2);
|
||||
}
|
||||
|
||||
if (e[h] == "") {e[h] = "0";}
|
||||
e[h]= e[h].substr(1, e[h].length-1);
|
||||
|
||||
for (k=0; k<n; k++)
|
||||
{ j[k] = Number(e[h].substr(k,1));
|
||||
q[h]=q[h]+j[k]*C[k];
|
||||
d[h]=d[h]+L[k]*j[k];
|
||||
}
|
||||
|
||||
// if (d[h] <= G)
|
||||
// document.write("<br>"+ G +" "+ d[h] +" "+ q[h] +" "+ e[h])
|
||||
|
||||
} document.write("<br>")
|
||||
|
||||
max=0; m=1;
|
||||
for (i=0; i<a; i++)
|
||||
{ if (d[i]<=G && q[i]>max){ max=q[i]; m=i;}
|
||||
}
|
||||
|
||||
document.write("<br>"+ d[m] +" "+ q[m] +" "+ e[m] +"<br><br>")
|
||||
|
||||
document.write("Mx St-st Schifr<br>")
|
||||
document.write("Mx Price Cipher<br><br>")
|
||||
|
||||
</script>
|
||||
|
||||
</body> </html>
|
||||
25
Task/Knapsack-problem-0-1/Jq/knapsack-problem-0-1-1.jq
Normal file
25
Task/Knapsack-problem-0-1/Jq/knapsack-problem-0-1-1.jq
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Input should be the array of objects giving name, weight and value.
|
||||
# Because of the way addition is defined on null and because of the
|
||||
# way setpath works, there is no need to initialize the matrix m in
|
||||
# detail.
|
||||
def dynamic_knapsack(W):
|
||||
. as $objects
|
||||
| length as $n
|
||||
| reduce range(1; $n+1) as $i # i is the number of items
|
||||
# state: m[i][j] is an array of [value, array_of_object_names]
|
||||
(null; # see above remark about initialization of m
|
||||
$objects[$i-1] as $o
|
||||
| reduce range(0; W+1) as $j
|
||||
( .;
|
||||
if $o.weight <= $j then
|
||||
.[$i-1][$j][0] as $v1 # option 1: do not add this object
|
||||
| (.[$i-1][$j - $o.weight][0] + $o.value) as $v2 # option 2: add it
|
||||
| (if $v1 > $v2 then
|
||||
[$v1, .[$i-1][$j][1]] # do not add this object
|
||||
else [$v2, .[$i-1][$j - $o.weight][1]+[$o.name]] # add it
|
||||
end) as $mx
|
||||
| .[$i][$j] = $mx
|
||||
else
|
||||
.[$i][$j] = .[$i-1][$j]
|
||||
end))
|
||||
| .[$n][W];
|
||||
26
Task/Knapsack-problem-0-1/Jq/knapsack-problem-0-1-2.jq
Normal file
26
Task/Knapsack-problem-0-1/Jq/knapsack-problem-0-1-2.jq
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
def objects: [
|
||||
{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: "suntancream", "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}
|
||||
];
|
||||
|
||||
objects | dynamic_knapsack(400)[]
|
||||
3
Task/Knapsack-problem-0-1/Jq/knapsack-problem-0-1-3.jq
Normal file
3
Task/Knapsack-problem-0-1/Jq/knapsack-problem-0-1-3.jq
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
$jq -M -c -n -f knapsack.jq
|
||||
1030
|
||||
["map","compass","water","sandwich","glucose","banana","suntancream","waterproof trousers","waterproof overclothes","note-case","sunglasses","socks"]
|
||||
17
Task/Knapsack-problem-0-1/Julia/knapsack-problem-0-1-1.julia
Normal file
17
Task/Knapsack-problem-0-1/Julia/knapsack-problem-0-1-1.julia
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
struct KPDSupply{T<:Integer}
|
||||
item::String
|
||||
weight::T
|
||||
value::T
|
||||
quant::T
|
||||
end
|
||||
|
||||
KPDSupply{T<:Integer}(itm::AbstractString, w::T, v::T, q::T=one(T)) = KPDSupply(itm, w, v, q)
|
||||
Base.show(io::IO, kdps::KPDSupply) = print(io, kdps.quant, " ", kdps.item, " ($(kdps.weight) kg, $(kdps.value) €)")
|
||||
|
||||
using MathProgBase, Cbc
|
||||
function solve(gear::Vector{<:KPDSupply}, capacity::Integer)
|
||||
w = getfield.(gear, :weight)
|
||||
v = getfield.(gear, :value)
|
||||
sol = mixintprog(-v, w', '<', capacity, :Bin, 0, 1, CbcSolver())
|
||||
gear[sol.sol .≈ 1]
|
||||
end
|
||||
27
Task/Knapsack-problem-0-1/Julia/knapsack-problem-0-1-2.julia
Normal file
27
Task/Knapsack-problem-0-1/Julia/knapsack-problem-0-1-2.julia
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
gear = [KPDSupply("map", 9, 150),
|
||||
KPDSupply("compass", 13, 35),
|
||||
KPDSupply("water", 153, 200),
|
||||
KPDSupply("sandwich", 50, 160),
|
||||
KPDSupply("glucose", 15, 60),
|
||||
KPDSupply("tin", 68, 45),
|
||||
KPDSupply("banana", 27, 60),
|
||||
KPDSupply("apple", 39, 40),
|
||||
KPDSupply("cheese", 23, 30),
|
||||
KPDSupply("beer", 52, 10),
|
||||
KPDSupply("suntan cream", 11, 70),
|
||||
KPDSupply("camera", 32, 30),
|
||||
KPDSupply("T-shirt", 24, 15),
|
||||
KPDSupply("trousers", 48, 10),
|
||||
KPDSupply("umbrella", 73, 40),
|
||||
KPDSupply("waterproof trousers", 42, 70),
|
||||
KPDSupply("waterproof overclothes", 43, 75),
|
||||
KPDSupply("note-case", 22, 80),
|
||||
KPDSupply("sunglasses", 7, 20),
|
||||
KPDSupply("towel", 18, 12),
|
||||
KPDSupply("socks", 4, 50),
|
||||
KPDSupply("book", 30, 10)]
|
||||
|
||||
pack = solve(gear, 400)
|
||||
println("The hicker should pack: \n - ", join(pack, "\n - "))
|
||||
println("\nPacked weight: ", mapreduce(x -> x.weight, +, pack), " kg")
|
||||
println("Packed value: ", mapreduce(x -> x.value, +, pack), " €")
|
||||
54
Task/Knapsack-problem-0-1/Kotlin/knapsack-problem-0-1.kotlin
Normal file
54
Task/Knapsack-problem-0-1/Kotlin/knapsack-problem-0-1.kotlin
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// version 1.1.2
|
||||
|
||||
data class Item(val name: String, val weight: Int, val value: Int)
|
||||
|
||||
val wants = listOf(
|
||||
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)
|
||||
)
|
||||
|
||||
const val MAX_WEIGHT = 400
|
||||
|
||||
fun m(i: Int, w: Int): Triple<MutableList<Item>, Int, Int> {
|
||||
val chosen = mutableListOf<Item>()
|
||||
if (i < 0 || w == 0) return Triple(chosen, 0, 0)
|
||||
else if (wants[i].weight > w) return m(i - 1, w)
|
||||
val (l0, w0, v0) = m(i - 1, w)
|
||||
var (l1, w1, v1) = m(i - 1, w - wants[i].weight)
|
||||
v1 += wants[i].value
|
||||
if (v1 > v0) {
|
||||
l1.add(wants[i])
|
||||
return Triple(l1, w1 + wants[i].weight, v1)
|
||||
}
|
||||
return Triple(l0, w0, v0)
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val (chosenItems, totalWeight, totalValue) = m(wants.size - 1, MAX_WEIGHT)
|
||||
println("Knapsack Item Chosen Weight Value")
|
||||
println("---------------------- ------ -----")
|
||||
for (item in chosenItems.sortedByDescending { it.value} )
|
||||
println("${item.name.padEnd(24)} ${"%3d".format(item.weight)} ${"%3d".format(item.value)}")
|
||||
println("---------------------- ------ -----")
|
||||
println("Total ${chosenItems.size} Items Chosen $totalWeight $totalValue")
|
||||
}
|
||||
50
Task/Knapsack-problem-0-1/LSL/knapsack-problem-0-1-1.lsl
Normal file
50
Task/Knapsack-problem-0-1/LSL/knapsack-problem-0-1-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);
|
||||
}
|
||||
}
|
||||
}
|
||||
85
Task/Knapsack-problem-0-1/LSL/knapsack-problem-0-1-2.lsl
Normal file
85
Task/Knapsack-problem-0-1/LSL/knapsack-problem-0-1-2.lsl
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
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},
|
||||
}
|
||||
|
||||
local unpack = table.unpack
|
||||
|
||||
function m(i, w)
|
||||
if i<1 or w==0 then
|
||||
return 0, {}
|
||||
else
|
||||
local _, wi, vi = unpack(items[i])
|
||||
if wi > w then
|
||||
return mm(i - 1, w)
|
||||
else
|
||||
local vn, ln = mm(i - 1, w)
|
||||
local vy, ly = mm(i - 1, w - wi)
|
||||
if vy + vi > vn then
|
||||
return vy + vi, { i, ly }
|
||||
else
|
||||
return vn, ln
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local memo, mm_calls = {}, 0
|
||||
function mm(i, w) -- memoization function for m
|
||||
mm_calls = mm_calls + 1
|
||||
local key = 10000*i + w
|
||||
local result = memo[key]
|
||||
if not result then
|
||||
result = { m(i, w) }
|
||||
memo[key] = result
|
||||
end
|
||||
return unpack(result)
|
||||
end
|
||||
|
||||
local total_value, index_list = m(#items, 400)
|
||||
|
||||
function list_items(head) -- makes linked list iterator function
|
||||
return function()
|
||||
local item, rest = unpack(head)
|
||||
head = rest
|
||||
return item
|
||||
end
|
||||
end
|
||||
|
||||
local names = {}
|
||||
local total_weight = 0
|
||||
for i in list_items(index_list) do
|
||||
local name, weight = unpack(items[i])
|
||||
table.insert(names, 1, name)
|
||||
total_weight = total_weight + weight
|
||||
end
|
||||
|
||||
local function printf(fmt, ...) print(string.format(fmt, ...)) end
|
||||
printf("items to pack: %s", table.concat(names, ", "))
|
||||
printf("total value: %d", total_value)
|
||||
printf("total weight: %d", total_weight)
|
||||
|
||||
-- out of curiosity
|
||||
local count = 0
|
||||
for k,v in pairs(memo) do count = count + 1 end
|
||||
printf("\n(memo count: %d; mm call count: %d)", count, mm_calls)
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
global globalItems = #()
|
||||
global usedMass = 0
|
||||
global neededItems = #()
|
||||
global totalValue = 0
|
||||
struct kn_item
|
||||
(
|
||||
item, weight, value
|
||||
)
|
||||
|
||||
itemStrings = #("map#9#150","compass#13#35","water#153#200", \
|
||||
"sandwich#50#160","glucose#15#60","tin#68#45", \
|
||||
"banana#27#60","apple#39#40","cheese#23#30", \
|
||||
"beer#52#10","suntan cream#11#70","camera#32#30", \
|
||||
"T-shirt#24#15","trousers#48#10","umbrella#73#40", \
|
||||
"waterproof trousers#42#70","waterproof overclothes#43#75", \
|
||||
"note-case#22#80","sunglasses#7#20", "towel#18#12", \
|
||||
"socks#4#50","book#30#10")
|
||||
|
||||
fn sortByValue a b =
|
||||
(
|
||||
if a[1].value > b[1].value then return -1
|
||||
else
|
||||
(
|
||||
if a[1].value == b[1].value then return 0
|
||||
else return 1
|
||||
)
|
||||
)
|
||||
fn chooseBestItem maximumWeight: items: =
|
||||
(
|
||||
local itemsCopy = deepcopy items
|
||||
local possibleItems = #()
|
||||
for i = 1 to itemsCopy.count do
|
||||
(
|
||||
if itemsCopy[i].weight <= maximumWeight do append possibleItems (#(itemsCopy[i],i))
|
||||
)
|
||||
qsort possibleItems sortByValue
|
||||
if possibleItems.count > 0 then return possibleItems[1] else return 0
|
||||
)
|
||||
|
||||
for i = 1 to itemStrings.count do
|
||||
(
|
||||
local split = filterstring itemStrings[i] "#"
|
||||
local itemStruct = kn_item item:split[1] weight:(split[2] as integer) \
|
||||
value:(split[3] as integer)
|
||||
appendifunique globalItems itemstruct
|
||||
)
|
||||
|
||||
while usedMass < 400 do
|
||||
(
|
||||
local item = chooseBestItem maximumweight:(400-usedMass) items:(globalItems)
|
||||
if item != 0 then
|
||||
(
|
||||
deleteitem globalItems (item[2])
|
||||
appendifunique neededItems item[1]
|
||||
usedMass += item[1].weight
|
||||
) else exit
|
||||
)
|
||||
for i in neededitems do
|
||||
(
|
||||
format "Item name: %, weight: %, value:%\n" i.item i.weight i.value
|
||||
totalValue += i.value
|
||||
)
|
||||
format "Total mass: %, Total Value: %\n" usedMass totalValue
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
Item name: water, weight: 153, value:200
|
||||
Item name: sandwich, weight: 50, value:160
|
||||
Item name: map, weight: 9, value:150
|
||||
Item name: note-case, weight: 22, value:80
|
||||
Item name: waterproof overclothes, weight: 43, value:75
|
||||
Item name: suntan cream, weight: 11, value:70
|
||||
Item name: waterproof trousers, weight: 42, value:70
|
||||
Item name: glucose, weight: 15, value:60
|
||||
Item name: banana, weight: 27, value:60
|
||||
Item name: socks, weight: 4, value:50
|
||||
Item name: compass, weight: 13, value:35
|
||||
Item name: sunglasses, weight: 7, value:20
|
||||
OK
|
||||
Total mass: 396, Total Value: 1030
|
||||
OK
|
||||
29
Task/Knapsack-problem-0-1/Maple/knapsack-problem-0-1.maple
Normal file
29
Task/Knapsack-problem-0-1/Maple/knapsack-problem-0-1.maple
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
weights := [9,13,153,50,15,68,27,39,23,52,11,32,24,48,73,42,43,22,7,18,4,30]:
|
||||
vals := [150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,50,10]:
|
||||
items := ["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"]:
|
||||
acc := Array(1..numelems(vals)+1,1..400+1,1,fill=0):
|
||||
len := numelems(weights):
|
||||
for i from 2 to len+1 do #number of items picked + 1
|
||||
for j from 2 to 401 do #weight capacity left + 1
|
||||
if weights[i-1] > j-1 then
|
||||
acc[i,j] := acc[i-1, j]:
|
||||
else
|
||||
acc[i,j] := max(acc[i-1,j], acc[i-1, j-weights[i-1]]+vals[i-1]):
|
||||
end if:
|
||||
end do:
|
||||
end do:
|
||||
printf("Total Value is %d\n", acc[len+1, 401]):
|
||||
count := 0:
|
||||
i := len+1:
|
||||
j := 401:
|
||||
while (i>1 and j>1) do
|
||||
if acc[i,j] <> acc[i-1,j] then
|
||||
printf("Item: %s\n", items[i-1]):
|
||||
count := count+weights[i-1]:
|
||||
j := j-weights[i-1]:
|
||||
i := i-1:
|
||||
else
|
||||
i := i-1:
|
||||
end if:
|
||||
end do:
|
||||
printf("Total Weight is %d\n", count):
|
||||
|
|
@ -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}}
|
||||
46
Task/Knapsack-problem-0-1/Mathprog/knapsack-problem-0-1.math
Normal file
46
Task/Knapsack-problem-0-1/Mathprog/knapsack-problem-0-1.math
Normal file
|
|
@ -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;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
%Knapsack 0/1. Nigel Galloway: October 5th., 2020.
|
||||
enum Items={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};
|
||||
array[Items] of int: weight=[9,13,153,50,15,68,27,39,23,52,11,32,24,48,73,42,43,22,7,18,4,30];
|
||||
array[Items] of int: value =[150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,50,10];
|
||||
int: maxWeight=400;
|
||||
var int: wTaken=sum(n in take)(weight[n]);
|
||||
var int: wValue=sum(n in take)(value[n]);
|
||||
var set of Items: take;
|
||||
constraint wTaken <= maxWeight;
|
||||
solve maximize wValue;
|
||||
output["Take "++show(take)++"\nTotal Weight=\(wTaken) Total Value=\(wValue)"]
|
||||
82
Task/Knapsack-problem-0-1/Nim/knapsack-problem-0-1.nim
Normal file
82
Task/Knapsack-problem-0-1/Nim/knapsack-problem-0-1.nim
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# Knapsack. Recursive algorithm.
|
||||
|
||||
import algorithm
|
||||
import sequtils
|
||||
import tables
|
||||
|
||||
# Description of an item.
|
||||
type Item = tuple[name: string; weight, value: int]
|
||||
|
||||
# List of available items.
|
||||
const Items: seq[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)
|
||||
]
|
||||
|
||||
type
|
||||
|
||||
# Item numbers (used rather than items themselves).
|
||||
Number = range[0..Items.high]
|
||||
|
||||
# Chosen items and their total value.
|
||||
Choice = tuple[nums: set[Number]; weight, value: int]
|
||||
|
||||
# Cache used to speed up the search.
|
||||
var cache: Table[tuple[num, weight: int], Choice]
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc select(num, weightLimit: int): Choice =
|
||||
## Find the best choice starting from item at index "num".
|
||||
|
||||
if num < 0 or weightLimit == 0:
|
||||
return
|
||||
|
||||
if (num, weightLimit) in cache:
|
||||
return cache[(num, weightLimit)]
|
||||
|
||||
let weight = Items[num].weight
|
||||
if weight > weightLimit:
|
||||
return select(num - 1, weightLimit)
|
||||
|
||||
# Try by leaving this item and selecting among remaining items.
|
||||
result = select(num - 1, weightLimit)
|
||||
|
||||
# Try by taking this item and completing with some remaining items.
|
||||
var result1 = select(num - 1, weightLimit - weight)
|
||||
inc result1.value, Items[num].value
|
||||
|
||||
# Select the best choice (giving the greater value).
|
||||
if result1.value > result.value:
|
||||
result = (result1.nums + {num.Number}, result1.weight + weight, result1.value)
|
||||
|
||||
cache[(num, weightLimit)] = result
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
let (nums, weight, value) = select(Items.high, 400)
|
||||
echo "List of items:"
|
||||
for num in sorted(toSeq(nums)):
|
||||
echo "– ", Items[num].name
|
||||
echo ""
|
||||
echo "Total weight: ", weight
|
||||
echo "Total value: ", value
|
||||
41
Task/Knapsack-problem-0-1/OCaml/knapsack-problem-0-1.ocaml
Normal file
41
Task/Knapsack-problem-0-1/OCaml/knapsack-problem-0-1.ocaml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
let 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;
|
||||
]
|
||||
|
||||
let comb =
|
||||
List.fold_left (fun acc x -> let acc2 = List.rev_map (fun li -> x::li) acc in
|
||||
List.rev_append acc acc2) [[]]
|
||||
|
||||
let score =
|
||||
List.fold_left (fun (w_tot,v_tot) (_,w,v) -> (w + w_tot, v + v_tot)) (0,0)
|
||||
|
||||
let () =
|
||||
let combs = comb items in
|
||||
let vals = List.rev_map (fun this -> (score this, this)) combs in
|
||||
let poss = List.filter (fun ((w,_), _) -> w <= 400) vals in
|
||||
let _, res = List.fold_left (fun (((_,s1),_) as v1) (((_,s2),_) as v2) ->
|
||||
if s2 > s1 then v2 else v1)
|
||||
(List.hd poss) (List.tl poss) in
|
||||
List.iter (fun (name,_,_) -> print_endline name) res;
|
||||
;;
|
||||
64
Task/Knapsack-problem-0-1/Oz/knapsack-problem-0-1.oz
Normal file
64
Task/Knapsack-problem-0-1/Oz/knapsack-problem-0-1.oz
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
declare
|
||||
%% maps items to pairs of Weight(hectogram) and Value
|
||||
Problem = knapsack('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
|
||||
)
|
||||
|
||||
%% item -> Weight
|
||||
Weights = {Record.map Problem fun {$ X} X.1 end}
|
||||
%% item -> Value
|
||||
Values = {Record.map Problem fun {$ X} X.2 end}
|
||||
|
||||
proc {Knapsack Solution}
|
||||
%% a solution maps items to finite domain variables
|
||||
%% with the domain {0,1}
|
||||
Solution = {Record.map Problem fun {$ _} {FD.int 0#1} end}
|
||||
%% no more than 400 hectograms
|
||||
{FD.sumC Weights Solution '=<:' 400}
|
||||
%% search through valid solutions
|
||||
{FD.distribute naive Solution}
|
||||
end
|
||||
|
||||
proc {PropagateLargerValue Old New}
|
||||
%% propagate that new solutions must yield a higher value
|
||||
%% than previously found solutions (essential for performance)
|
||||
{FD.sumC Values New '>:' {Value Old}}
|
||||
end
|
||||
|
||||
fun {Value Candidate}
|
||||
{Record.foldL {Record.zip Candidate Values Number.'*'} Number.'+' 0}
|
||||
end
|
||||
|
||||
fun {Weight Candidate}
|
||||
{Record.foldL {Record.zip Candidate Weights Number.'*'} Number.'+' 0}
|
||||
end
|
||||
|
||||
[Best] = {SearchBest Knapsack PropagateLargerValue}
|
||||
in
|
||||
{System.showInfo "Items: "}
|
||||
{ForAll
|
||||
{Record.arity {Record.filter Best fun {$ T} T == 1 end}}
|
||||
System.showInfo}
|
||||
{System.printInfo "\n"}
|
||||
{System.showInfo "total value: "#{Value Best}}
|
||||
{System.showInfo "total weight: "#{Weight Best}}
|
||||
100
Task/Knapsack-problem-0-1/PHP/knapsack-problem-0-1-1.php
Normal file
100
Task/Knapsack-problem-0-1/PHP/knapsack-problem-0-1-1.php
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#########################################################
|
||||
# 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
|
||||
#
|
||||
#########################################################
|
||||
|
||||
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);
|
||||
|
||||
if ($w[$i] > $aW) { // Does it return too many?
|
||||
|
||||
$m[$i][$aW] = $without_i; // Memo without including this one
|
||||
$m['picked'][$i][$aW] = $without_PI; // and a blank array entry...
|
||||
return array($without_i, $without_PI); // and return it
|
||||
|
||||
} else {
|
||||
|
||||
// Get the result of the next branch (WITH this one picked, so available weight is reduced)
|
||||
list ($with_i,$with_PI) = knapSolveFast2($w, $v, ($i-1), ($aW - $w[$i]), $m);
|
||||
$with_i += $v[$i]; // ..and add the value of this one..
|
||||
|
||||
// Get the greater of WITH or WITHOUT
|
||||
if ($with_i > $without_i) {
|
||||
$res = $with_i;
|
||||
$picked = $with_PI;
|
||||
array_push($picked,$i);
|
||||
} else {
|
||||
$res = $without_i;
|
||||
$picked = $without_PI;
|
||||
}
|
||||
|
||||
$m[$i][$aW] = $res; // Store it in the memo
|
||||
$m['picked'][$i][$aW] = $picked; // and store the picked item
|
||||
return array ($res,$picked); // and then return it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$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);
|
||||
|
||||
# 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>";
|
||||
$totalVal = $totalWt = 0;
|
||||
foreach($pickedItems as $key) {
|
||||
$totalVal += $v4[$key];
|
||||
$totalWt += $w4[$key];
|
||||
echo "<tr><td>".$items4[$key]."</td><td>".$v4[$key]."</td><td>".$w4[$key]."</td></tr>";
|
||||
}
|
||||
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>";
|
||||
88
Task/Knapsack-problem-0-1/Pascal/knapsack-problem-0-1.pas
Normal file
88
Task/Knapsack-problem-0-1/Pascal/knapsack-problem-0-1.pas
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
program project1;
|
||||
uses
|
||||
sysutils, classes, math;
|
||||
|
||||
const
|
||||
MaxWeight = 400;
|
||||
N = 22;
|
||||
|
||||
type
|
||||
TMaxArray = array[0..N, 0..MaxWeight] of integer;
|
||||
|
||||
TEquipment = record
|
||||
Description : string;
|
||||
Weight : integer;
|
||||
Value : integer;
|
||||
end;
|
||||
|
||||
TEquipmentList = array[1..N] of TEquipment;
|
||||
|
||||
var
|
||||
M:TMaxArray;
|
||||
MaxValue, WeightLeft, i, j : integer;
|
||||
S,KnapSack:TStringList;
|
||||
L:string;
|
||||
List:TEquipmentList;
|
||||
|
||||
begin
|
||||
//Put all the items into an array called List
|
||||
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,suntancreme,11,70,camera,32,30,T-shirt,24,15,trousers,48,40,umbrella,73,40,' +
|
||||
'waterprooftrousers,42,70,waterproofoverclothes,43,75,notecase,22,80,sunglasses,7,20,towel,18,12,' +
|
||||
'socks,4,50,book,30,10';
|
||||
S:=TStringList.create;
|
||||
S.Commatext:=L;
|
||||
|
||||
For i:= 1 to N do
|
||||
begin
|
||||
List[i].Description:=S[3*i - 3];
|
||||
List[i].Weight:=strtoint(S[3*i - 2]);
|
||||
List[i].Value:=strtoint(S[3*i - 1]);
|
||||
end;
|
||||
|
||||
//create M, a table linking the possible items for each weight
|
||||
//and recording the value at that point
|
||||
for j := 0 to MaxWeight do
|
||||
M[0, j] := 0;
|
||||
|
||||
for i := 1 to N do
|
||||
for j := 0 to MaxWeight do
|
||||
if List[i].weight > j then
|
||||
M[i, j] := M[i-1, j]
|
||||
else
|
||||
M[i, j] := max(M[i-1, j], M[i-1, j-List[i].weight] + List[i].value);
|
||||
|
||||
//get the highest total value by testing every value in table M
|
||||
MaxValue := 0;
|
||||
for i:=1 to N do
|
||||
for j:= 0 to MaxWeight do
|
||||
If M[i,j] > MaxValue then
|
||||
MaxValue := m[i,j];
|
||||
|
||||
writeln('Highest total value : ',MaxValue);
|
||||
|
||||
//Work backwards through the items to find those items that go in the Knapsack (a stringlist)
|
||||
KnapSack := TStringList.create;
|
||||
WeightLeft := MaxWeight;
|
||||
For i:= N downto 1 do
|
||||
if M[i,WeightLeft] = MaxValue then
|
||||
if M[i-1, WeightLeft - List[i].Weight] = MaxValue - List[i].Value then
|
||||
begin
|
||||
Knapsack.add(List[i].Description + ' ' + IntToStr(List[i].Weight)+ ' ' + inttostr(List[i].Value));
|
||||
MaxValue := MaxValue - List[i].Value;
|
||||
WeightLeft := WeightLeft - List[i].Weight;
|
||||
end;
|
||||
|
||||
//Show the items in the knapsack
|
||||
writeln('Number of items : ',KnapSack.count);
|
||||
writeln('-------------------------');
|
||||
For i:= KnapSack.count-1 downto 0 do
|
||||
writeln(KnapSack[i]);
|
||||
|
||||
KnapSack.free;
|
||||
S.free;
|
||||
writeln('-------------------------');
|
||||
writeln('done');
|
||||
readln;
|
||||
end.
|
||||
59
Task/Knapsack-problem-0-1/Perl/knapsack-problem-0-1.pl
Normal file
59
Task/Knapsack-problem-0-1/Perl/knapsack-problem-0-1.pl
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
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 [map undef, 0 .. 1+$max_weight], 0 .. $#name;
|
||||
|
||||
sub optimal {
|
||||
my ($i, $w) = @_;
|
||||
return [0, []] if $i < 0;
|
||||
return $p[$i][$w] if $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 $solution = optimal($#name, $max_weight);
|
||||
print "$solution->[0]: @{$solution->[1]}\n";
|
||||
74
Task/Knapsack-problem-0-1/Phix/knapsack-problem-0-1.phix
Normal file
74
Task/Knapsack-problem-0-1/Phix/knapsack-problem-0-1.phix
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\knapsack0.exw</span>
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
|
||||
<span style="color: #004080;">bool</span> <span style="color: #000000;">terminate</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
|
||||
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">attempts</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">knapsack</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">goodies</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">at</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">={})</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{?,</span><span style="color: #000000;">witem</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pitem</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">goodies</span><span style="color: #0000FF;">[</span><span style="color: #000000;">at</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">witem</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">?</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">chosen</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">n</span>
|
||||
<span style="color: #000000;">points</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">pitem</span> <span style="color: #000080;font-style:italic;">-- increase value</span>
|
||||
<span style="color: #000000;">weight</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">witem</span> <span style="color: #000080;font-style:italic;">-- decrease weight left</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">at</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">goodies</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">attempts</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">or</span> <span style="color: #000000;">res</span><span style="color: #0000FF;"><{</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">terminate</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000080;font-style:italic;">-- while n>=0 do -- full exhaustive search</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #008080;">not</span> <span style="color: #000000;">terminate</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- optimised</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">knapsack</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">goodies</span><span style="color: #0000FF;">,</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #000000;">at</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #000000;">n</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">chosen</span><span style="color: #0000FF;">[$]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
|
||||
<span style="color: #000000;">points</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">pitem</span>
|
||||
<span style="color: #000000;">weight</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">witem</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">byweightedvalue</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- sort by weight/value</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]/</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">],</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]/</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #000080;font-style:italic;">-- nb other sort orders break the optimisation</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">goodies</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">byweightedvalue</span><span style="color: #0000FF;">,{</span>
|
||||
<span style="color: #000080;font-style:italic;">-- item weight value</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"map"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">150</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"compass"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">35</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"water"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">153</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">200</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"sandwich"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">50</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">160</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"glucose"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">60</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"tin"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">68</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">45</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"banana"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">27</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">60</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"apple"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">39</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">40</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"cheese"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">23</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">30</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"beer"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">52</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"suntan cream"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">70</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"camera"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">30</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"T-shirt"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">24</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"trousers"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">48</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"umbrella"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">73</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">40</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"waterproof trousers"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">42</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">70</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"waterproof overclothes"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">43</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">75</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"note-case"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">22</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">80</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"sunglasses"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">20</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"towel"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">18</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"socks"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">50</span> <span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"book"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">30</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span> <span style="color: #0000FF;">}})</span>
|
||||
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #000000;">counts</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">knapsack</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">goodies</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">400</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Value %d, weight %g [%d attempts, %3.2fs]:\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">400</span><span style="color: #0000FF;">-</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #000000;">attempts</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">counts</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">goodies</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
69
Task/Knapsack-problem-0-1/Picat/knapsack-problem-0-1.picat
Normal file
69
Task/Knapsack-problem-0-1/Picat/knapsack-problem-0-1.picat
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import mip,util.
|
||||
|
||||
go =>
|
||||
items(AllItems,MaxTotalWeight),
|
||||
[Items,Weights,Values] = transpose(AllItems),
|
||||
|
||||
knapsack_01(Weights,Values,MaxTotalWeight, X,TotalWeight,TotalValues),
|
||||
print_solution(Items,Weights,Values, X,TotalWeight,TotalValues),
|
||||
nl.
|
||||
|
||||
% Print the solution
|
||||
print_solution(Items,Weights,Values, X,TotalWeight,TotalValues) =>
|
||||
println("\nThese are the items to pick:"),
|
||||
println(" Item Weight Value"),
|
||||
|
||||
foreach(I in 1..Items.len)
|
||||
if X[I] == 1 then
|
||||
printf("* %-25w %3d %3d\n", Items[I],Weights[I], Values[I])
|
||||
end
|
||||
end,
|
||||
nl,
|
||||
|
||||
printf("Total weight: %d\n", TotalWeight),
|
||||
printf("Total value: %d\n", TotalValues),
|
||||
nl.
|
||||
|
||||
% Solve the knapsack problem
|
||||
knapsack_01(Weights,Values,MaxTotalWeight, X,TotalWeight,TotalValues) =>
|
||||
NumItems = length(Weights),
|
||||
|
||||
% Variables
|
||||
X = new_list(NumItems),
|
||||
X :: 0..1,
|
||||
|
||||
% Constraints
|
||||
scalar_product(Weights,X,TotalWeight),
|
||||
scalar_product(Values,X,TotalValues),
|
||||
TotalWeight #=< MaxTotalWeight,
|
||||
|
||||
% Search
|
||||
Vars = X ++ [TotalWeight, TotalValues],
|
||||
solve($[max(TotalValues)], Vars).
|
||||
|
||||
% data
|
||||
items(Items,MaxTotalWeight) =>
|
||||
% Item Weight Value
|
||||
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],
|
||||
["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]],
|
||||
MaxTotalWeight = 400.
|
||||
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 (cons W Lst)
|
||||
(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).
|
||||
116
Task/Knapsack-problem-0-1/PureBasic/knapsack-problem-0-1.basic
Normal file
116
Task/Knapsack-problem-0-1/PureBasic/knapsack-problem-0-1.basic
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
Structure item
|
||||
name.s
|
||||
weight.i ;units are dekagrams (dag)
|
||||
Value.i
|
||||
EndStructure
|
||||
|
||||
Structure memo
|
||||
Value.i
|
||||
List picked.i()
|
||||
EndStructure
|
||||
|
||||
Global itemCount = 0 ;this will be increased as needed to match count
|
||||
Global Dim items.item(itemCount)
|
||||
|
||||
Procedure addItem(name.s, weight, Value)
|
||||
If itemCount >= ArraySize(items())
|
||||
Redim items.item(itemCount + 10)
|
||||
EndIf
|
||||
With items(itemCount)
|
||||
\name = name
|
||||
\weight = weight
|
||||
\Value = Value
|
||||
EndWith
|
||||
itemCount + 1
|
||||
EndProcedure
|
||||
|
||||
;build item list
|
||||
addItem("map", 9, 150)
|
||||
addItem("compass", 13, 35)
|
||||
addItem("water", 153, 200)
|
||||
addItem("sandwich", 50, 160)
|
||||
addItem("glucose", 15, 60)
|
||||
addItem("tin", 68, 45)
|
||||
addItem("banana", 27, 60)
|
||||
addItem("apple", 39, 40)
|
||||
addItem("cheese", 23, 30)
|
||||
addItem("beer", 52, 10)
|
||||
addItem("suntan cream", 11, 70)
|
||||
addItem("camera", 32, 30)
|
||||
addItem("t-shirt", 24, 15)
|
||||
addItem("trousers", 48, 10)
|
||||
addItem("umbrella", 73, 40)
|
||||
addItem("waterproof trousers", 42, 70)
|
||||
addItem("waterproof overclothes", 43, 75)
|
||||
addItem("note-case", 22, 80)
|
||||
addItem("sunglasses", 7, 20)
|
||||
addItem("towel", 18, 12)
|
||||
addItem("socks", 4, 50)
|
||||
addItem("book", 30, 10)
|
||||
|
||||
Procedure knapsackSolveFast(Array item.item(1), i, aw, Map m.memo())
|
||||
Protected.memo without_i, with_i, result, *tmp, memoIndex.s = Hex((i << 16) + aw, #PB_Long)
|
||||
If FindMapElement(m(), memoIndex)
|
||||
ProcedureReturn @m()
|
||||
Else
|
||||
If i = 0
|
||||
If item(0)\weight <= aw
|
||||
;item fits
|
||||
m(memoIndex)\Value = item(0)\Value ;memo this item's value
|
||||
AddElement(m()\picked())
|
||||
m()\picked() = 0 ;memo item's index also
|
||||
Else
|
||||
;item doesn't fit, memo a zero Value
|
||||
m(memoIndex)\Value = 0
|
||||
EndIf
|
||||
ProcedureReturn @m()
|
||||
EndIf
|
||||
|
||||
;test if a greater value results with or without item included
|
||||
*tmp = knapsackSolveFast(item(), i - 1, aw, m()) ;find value without this item
|
||||
CopyStructure(*tmp, @without_i, memo)
|
||||
If item(i)\weight > aw
|
||||
;item weighs too much, memo without including this item
|
||||
m(memoIndex) = without_i
|
||||
ProcedureReturn @m()
|
||||
Else
|
||||
*tmp = knapsackSolveFast(item(), i - 1, aw - item(i)\weight, m()) ;find value when item is included
|
||||
CopyStructure(*tmp, @with_i, memo)
|
||||
with_i\Value + item(i)\Value
|
||||
AddElement(with_i\picked())
|
||||
with_i\picked() = i ;add item to with's picked list
|
||||
EndIf
|
||||
|
||||
;set the result to the larger value
|
||||
If with_i\Value > without_i\Value
|
||||
result = with_i
|
||||
Else
|
||||
result = without_i
|
||||
EndIf
|
||||
|
||||
m(memoIndex) = result ;memo the result
|
||||
ProcedureReturn @m()
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
Procedure.s knapsackSolve(Array item.item(1), i, aw)
|
||||
Protected *result.memo, output.s, totalWeight
|
||||
NewMap m.memo()
|
||||
*result = knapsackSolveFast(item(), i, aw, m())
|
||||
output = "Knapsack:" + #CRLF$
|
||||
ForEach *result\picked()
|
||||
output + LSet(item(*result\picked())\name, 24) + RSet(Str(item(*result\picked())\weight), 5) + RSet(Str(item(*result\picked())\Value), 5) + #CRLF$
|
||||
totalWeight + item(*result\picked())\weight
|
||||
Next
|
||||
output + LSet("TOTALS:", 24) + RSet(Str(totalWeight), 5) + RSet(Str(*result\Value), 5)
|
||||
ProcedureReturn output
|
||||
EndProcedure
|
||||
|
||||
If OpenConsole()
|
||||
#maxWeight = 400
|
||||
Define *result.memo
|
||||
PrintN(knapsackSolve(items(), itemCount - 1, #maxWeight))
|
||||
|
||||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
|
||||
CloseConsole()
|
||||
EndIf
|
||||
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))
|
||||
36
Task/Knapsack-problem-0-1/Python/knapsack-problem-0-1-3.py
Normal file
36
Task/Knapsack-problem-0-1/Python/knapsack-problem-0-1-3.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
def total_value(items, max_weight):
|
||||
return sum([x[2] for x in items]) if sum([x[1] for x in items]) <= max_weight else 0
|
||||
|
||||
cache = {}
|
||||
def solve(items, max_weight):
|
||||
if not items:
|
||||
return ()
|
||||
if (items,max_weight) not in cache:
|
||||
head = items[0]
|
||||
tail = items[1:]
|
||||
include = (head,) + solve(tail, max_weight - head[1])
|
||||
dont_include = solve(tail, max_weight)
|
||||
if total_value(include, max_weight) > total_value(dont_include, max_weight):
|
||||
answer = include
|
||||
else:
|
||||
answer = dont_include
|
||||
cache[(items,max_weight)] = answer
|
||||
return cache[(items,max_weight)]
|
||||
|
||||
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),
|
||||
)
|
||||
max_weight = 400
|
||||
|
||||
solution = solve(items, max_weight)
|
||||
print "items:"
|
||||
for x in solution:
|
||||
print x[0]
|
||||
print "value:", total_value(solution, max_weight)
|
||||
print "weight:", sum([x[1] for x in solution])
|
||||
30
Task/Knapsack-problem-0-1/Python/knapsack-problem-0-1-4.py
Normal file
30
Task/Knapsack-problem-0-1/Python/knapsack-problem-0-1-4.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
n=5; N=n+1; G=5; a=2**N # KNAPSACK 0-1 DANILIN
|
||||
L=[];C=[];e=[];j=[];q=[];s=[] # rextester.com/BCKP19591
|
||||
d=[];L=[1]*n;C=[1]*n;e=[1]*a
|
||||
j=[1]*n;q=[0]*a;s=[0]*a;d=[0]*a
|
||||
|
||||
from random import randint
|
||||
for i in range(0,n):
|
||||
L[i]=randint(1,3)
|
||||
C[i]=10+randint(1,9)
|
||||
print(i+1,L[i],C[i])
|
||||
print()
|
||||
|
||||
for h in range(a-1,(a-1)//2,-1):
|
||||
b=str(bin(h))
|
||||
e[h]=b[3:len(b)]
|
||||
|
||||
for k in range (n):
|
||||
j[k]=int(e[h][k])
|
||||
q[h]=q[h]+L[k]*j[k]*C[k]
|
||||
d[h]=d[h]+L[k]*j[k]
|
||||
|
||||
if d[h]<= G:
|
||||
print(e[h], G, d[h], q[h])
|
||||
print()
|
||||
|
||||
max=0; m=1
|
||||
for i in range(a):
|
||||
if d[i]<=G and q[i]>max:
|
||||
max=q[i]; m=i
|
||||
print (d[m], q[m], e[m])
|
||||
24
Task/Knapsack-problem-0-1/QB64/knapsack-problem-0-1.qb64
Normal file
24
Task/Knapsack-problem-0-1/QB64/knapsack-problem-0-1.qb64
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Open "knapsack.txt" For Output As #1
|
||||
N=7: L=5: a = 2^(N+1): Randomize Timer 'knapsack.bas DANILIN
|
||||
Dim L(N), C(N), j(N), q(a), q$(a), d(a)
|
||||
|
||||
For m=a-1 To (a-1)/2 Step -1: g=m: Do ' cipher 0-1
|
||||
q$(m)=LTrim$(Str$(g Mod 2))+q$(m)
|
||||
g=g\2: Loop Until g=0
|
||||
q$(m)=Mid$(q$(m), 2, Len(q$(m)))
|
||||
Next
|
||||
|
||||
For i=1 To N: L(i)=Int(Rnd*3+1) ' mass & cost
|
||||
C(i)=10+Int(Rnd*9): Print #1, i, L(i), C(i): Next ' origin
|
||||
|
||||
For h=a-1 To (a-1)/2 Step -1
|
||||
For k=1 To N: j(k)=Val(Mid$(q$(h), k, 1)) ' j() = cipher
|
||||
q(h)=q(h)+L(k)*j(k)*C(k) ' 0 or 1
|
||||
d(h)=d(h)+L(k)*j(k)
|
||||
Next
|
||||
If d(h) <= L Then Print #1, d(h), q(h), q$(h)
|
||||
Next
|
||||
max=0: m=1: For i=1 To a
|
||||
If d(i)<=L Then If q(i) > max Then max=q(i): m=i
|
||||
Next
|
||||
Print #1,: Print #1, d(m), q(m), q$(m): End
|
||||
36
Task/Knapsack-problem-0-1/QBasic/knapsack-problem-0-1.basic
Normal file
36
Task/Knapsack-problem-0-1/QBasic/knapsack-problem-0-1.basic
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
N = 7: G = 5: a = 2 ^ (N + 1) ' Author: DANILIN & Editor: Jjuanhdez or Unknow
|
||||
RANDOMIZE TIMER
|
||||
DIM L(N), C(N), j(N), q(a), d(a), q$(a)
|
||||
|
||||
FOR i = a - 1 TO (a - 1) \ 2 STEP -1
|
||||
k = i
|
||||
DO ' cipher 0-1
|
||||
q$(i) = LTRIM$(STR$(k MOD 2)) + q$(i)
|
||||
k = INT(k / 2)
|
||||
LOOP UNTIL k = 0
|
||||
q$(i) = MID$(q$(i), 2, LEN(q$(i)))
|
||||
NEXT i
|
||||
|
||||
PRINT " # Mass Cost"
|
||||
FOR i = 1 TO N
|
||||
L(i) = INT(RND * 3 + 1)' mass & cost
|
||||
C(i) = 10 + INT(RND * 9)
|
||||
PRINT i, L(i), C(i)
|
||||
NEXT i ' origin
|
||||
|
||||
PRINT CHR$(10) + "Mass Cost Chifer"
|
||||
FOR h = a - 1 TO (a - 1) / 2 STEP -1
|
||||
FOR k = 1 TO N
|
||||
j(k) = VAL(MID$(q$(h), k, 1)) ' j() = cipher
|
||||
q(h) = q(h) + L(k) * j(k) * C(k) ' 0 or 1
|
||||
d(h) = d(h) + L(k) * j(k)
|
||||
NEXT k
|
||||
IF d(h) <= G THEN PRINT d(h), q(h), q$(h)
|
||||
NEXT h
|
||||
|
||||
PRINT CHR$(10) + "Mass MAX Chifer"
|
||||
max = 0: h = 1
|
||||
FOR i = 1 TO a
|
||||
IF d(i) <= G AND q(i) > max THEN max = q(i): h = i
|
||||
NEXT i
|
||||
PRINT d(h), q(h), q$(h)
|
||||
78
Task/Knapsack-problem-0-1/R/knapsack-problem-0-1-1.r
Normal file
78
Task/Knapsack-problem-0-1/R/knapsack-problem-0-1-1.r
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
Full_Data<-structure(list(item = c("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"), weigth = c(9, 13, 153, 50, 15, 68, 27, 39,
|
||||
23, 52, 11, 32, 24, 48, 73, 42, 43, 22, 7, 18, 4, 30), value = c(150,
|
||||
35, 200, 160, 60, 45, 60, 40, 30, 10, 70, 30, 15, 10, 40, 70,
|
||||
75, 80, 20, 12, 50, 10)), .Names = c("item", "weigth", "value"
|
||||
), row.names = c(NA, 22L), class = "data.frame")
|
||||
|
||||
|
||||
Bounded_knapsack<-function(Data,W)
|
||||
{
|
||||
K<-matrix(NA,nrow=W+1,ncol=dim(Data)[1]+1)
|
||||
0->K[1,]->K[,1]
|
||||
matrix_item<-matrix('',nrow=W+1,ncol=dim(Data)[1]+1)
|
||||
for(j in 1:dim(Data)[1])
|
||||
{
|
||||
for(w in 1:W)
|
||||
{
|
||||
wj<-Data$weigth[j]
|
||||
item<-Data$item[j]
|
||||
value<-Data$value[j]
|
||||
if( wj > w )
|
||||
{
|
||||
K[w+1,j+1]<-K[w+1,j]
|
||||
matrix_item[w+1,j+1]<-matrix_item[w+1,j]
|
||||
}
|
||||
else
|
||||
{
|
||||
if( K[w+1,j] >= K[w+1-wj,j]+value )
|
||||
{
|
||||
K[w+1,j+1]<-K[w+1,j]
|
||||
matrix_item[w+1,j+1]<-matrix_item[w+1,j]
|
||||
}
|
||||
else
|
||||
{
|
||||
K[w+1,j+1]<-K[w+1-wj,j]+value
|
||||
matrix_item[w+1,j+1]<-item
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(list(K=K,Item=matrix_item))
|
||||
}
|
||||
|
||||
backtracking<-function(knapsack, Data)
|
||||
{
|
||||
W<-dim(knapsack$K)[1]
|
||||
itens<-c()
|
||||
col<-dim(knapsack$K)[2]
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
while(selected_item!='')
|
||||
{
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
if(selected_item!='')
|
||||
{
|
||||
selected_item_value<-Data[Data$item == selected_item,]
|
||||
if(-knapsack$K[W - selected_item_value$weigth,col-1]+knapsack$K[W,col]==selected_item_value$value)
|
||||
{
|
||||
W <- W - selected_item_value$weigth
|
||||
itens<-c(itens,selected_item)
|
||||
}
|
||||
col <- col - 1
|
||||
}
|
||||
}
|
||||
return(itens)
|
||||
}
|
||||
|
||||
print_output<-function(Data,W)
|
||||
{
|
||||
Bounded_knapsack(Data,W)->Knap
|
||||
backtracking(Knap, Data)->Items
|
||||
output<-paste('You must carry:', paste(Items, sep = ', '), sep=' ' )
|
||||
return(output)
|
||||
}
|
||||
|
||||
print_output(Full_Data, 400)
|
||||
12
Task/Knapsack-problem-0-1/R/knapsack-problem-0-1-2.r
Normal file
12
Task/Knapsack-problem-0-1/R/knapsack-problem-0-1-2.r
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[1] "You must carry: socks"
|
||||
[2] "You must carry: sunglasses"
|
||||
[3] "You must carry: note-case"
|
||||
[4] "You must carry: waterproof_overclothes"
|
||||
[5] "You must carry: waterproof_trousers"
|
||||
[6] "You must carry: suntan_cream"
|
||||
[7] "You must carry: banana"
|
||||
[8] "You must carry: glucose"
|
||||
[9] "You must carry: sandwich"
|
||||
[10] "You must carry: water"
|
||||
[11] "You must carry: compass"
|
||||
[12] "You must carry: map"
|
||||
102
Task/Knapsack-problem-0-1/REXX/knapsack-problem-0-1.rexx
Normal file
102
Task/Knapsack-problem-0-1/REXX/knapsack-problem-0-1.rexx
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*REXX program solves a knapsack problem (22 {+1} items with a weight restriction). */
|
||||
maxWeight=400 /*the maximum weight for the knapsack. */
|
||||
say 'maximum weight allowed for a knapsack:' commas(maxWeight); say
|
||||
call gen@ /*generate the @ array of choices. */
|
||||
call sortD /* sort " " " " " */
|
||||
call build /*build some associative arrays from @.*/
|
||||
call findBest /*go ye forth and find the best choises*/
|
||||
call results /*display the best choices for knapsack*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
build: do j=1 for obj; parse var @.j x w v . /*construct a list of knapsack choices.*/
|
||||
if w>maxWeight then iterate /*Is weight greater than max? Ignore.*/
|
||||
totW=totW + w; totV=totV + v /*add the totals (for output alignment)*/
|
||||
maxL=max(maxL, length(x) ) /*determine maximum width for an item. */
|
||||
#=#+1; i.#=x; w.#=w; v.#=v /*bump the number of items (choices). */
|
||||
end /*j*/ /* [↑] build indexable arrays of items*/
|
||||
maxL= maxL + maxL%4 + 4 /*extend width of name for shown table.*/
|
||||
maxW= max(maxW, length( commas(totW) ) ) /*find the maximum width for weight. */
|
||||
maxV= max(maxV, length( commas(totV) ) ) /* " " " " " value. */
|
||||
call hdr 'potential knapsack items' /*display a header for list of choices.*/
|
||||
do j=1 for obj; parse var @.j i w v . /*show all the choices in a nice format*/
|
||||
if w<=maxWeight then call show i,w,v /*Is weight within limits? Then show. */
|
||||
end /*j*/ /* [↑] display the list of choices. */
|
||||
$=0
|
||||
say; say 'number of allowable items: ' #
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
commas: procedure; parse arg _; n=_'.9'; #=123456789; b=verify(n, #, "M")
|
||||
e=verify(n, #'0', , verify(n, #"0.", 'M')) - 4; comma=','
|
||||
do j=e to b by -3; _=insert(comma, _, j); end /*j*/; return _
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
findBest: m=maxWeight /*items are in decreasing weight.*/
|
||||
do j1 =0 for #+1; w1 = w.j1 ; z1 = v.j1
|
||||
do j2 =j1 +(j1 >0) to #; if w.j2 +w1 >m then iterate j1 ; w2 =w1 +w.j2 ; z2 =z1 +v.j2
|
||||
do j3 =j2 +(j2 >0) to #; if w.j3 +w2 >m then iterate j2 ; w3 =w2 +w.j3 ; z3 =z2 +v.j3
|
||||
do j4 =j3 +(j3 >0) to #; if w.j4 +w3 >m then iterate j3 ; w4 =w3 +w.j4 ; z4 =z3 +v.j4
|
||||
do j5 =j4 +(j4 >0) to #; if w.j5 +w4 >m then iterate j4 ; w5 =w4 +w.j5 ; z5 =z4 +v.j5
|
||||
do j6 =j5 +(j5 >0) to #; if w.j6 +w5 >m then iterate j5 ; w6 =w5 +w.j6 ; z6 =z5 +v.j6
|
||||
do j7 =j6 +(j6 >0) to #; if w.j7 +w6 >m then iterate j6 ; w7 =w6 +w.j7 ; z7 =z6 +v.j7
|
||||
do j8 =j7 +(j7 >0) to #; if w.j8 +w7 >m then iterate j7 ; w8 =w7 +w.j8 ; z8 =z7 +v.j8
|
||||
do j9 =j8 +(j8 >0) to #; if w.j9 +w8 >m then iterate j8 ; w9 =w8 +w.j9 ; z9 =z8 +v.j9
|
||||
do j10=j9 +(j9 >0) to #; if w.j10+w9 >m then iterate j9 ; w10=w9 +w.j10; z10=z9 +v.j10
|
||||
do j11=j10+(j10>0) to #; if w.j11+w10>m then iterate j10; w11=w10+w.j11; z11=z10+v.j11
|
||||
do j12=j11+(j11>0) to #; if w.j12+w11>m then iterate j11; w12=w11+w.j12; z12=z11+v.j12
|
||||
do j13=j12+(j12>0) to #; if w.j13+w12>m then iterate j12; w13=w12+w.j13; z13=z12+v.j13
|
||||
do j14=j13+(j13>0) to #; if w.j14+w13>m then iterate j13; w14=w13+w.j14; z14=z13+v.j14
|
||||
do j15=j14+(j14>0) to #; if w.j15+w14>m then iterate j14; w15=w14+w.j15; z15=z14+v.j15
|
||||
do j16=j15+(j15>0) to #; if w.j16+w15>m then iterate j15; w16=w15+w.j16; z16=z15+v.j16
|
||||
do j17=j16+(j16>0) to #; if w.j17+w16>m then iterate j16; w17=w16+w.j17; z17=z16+v.j17
|
||||
do j18=j17+(j17>0) to #; if w.j18+w17>m then iterate j17; w18=w17+w.j18; z18=z17+v.j18
|
||||
do j19=j18+(j18>0) to #; if w.j19+w18>m then iterate j18; w19=w18+w.j19; z19=z18+v.j19
|
||||
do j20=j19+(j19>0) to #; if w.j20+w19>m then iterate j19; w20=w19+w.j20; z20=z19+v.j20
|
||||
do j21=j20+(j20>0) to #; if w.j21+w20>m then iterate j20; w21=w20+w.j21; z21=z20+v.j21
|
||||
do j22=j21+(j21>0) to #; if w.j22+w21>m then iterate j21; w22=w21+w.j22; z22=z21+v.j22
|
||||
if z22>$ then do; ?=; $=z22; do j=1 for 22; ?=? value("J"j); end /*j*/; end
|
||||
end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
gen@: @. = ; @.12= 'camera 32 30'
|
||||
@.1 = 'map 9 150' ; @.13= 'T-shirt 24 15'
|
||||
@.2 = 'compass 13 35' ; @.14= 'trousers 48 10'
|
||||
@.3 = 'water 153 200' ; @.15= 'umbrella 73 40'
|
||||
@.4 = 'sandwich 50 160' ; @.16= 'waterproof_trousers 42 70'
|
||||
@.5 = 'glucose 15 60' ; @.17= 'waterproof_overclothes 43 75'
|
||||
@.6 = 'tin 68 45' ; @.18= 'note-case 22 80'
|
||||
@.7 = 'banana 27 60' ; @.19= 'sunglasses 7 20'
|
||||
@.8 = 'apple 39 40' ; @.20= 'towel 18 12'
|
||||
@.9 = 'cheese 23 30' ; @.21= 'socks 4 50'
|
||||
@.10= 'beer 52 10' ; @.22= 'book 30 10'
|
||||
@.11= 'suntan_cream 11 70' ; @.23= 'anvil 100000 1'
|
||||
maxL = length('potential knapsack items') /*maximum width for the table items. */
|
||||
maxW = length('weight') /* " " " " " weights. */
|
||||
maxV = length('value') /* " " " " " values. */
|
||||
#=0; i.=; w.=0; v.=0; totW=0; totV=0 /*initialize some REX variables stuff. */
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
hdr: say; call show center(arg(1),maxL),center('weight',maxW),center("value",maxV)
|
||||
hdr2: call show copies('═',maxL),copies('═',maxW),copies('═',maxV); return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
results: do #; ?=strip( space(?), "L", 0); end /*h*/ /*elide leading zeroes*/
|
||||
bestC=?; bestW=0; totP=words(bestC); say; call hdr 'best choice'
|
||||
do j=1 for totP; _=word(bestC, j); _w=w._; _v=v._
|
||||
do k=j+1 to totP; __=word(bestC, k); if i._\==i.__ then leave
|
||||
j=j+1; w._=w._ + _w; v._=v._ + _v
|
||||
end /*k*/
|
||||
call show i._, w._, v._; bestW=bestW + w._
|
||||
end /*j*/
|
||||
call hdr2 ; say; @bestTK= 'best total knapsack'
|
||||
call show @bestTK 'weight' , bestW /*display a nicely formatted winner wt.*/
|
||||
call show @bestTK 'value' ,, $ /* " " " " winner val*/
|
||||
call show @bestTK 'items' ,,, totP /* " " " " pieces. */
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
show: parse arg _i,_w,_v,_p; say translate( left(_i,maxL,'─'), , "_") ,
|
||||
right(commas(_w),maxW) right(commas(_v),maxV) _p; return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
sortD: do j=1 while @.j\==''; y=word(@.j,2) /*process each of the knapsack choices.*/
|
||||
do k=j+1 while @.k\=='' /*find a possible heavier knapsack item*/
|
||||
?=word(@.k,2); if ?>y then do; _=@.k; @.k=@.j; @.j=_; y=?; end /*swap*/
|
||||
end /*k*/
|
||||
end /*j*/ /* [↑] sort choices by decreasing wt. */
|
||||
obj=j-1; return /*decrement J for the DO loop index*/
|
||||
56
Task/Knapsack-problem-0-1/Racket/knapsack-problem-0-1-1.rkt
Normal file
56
Task/Knapsack-problem-0-1/Racket/knapsack-problem-0-1-1.rkt
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#lang racket
|
||||
; An ITEM a list of three elements:
|
||||
; a name, a weight, and, a value
|
||||
|
||||
; A SOLUTION to a knapsack01 problems is a list of three elements:
|
||||
; the total value, the total weight, and, names of the items to bag
|
||||
|
||||
(define (add i s) ; add an item i to the solution s
|
||||
(match-define (list in iw iv) i)
|
||||
(match-define (list v w is) s)
|
||||
(list (+ v iv) (+ w iw) (cons in is)))
|
||||
|
||||
(define (knapsack max-weight items)
|
||||
; return a solution to the knapsack01 problem
|
||||
(define ht (make-hash)) ; (weight number-of-items) -> items
|
||||
(define (get w no-items) (hash-ref ht (list w no-items) #f))
|
||||
(define (update w is x) (hash-set! ht (list w (length is)) is) x)
|
||||
(define (knapsack1 left items)
|
||||
; return a solution to the (left, items) problem
|
||||
(cond
|
||||
; if there are no items, then bag no items:
|
||||
[(empty? items) (list 0 0 '())]
|
||||
; look up the best solution:
|
||||
[(or (get left (length items))
|
||||
; the solution haven't been cached, so we
|
||||
; must compute it and update the cache:
|
||||
(update
|
||||
left items
|
||||
(match items
|
||||
; let us name the first item
|
||||
[(cons (and (list i w v) x) more)
|
||||
; if the first item weighs more than the space left,
|
||||
; we simply find a solution, where it is omitted:
|
||||
(cond [(> w left) (knapsack left more)]
|
||||
; there is room for the first item, but
|
||||
; we need to choose the best solutions
|
||||
; between those with it and that without:
|
||||
[else
|
||||
(define without (knapsack left more))
|
||||
(define value-without (first without))
|
||||
(define with (knapsack (- left w) more))
|
||||
(define value-with (+ (first with) v))
|
||||
; choose the solutions with greatest value
|
||||
(if (> value-without value-with)
|
||||
without
|
||||
(add x with))])])))]))
|
||||
(knapsack1 max-weight items))
|
||||
|
||||
(knapsack 400
|
||||
'((map 9 150) ; 9 is weight, 150 is value
|
||||
(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)))
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue