Knapsack problem/0-1: Difference between revisions

No edit summary
 
(235 intermediate revisions by 78 users not shown)
Line 1:
{{task|Classic CS problems and programs}}[[Category:Memoization]]
[[Category:Memoization]]
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.
[[Category:Puzzles]]
{{omit from|GUISS}}
 
A tourist wants to make a good trip at the weekend with his friends.
Here is the list:
 
They will go to the mountains to see the wonders of nature, so he needs to pack well for the trip.
{| style="text-align: left; width: 80%;" border="4" cellpadding="2" cellspacing="2"
 
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);"
Line 56 ⟶ 68:
|}
 
<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.
The tourist can choose to take any combination of items from the list,
but only one of each item is available.
 
He may not cut or diminish the items, so he can only take whole units of any item.
'''Which items does the tourist carry in his knapsack so that their total weight does not exceed 400 dag [4 kg], and their total value is maximised?'''
 
 
;Task:
Show which items the tourist can carry in his knapsack so that their total weight does not
exceed 400 dag [4 kg], &nbsp; and their total value is maximized.
 
[dag = decagram = 10 grams]
 
 
;See also:
;Related tasks:
* [[Knapsack problem/Unbounded]]
* &nbsp; [[Knapsack problem/Bounded]]
* &nbsp; [[Knapsack problem/Unbounded]]
* &nbsp; [[Knapsack problem/Continuous]]
* &nbsp; [[A* search algorithm]]
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">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))</syntaxhighlight>
 
{{out}}
<pre>
Bagged the following items
banana
compass
glucose
map
note-case
sandwich
socks
sunglasses
suntan cream
water
waterproof overclothes
waterproof trousers
for a total value of 1030 and a total weight of 396
</pre>
 
=={{header|360 Assembly}}==
Non recurvive brute force version.
<syntaxhighlight lang="360asm">* 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</syntaxhighlight>
{{out}}
<pre>
n=22
map
compass
water
sandwich
glucose
banana
suntan cream
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
items=12 weight=396 value=1030
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
with Ada.Strings.Unbounded;
 
Line 175 ⟶ 406:
end if;
end loop;
end Knapsack_01;</langsyntaxhighlight>
{{out}}
<pre>
Line 196 ⟶ 427:
 
=={{header|APL}}==
<langsyntaxhighlight APLlang="apl"> ∇ 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)
Line 208 ⟶ 439:
[10] :end
[11] ret←⊃ret,⊂'TOTALS:' (+/2⊃¨ret)(+/3⊃¨ret)
∇</langsyntaxhighlight>
{{out}}
<pre>
Line 227 ⟶ 458:
 
Average runtime: 0.000168 seconds
</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# 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)
}
</syntaxhighlight>
{{out}}
<pre>
water
sandwich
map
note-case
waterproof overclothes
waterproof trousers
suntan cream
banana
glucose
socks
compass
sunglasses
items=12 (out of 22) weight=396 value=1030
</pre>
 
=={{header|BASIC}}==
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
{{trans|QB64}}
<syntaxhighlight lang="qbasic">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)</syntaxhighlight>
{{out}}
<pre>Same as QB64 entry.</pre>
 
==={{header|Yabasic}}===
{{trans|QB64}}
<syntaxhighlight lang="freebasic">N = 7 : G = 5 : a = 2^(N+1) ' Author: DANILIN & Editor: Jjuanhdez or Unknow
dim L(N), C(N), j(N), q(a), d(a), q$(a)
 
for i = a-1 to int((a-1)/2) step -1
k = i
repeat // cipher 0-1
q$(i) = ltrim$(str$(mod(k, 2))) + q$(i)
k = int(k / 2)
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(ran(3)) + 1 // mass & cost
C(i) = 10 + int(ran(9))
print i, chr$(9), L(i), chr$(9), 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 print d(h), chr$(9), q(h), chr$(9), q$(h)
next h
 
print chr$(10) + "Mass MAX Chifer"
maxx = 0 : h = 1
for i = 1 to a
if d(i) <= G and q(i) > maxx maxx = q(i) : h = i
next i
print d(h), chr$(9), q(h), chr$(9), q$(h)
end</syntaxhighlight>
{{out}}
<pre>Same as QB64 entry
https://jdoodle.com/iembed/v0/suj</pre>
 
=={{header|Batch File}}==
<syntaxhighlight lang="dos">
:: 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
</syntaxhighlight>
 
{{out}}
<pre>
List of things taken [12]: map socks suntancream glucose notecase sandwich sunglasses compass banana waterproofoverclothes waterprooftrousers water
Total Value: 1030 Total Weight: 396
</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> 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%</syntaxhighlight>
{{out}}
<pre>
map
compass
water
sandwich
glucose
banana
suntan cream
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
 
Total weight = 396
Total value = 1030
</pre>
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat">(knapsack=
( things
= (map.9.150)
Line 295 ⟶ 837:
& out$(!maxvalue.!sack));
!knapsack;</langsyntaxhighlight>
{{out}}
Output:
<langsyntaxhighlight lang="bracmat"> 1030
. map
compass
Line 309 ⟶ 851:
note-case
sunglasses
socks</langsyntaxhighlight>
 
=={{header|C}}==
 
Brute force takes 0.2 seconds-ish, so not motivated to do caching.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
 
typedef struct {
char * name;
int weight, value;
int value;
} item_t;
 
item_t itemitems[] = {
{"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},
{"suntancreamsuntan 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) {
#define n_items (sizeof(item)/sizeof(item_t))
int i, j, a, b, *mm, **m, *s;
 
mm = calloc((n + 1) * (w + 1), sizeof (int));
typedef struct {
m = malloc((n + 1) * sizeof (int *));
uint32_t bits; /* 32 bits, can solve up to 32 items */
m[0] = int valuemm;
for (i = 1; i <= n; i++) {
} solution;
m[i] = &mm[i * (w + 1)];
 
for (j = 0; j <= w; j++) {
 
if (items[i - 1].weight > j) {
void optimal(int weight, int idx, solution *s)
m[i][j] = m[i - 1][j];
{
solution v1, v2; }
if (idx < 0) else {
s->bitsa = sm[i ->value = 01][j];
returnb = m[i - 1][j - items[i - 1].weight] + items[i - 1].value;
m[i][j] = a > b ? a : b;
}
}
}
 
s = calloc(n, sizeof (int));
if (weight < item[idx].weight)
for (i = n, j = w; i > 0; return optimal(weight, idx i--) 1, s);{
if (m[i][j] > m[i - 1][j]) {
 
optimal(weight, idx s[i - 1,] &v1)= 1;
optimal(weight j -= itemitems[idx].weight, idxi - 1, &v2)].weight;
}
 
}
v2.value += item[idx].value;
v2.bits |= free(1 << idxmm);
free(m);
 
return s;
*s = (v1.value >= v2.value) ? v1 : v2;
}
 
int main () {
int i, n, tw = 0, tv = 0, *s;
{
n = sizeof (items) int/ i = 0, w =sizeof 0(item_t);
solution s = {0knapsack(items, n, 0}400);
for (i = 0; optimal(400,i n_items< -n; 1, &si++); {
if (s[i]) {
 
printf("%-22s %5d %5d\n", items[i].name, items[i].weight, items[i].value);
for (i = 0; i < n_items; i++) {
tw += if (sitems[i].bits & (1 << i)) {weight;
tv += printf("%s\n", itemitems[i].name)value;
w += item[i].weight;
}
}
printf("Total value: %d; weight: %d\n", s.value, w);
return 0;
}</lang>
{{out}}
<pre>
map
compass
water
sandwich
glucose
banana
suntancream
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
Total value: 1030; weight: 396
</pre>
 
=={{header|C++}}==
<lang cpp>#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 ;
}
}
printf("%-22s %5d %5d\n", "totals:", tw, tv);
for ( int i = 0 ; i < n ; i++ ) {
return 0;
for ( int weight = 0 ; weight < weightlimit ; weight++ ) {
}
if ( i == 0 )
</syntaxhighlight>
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 ] ;
}</lang>
{{out}}
<pre>
map 9 150
The best value that can be packed in the given knapsack is 1030 !
compass 13 35
The following items should be packed in the knapsack:
water 153 200
map
sandwich 50 160
compass
glucose 15 60
water
banana 27 60
sandwich
suntan cream 11 70
glucose
waterproof trousers 42 70
banana
waterproof overclothes 43 75
suntan creme
note-case 22 80
waterproof trousers
sunglasses 7 20
waterproof overclothes
socks 4 50
note-case
totals: 396 1030
sunglasses
socks
The total weight of all items is 396 !
</pre>
 
Line 528 ⟶ 954:
{{libheader|System}}
{{libheader|System.Collections.Generic}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
 
Line 546 ⟶ 972:
void AddItem(Item i)
{
if ((TotalWeight + i.Weight) <= MaxWeightAllowed)
items.Add(i);
}
Line 669 ⟶ 1,095:
}
}
}</langsyntaxhighlight>
("Bag" might not be the best name for the class, since "bag" is sometimes also used to refer to a multiset data structure.)
 
 
 
===C#, Alternative Version===
C# Knapsak 0-1 Russian Binary ciphers
 
Russian Knapsack 0-1 synthesizes all ciphers from 0 & 1 adding left +1 register and 0 remain on left in cipher
 
Number of comparisons decreases from N! to 2^N for example N=8 N!=40320 >> 2^N=256
 
Random values origin are automatically assigned create integral of quantity and quality
 
<syntaxhighlight lang="csharp">using System; // Knapsack C# binary DANILIN
using System.Text; // rextester.com/YRFA61366
namespace Knapsack
{
class Knapsack
{
static void Main()
{
int n = 7;
int Inside = 5;
int all=Convert.ToInt32(Math.Pow(2,(n+1)));
int[] mass = new int[n];
int[] cost = new int[n];
int[] jack = new int[n];
int[] quality = new int[all];
int[] amount = new int[all];
int i; // circle
int k; // circle
int dec;
string[] bin = new string[all];
int list;
int max;
int max_num;
Random rand = new Random();
 
for (i=0; i<n; i++)
{
mass[i]=1+rand.Next(3);
cost[i]=10+rand.Next(9);
Console.WriteLine("{0} {1} {2}", i+1, mass[i], cost[i]);
}
Console.WriteLine();
 
for (list = all-1; list>(all-1)/2; list--)
{
dec=list;
while (dec > 0)
{
bin[list] = dec % 2 + bin[list]; // from 10 to 2
dec/=2;
}
if (bin[list] == "")
{
bin[list] = "0";
}
bin[list]=bin[list].Substring(1,bin[list].Length-1);
for (k=0; k<n; k++) // inside 01
{
jack[k]=Convert.ToInt32(bin[list].Substring(k,1));
quality[list]=quality[list]+mass[k]*jack[k]*cost[k]; // integral of costs
amount[list]=amount[list]+mass[k]*jack[k]; // integral of mass
}
if (amount[list]<= Inside) // current mass < Knapsack
{
Console.WriteLine("{0} {1} {2} {3}", Inside, amount[list], quality[list], bin[list]);
}
}
Console.WriteLine();
 
max=0;
max_num=1;
for (i=0; i < all; i++)
{
if (amount[i]<=Inside && quality[i]>max)
{
max = quality[i]; max_num =i ;
}
}
Console.WriteLine("{0} {1} {2}",amount[max_num],quality[max_num],bin[max_num]);
}
}
}</syntaxhighlight>
 
{{out}}
<pre> # Mass Cost
1 2 12
2 3 17
3 1 14
4 3 17
5 1 13
Chifer Mass Cost
11000 5 5 75
01001 5 4 64
00111 5 5 78 !!!
00110 5 4 65
00101 5 2 27
Mass MAX Chifer
5 78 00111</pre>
 
{{out}}
<pre>int n = 20;
int Inside = 400;
int all=Convert.ToInt32(Math.Pow(2,(n+1)));
int[] mass = {9,13,153,50,15,68,27,39,23,52,11,32,24,48,73,42,43,22,7,4,30};
int[] cost = {150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,50,10};
 
396 1030 11111010001000011111
 
jdoodle.com/ia/rSn</pre>
 
=={{header|C++}}==
=== First version ===
{{libheader|Boost}}
<syntaxhighlight lang="cpp">#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 ] ;
}</syntaxhighlight>
{{out}}
<pre>
The best value that can be packed in the given knapsack is 1030 !
The following items should be packed in the knapsack:
map
compass
water
sandwich
glucose
banana
suntan creme
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
The total weight of all items is 396 !
</pre>
 
=== Second version ===
{{Works with|C++17}}
<syntaxhighlight lang="cpp">#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;
}</syntaxhighlight>
{{Out}}
<pre> best knapsack:
map 9 150
compass 13 35
water 153 200
sandwich 50 160
glucose 15 60
banana 27 60
suntan creme 11 70
waterproof trousers 42 70
waterproof overclothes 43 75
note-case 22 80
sunglasses 7 20
socks 4 50
 
total: 396 1030</pre>
 
=={{header|C_sharp}}==
All combinations, eight threads, break when weight is to large.
<syntaxhighlight lang="csharp">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"};
}</syntaxhighlight>
A dynamic version.
<syntaxhighlight lang="csharp">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"};
}</syntaxhighlight>
 
=={{header|Ceylon}}==
 
 
<b>module.ceylon</b>:
 
<syntaxhighlight lang="ceylon">
module knapsack "1.0.0" {
}
</syntaxhighlight>
 
<b>run.ceylon:</b>
 
<syntaxhighlight lang="ceylon">
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;
</syntaxhighlight>
 
 
{{out}}
<pre>
Total value: 1030.0
Total weight: 396
Items:
item(map, 9, 150.0)
item(socks, 4, 50.0)
item(cream, 11, 70.0)
item(glucose, 15, 60.0)
item(notecase, 22, 80.0)
item(sandwich, 50, 160.0)
item(sunglasses, 7, 20.0)
item(compass, 13, 35.0)
item(banana, 27, 60.0)
item(overclothes, 43, 75.0)
item(trousers, 42, 70.0)
item(water, 153, 200.0)
</pre>
 
=={{header|Clojure}}==
Uses the dynamic programming solution from [[wp:Knapsack_problem#0-1_knapsack_problem|Wikipedia]].
First define the ''items'' data:
<langsyntaxhighlight lang="clojure">(def item-data
[ "map" 9 150
"compass" 13 35
Line 701 ⟶ 1,670:
(defstruct item :name :weight :value)
 
(def items (vec (map #(apply struct item %) (partition 3 item-data))))</langsyntaxhighlight>
''m'' is as per the Wikipedia formula, except that it returns a pair ''[value indexes]'' where ''indexes'' is a vector of index values in ''items''. ''value'' is the maximum value attainable using items 0..''i'' whose total weight doesn't exceed ''w''; ''indexes'' are the item indexes that produces the value.
<langsyntaxhighlight lang="clojure">(declare mm) ;forward decl for memoization function
 
(defn m [i w]
Line 719 ⟶ 1,688:
no))))))
 
(def mm (memoize m))</langsyntaxhighlight>
Call ''m'' and print the result:
<langsyntaxhighlight lang="clojure">(use '[clojure.string :only [join]])
 
(let [[value indexes] (m (-> items count dec) 400)
Line 727 ⟶ 1,696:
(println "items to pack:" (join ", " names))
(println "total value:" value)
(println "total weight:" (reduce + (map (comp :weight items) indexes))))</langsyntaxhighlight>
{{out}}
<pre>items to pack: map, compass, water, sandwich, glucose, banana, suntan cream, waterproof trousers,
Line 736 ⟶ 1,705:
=={{header|Common Lisp}}==
Cached method.
<langsyntaxhighlight lang="lisp">;;; memoize
(defmacro mm-set (p v) `(if ,p ,p (setf ,p ,v)))
 
Line 765 ⟶ 1,734:
(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))))</langsyntaxhighlight>
{{out}}
<pre>(1030 396
Line 771 ⟶ 1,740:
(BANANA 27 60) (CREAM 11 70) (TROUSERS 42 70) (OVERCLOTHES 43 75)
(NOTECASE 22 80) (GLASSES 7 20) (SOCKS 4 50)))</pre>
 
=={{header|Crystal}}==
Branch and bound solution
<syntaxhighlight lang="ruby">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}"
</syntaxhighlight>
{{out}}
<pre>optimal choice: ["map", "socks", "suntan cream", "glucose", "note-case", "sandwich", "sunglasses", "compass", "banana", "waterproof overclothes", "waterproof trousers", "water"]
total weight 396, total value 1030
checked nodes: 992</pre>
 
=={{header|D}}==
===Dynamic Programming Version===
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.typecons, std.array, std.range;
 
struct Item { string name; int weight, value; }
string name;
int weight, value;
}
 
Item[] knapsack01DinamicProgknapsack01DinamicProgramming(inimmutable 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);
 
Item[]typeof(return) result;
int w = limit;
foreach_reverse (immutable i, immutable it; items)
if (tab[i + 1][w] != tab[i][w]) {
w -= it.weight;
Line 801 ⟶ 1,862:
}
 
void main() @safe {
enum int limit = 400;
immutable Item[] items = [{"map", 9, 150},
{"apple", 39, 40}, {"compassbanana", 1327, 3560},
{"beer", 52, 10}, {"waterbook", 30, 153, 20010},
{"camera", 32, 30}, {"sandwichcheese", 23, 50, 16030},
{"compass", 13, 35}, {"glucose", 15, 60},
{"map", 9, 150}, {"tinnote-case", 6822, 4580},
{"sandwich", 50, 160}, {"bananasocks", 274, 6050},
{"applesunglasses", 7, 20}, {"suntan cream", 3911, 4070},
{"t-shirt", 24, 15}, {"cheesetin", 2368, 3045},
{"towel", 18, 12}, {"beertrousers", 5248, 10},
{"umbrella", 73, 40}, {"suntan creamwater", 11153, 70200},
{"camerawaterproof overclothes", 3243, 3075},
{"t-shirtwaterproof trousers", 2442, 1570},];
{"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}];
 
autoimmutable baggedbag = knapsack01DinamicProgknapsack01DinamicProgramming(items, limit);
writelnwritefln("Items:\n%-( to pack:%s\n%)", bag.map!q{ a.name }.retro);
const t = reduce!q{ a[] += [b.weight, b.value] }([0, 0], bag);
bagged.map!q{ a.name }().array().sort().join("\n").writeln();
constwriteln("\nTotal tweight =and reduce!q{value: a", t[0] +<= [b.weight,limit b.value][]? t : }([0, 0], bagged);
}</syntaxhighlight>
const tot_wv = (t[0] <= limit) ? t : [0, 0];
writefln("\nFor a total weight of %d and a total value of %d",
tot_wv[0], tot_wv[1]);
}</lang>
{{out}}
<pre>Items to pack:
banana
compass
glucose
map
note-case
sandwich
socks
sunglasses
suntan cream
water
waterproof overclothes
waterproof trousers
 
For a totalTotal weight of 396 and a total value: of[396, 1030]</pre>
 
===Brute Force Version===
{{trans|C}}
<syntaxhighlight lang="d">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);
}</syntaxhighlight>
The runtime is about 0.09 seconds.
{{out}}
<pre>Items:
banana
compass
glucose
map
note-case
sandwich
socks
sunglasses
suntan cream
water
waterproof overclothes
waterproof trousers
 
Total value: 1030; weight: 396</pre>
 
===Short Dynamic Programming Version===
{{trans|Haskell}}
<syntaxhighlight lang="d">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;
}</syntaxhighlight>
Runtime about 0.04 seconds.
{{out}}
<pre>Tuple!(int, "tot", string[], "names")(1030, ["banana", "compass", "glucose", "map", "note-case", "sandwich", "socks", "sunglasses", "suntan cream", "water", "overclothes", "waterproof trousers"])</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
This is a good example of using an iterator. The problem involves looking at all different compinations of items in the list. If you increment a number up to a certain maximum, you systematically set all combination of bits in that number. The trick is turning the pattern of bits in a number into indices into the packing list. The iterater handles that and so it can be used in multiple places in the code to step through various the combinations of items in the list.
<syntaxhighlight lang="Delphi">
{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;
 
</syntaxhighlight>
{{out}}
<pre>
Item Weight Value
---------------------------------------
map 9 150
compass 13 35
water 153 200
sandwich 50 160
glucose 15 60
banana 27 60
suntan cream 11 70
waterproof trousers 42 70
waterproof overclothes 43 75
note-case 22 80
sunglasses 7 20
socks 4 50
---------------------------------------
Total 396 1030
Best Inx: 1541215
Best Value: 1030
Best Weight: 396
</pre>
 
=={{header|Dart}}==
<langsyntaxhighlight lang="dart">List solveKnapsack(items, maxWeight) {
int MIN_VALUE=-100;
int N = items.length; // number of items
Line 955 ⟶ 2,275:
print("Elapsed Time = ${sw.elapsedInMs()}ms");
}</langsyntaxhighlight>
{{out}}
<pre>[item, profit, weight]
Line 973 ⟶ 2,293:
Total Weight = 396
Elapsed Time = 6ms</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
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
solve i - 1 maxw items[] wres vres
else
solve i - 1 maxw items[] wres vres
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
.
.
.
solve len weight[] max_w items[] w v
print "weight: " & w
print "value: " & v
print "items:"
for item in items[]
print " " & name$[item]
.
</syntaxhighlight>
 
=={{header|EchoLisp}}==
<syntaxhighlight lang="scheme">
(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)))
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="scheme">
;; 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
</syntaxhighlight>
 
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
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
</syntaxhighlight>
<syntaxhighlight lang="eiffel">
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
</syntaxhighlight>
<syntaxhighlight lang="eiffel">
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
</syntaxhighlight>
{{out}}
<pre>
The final value of the knapsack will be: 1030
We'll take the following items:
socks
sunglasses
note-case
waterproof overclothes
waterproof trousers
suntan cream
banana
glucose
sandwich
water
compass
map
</pre>
 
=={{header|Elixir}}==
{{trans|Erlang}}
<syntaxhighlight lang="elixir">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)</syntaxhighlight>
 
{{out}}
<pre>
Items:
"socks"
"sunglasses"
"note-case"
"waterproof overclothes"
"waterproof trousers"
"suntan cream"
"banana"
"glucose"
"sandwich"
"water"
"compass"
"map"
Total value: 1030
Total weight: 396
Time elapsed in milliseconds: 733.0
</pre>
 
=={{header|Emacs Lisp}}==
Line 978 ⟶ 2,684:
{{Trans|Common Lisp}} with changes (memoization without macro)
 
<langsyntaxhighlight lang="lisp">
(defun ks (max-w items)
(let ((cache (make-vector (1+ (length items)) nil)))
Line 1,013 ⟶ 2,719:
(waterproof-trousers 42 70) (overclothes 43 75) (notecase 22 80)
(glasses 7 20) (towel 18 12) (socks 4 50) (book 30 10)))
</syntaxhighlight>
</lang>
 
{{out}}
Output:
<pre>
(1030 396 ((map 9 150) (compass 13 35) (water 153 200) (sandwich 50 160) (glucose 15 60)
Line 1,023 ⟶ 2,729:
 
Another way without cache :
<langsyntaxhighlight lang="lisp">
(defun best-rate (l1 l2)
"predicate for sorting a list of elements regarding the value/weight rate"
Line 1,071 ⟶ 2,777:
(waterproof-trousers 42 70) (overclothes 43 75) (notecase 22 80)
(glasses 7 20) (towel 18 12) (socks 4 50) (book 30 10)) 400)
</syntaxhighlight>
</lang>
 
Output with org-babel in Emacs
 
{{out}} with org-babel in Emacs
<pre>
| map | 9 | 150 |
Line 1,090 ⟶ 2,795:
| | 396 | 1030 |
 
</pre>
 
=={{header|Erlang}}==
 
<syntaxhighlight lang="erlang">
 
-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.
</syntaxhighlight>
 
{{out}}
<pre>
1> knapsack_0_1:go().
Items:
"socks"
"sunglasses"
"note-case"
"waterproof overclothes"
"waterproof trousers"
"suntan cream"
"banana"
"glucose"
"sandwich"
"water"
"compass"
"map"
Total value: 1030
Total weight: 396
Time elapsed in milliseconds: 133.445
ok
</pre>
 
=={{header|Euler Math Toolbox}}==
 
<syntaxhighlight lang="euler math toolbox">
>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
</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
===Using A* Algorithm===
<syntaxhighlight lang="fsharp">
//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 [])
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="fsharp">
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)
</syntaxhighlight>
<pre>
> let x=knapStar itemsf 400.0;;
> x|>Seq.map (fun n->Seq.item n itemsf)|>Seq.sumBy(fun (_,_,n)->(+n));;
val it : float = 1030.0
> x|>Seq.map (fun n->Seq.item n itemsf)|>Seq.sumBy(fun (_,n,_)->(+n));;
val it : float = 396.0
> x|>Seq.iter(fun n->printfn "%A" (List.item n itemsf));;
("map", 9.0, 150.0)
("socks", 4.0, 50.0)
("suntan cream", 11.0, 70.0)
("glucose", 15.0, 60.0)
("note-case", 22.0, 80.0)
("sandwich", 50.0, 160.0)
("sunglasses", 7.0, 20.0)
("compass", 13.0, 35.0)
("banana", 27.0, 60.0)
("waterproof overclothes", 43.0, 75.0)
("waterproof trousers", 42.0, 70.0)
("water", 153.0, 200.0)
</pre>
 
=={{header|Factor}}==
Using dynamic programming:
<langsyntaxhighlight lang="factor">USING: accessors arrays fry io kernel locals make math
math.order math.parser math.ranges sequences sorting ;
IN: rosetta.knappsack.0-1
Line 1,170 ⟶ 3,078:
"Items packed: " print
natural-sort
[ " " write print ] each ;</langsyntaxhighlight>
<pre>
( scratchpad ) main
Line 1,187 ⟶ 3,095:
waterproof overclothes
waterproof trousers
</pre>
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">
\ 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 .
;
</syntaxhighlight>
{{out}}
<pre>
map
compass
water
sandwich
glucose
banana
suntan cream
wp trousers
wp overclothes
note-case
sunglasses
socks
Weight: 396 Value: 1030
</pre>
 
 
# Numbered list item
=={{header|Fortran}}==
{{trans|Pascal}}
<syntaxhighlight lang="FORTRAN">
Program Knapsack01
! Translation of Pascal version on Rosetta Code.
implicit none
integer, parameter :: NUM_ITEMS = 22
integer, parameter :: MAX_WEIGHT = 400
type :: TItem
character(len=20) :: Name
integer :: Weight, Value
end type TItem
type(TItem), dimension(0:NUM_ITEMS-1) :: ITEMS
integer, dimension(0:NUM_ITEMS, 0:MAX_WEIGHT) :: D
integer :: I, W, V, MaxWeight
! Init Arrays
d = 0
ITEMS = [ TItem('compass', 13, 35), &
TItem('water', 153, 200), &
TItem('sandwich', 50, 160), &
TItem('glucose', 15, 60), &
TItem('tin', 68, 45), &
TItem('banana', 27, 60), &
TItem('apple', 39, 40), &
TItem('cheese', 23, 30), &
TItem('beer', 52, 10), &
TItem('suntan cream', 11, 70), &
TItem('camera', 32, 30), &
TItem('T-shirt', 24, 15), &
TItem('trousers', 48, 10), &
TItem('umbrella', 73, 40), &
TItem('waterproof trousers', 43, 70), &
TItem('waterproof overclothes', 42, 75), &
TItem('note-case', 22, 80), &
TItem('sunglasses', 7, 20), &
TItem('towel', 18, 12), &
TItem('map', 9, 150), &
TItem('socks', 4, 50), &
TItem('book', 30, 10) ]
!
do I = 0, NUM_ITEMS-1
do W = 0, MAX_WEIGHT
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)
end if
end do
end do
W = MAX_WEIGHT
V = D(NUM_ITEMS, W)
MaxWeight = 0
!
write(*, "(/,'bagged:')")
do I = NUM_ITEMS-1, 0, -1 !Pete
if (D(I+1, W) == V) then
if((D(I, (W - ITEMS(I)%Weight)) == V - ITEMS(I)%Value)) then
write(*, "(' ', A,t25,i0,t35,i0)", advance='yes') ITEMS(I)%Name,ITEMS(I)%weight,ITEMS(I)%value
MaxWeight = MaxWeight + ITEMS(I)%Weight
W = W - ITEMS(I)%Weight
V = V - ITEMS(I)%Value
end if
end if
end do
!
write(*, "('value = ', I0)") D(NUM_ITEMS, MAX_WEIGHT)
write(*, "('weight = ', I0)") MaxWeight
end program Knapsack01
</syntaxhighlight>
{{out}}
<pre>
bagged:
socks 4 50
map 9 150
sunglasses 7 20
note-case 22 80
waterproof overcloth 42 75
waterproof trousers 43 70
suntan cream 11 70
banana 27 60
glucose 15 60
sandwich 50 160
water 153 200
compass 13 35
value = 1030
weight = 396
knapsack time = 94 Milliseconds
</pre>
===Branch and Bound Version===
{{trans|Fortran 77}}
<syntaxhighlight lang="fortran">
module ksack2
!
! THIS SUBROUTINE SOLVES THE 0-1 SINGLE KNAPSACK PROBLEM
!
! MAXIMIZE Z = P(1)*X(1) + ... + P(N)*X(N)
!
! SUBJECT TO: W(1)*X(1) + ... + W(N)*X(N) .LE. C ,
! X(J) = 0 OR 1 FOR J=1,...,N.
!
! THE PROGRAM IS INCLUDED IN THE VOLUME
! S. MARTELLO, P. TOTH, "KNAPSACK PROBLEMS: ALGORITHMS
! AND COMPUTER IMPLEMENTATIONS", JOHN WILEY, 1990
! (https://dl.acm.org/doi/book/10.5555/98124)
! AND IMPLEMENTS THE BRANCH-AND-BOUND ALGORITHM DESCRIBED IN
! SECTION 2.5.2 .
! THE PROGRAM DERIVES FROM AN EARLIER CODE PRESENTED IN
! S. MARTELLO, P. TOTH, "ALGORITHM FOR THE SOLUTION OF THE 0-1 SINGLE
! KNAPSACK PROBLEM", COMPUTING, 1978.
 
! The orignal program was written in Fortran 77 and was an amazing tangle of GOTO statements.
! I have reworked the code in such a manner as to eliminate the GOTO statements and bring it
! to Fortran 2018 LANGUAGE compliance though the code logic remains somewhat untractable.
!
! The routine requires a large parameter string which includes 4 dummy arrays for it's calculations.
! As well, it offers an option to check the input data for correctness.
! Rather than modify the original algorithm, I wrote a simple wrapper called "start_knapsack" that
! allocates those arrays as well as defaulting the input parameter check to "on", hiding them from the user.
! Having said that, the algorithm works very well and is very fast. I've included it in this
! Rosetta Code listing because it scales well and can be used with a large dataset.
! Which a potential user may desire.
! Peter.kelly@acm.org (28-December-2023)
!
! THE INPUT PROBLEM MUST SATISFY THE CONDITIONS
!
! 1) 2 .LE. N .LE. JDIM - 1 ;
! 2) P(J), W(J), C POSITIVE INTEGERS;
! 3) MAX (W(J)) .LE. C ;
! 4) W(1) + ... + W(N) .GT. C ;
! 5) P(J)/W(J) .GE. P(J+1)/W(J+1) FOR J=1,...,N-1. <-- Note well. They need to be sorted in the greatest ratio of (p(j)/w(j)) down to the smallest one
!
! MT1 CALLS 1 PROCEDURE: CHMT1.
!
! MT1 NEEDS 8 ARRAYS ( P , W , X , XX , MIN , PSIGN , WSIGN
! AND ZSIGN ) OF LENGTH AT LEAST N + 1 .
!
! MEANING OF THE INPUT PARAMETERS:
! N = NUMBER OF ITEMS;
! P(J) = PROFIT OF ITEM J (J=1,...,N);
! W(J) = WEIGHT OF ITEM J (J=1,...,N);
! C = CAPACITY OF THE KNAPSACK;
! JDIM = DIMENSION OF THE 8 ARRAYS;
! JCK = 1 IF CHECK ON THE INPUT DATA IS DESIRED,
! = 0 OTHERWISE.
!
! MEANING OF THE OUTPUT PARAMETERS:
! Z = VALUE OF THE OPTIMAL SOLUTION IF Z .GT. 0 ,
! = ERROR IN THE INPUT DATA (WHEN JCK=1) IF Z .LT. 0 : CONDI-
! TION - Z IS VIOLATED;
! X(J) = 1 IF ITEM J IS IN THE OPTIMAL SOLUTION,
! = 0 OTHERWISE.
!
! ARRAYS XX, MIN, PSIGN, WSIGN AND ZSIGN ARE DUMMY.
!
! ALL THE PARAMETERS ARE INTEGER. ON RETURN OF MT1 ALL THE INPUT
! PARAMETERS ARE UNCHANGED.
!
implicit none
contains
subroutine mt1(n , p , w , c , z , x , jdim , jck , xx , min , psign , wsign , zsign)
implicit none
integer :: jdim
integer :: n
integer , intent(inout) , dimension(jdim) :: p
integer , intent(inout) , dimension(jdim) :: w
integer :: c
integer , intent(inout) :: z
integer , intent(out) , dimension(jdim) :: x
integer , intent(in) :: jck
integer , intent(inout) , dimension(jdim) :: xx
integer , intent(inout) , dimension(jdim) :: min
integer , intent(inout) , dimension(jdim) :: psign
integer , intent(inout) , dimension(jdim) :: wsign
integer , intent(inout) , dimension(jdim) :: zsign
!
real :: a
real :: b
integer :: ch
integer :: chs
integer :: diff
integer :: ii
integer :: ii1
integer :: in
integer :: ip
integer :: iu
integer :: j
integer :: j1
integer :: jj
integer :: jtemp
integer :: kk
integer :: lim
integer :: lim1
integer :: ll
integer :: lold
integer :: mink
integer :: n1
integer :: nn
integer :: profit
integer :: r
integer :: t
integer :: next_code_block
!*Code
next_code_block = 1
dispatch_loop: do
select case(next_code_block)
case(1)
z = 0
if( jck==1 )call chmt1(n , p , w , c , z , jdim)
if( z<0 )return
! INITIALIZE.
ch = c
ip = 0
chs = ch
first_loop: do ll = 1 , n
if( w(ll)>chs )exit first_loop
ip = ip + p(ll)
chs = chs - w(ll)
end do first_loop
ll = ll - 1
if( chs==0 )then
z = ip
x(1:ll) = 1
nn = ll + 1
x(nn:n) = 0
return
else
p(n + 1) = 0
w(n + 1) = ch + 1
lim = ip + chs*p(ll + 2)/w(ll + 2)
a = w(ll + 1) - chs
b = ip + p(ll + 1)
lim1 = b - a*float(p(ll))/float(w(ll))
if( lim1>lim )lim = lim1
mink = ch + 1
min(n) = mink
do j = 2 , n
kk = n + 2 - j
if( w(kk)<mink )mink = w(kk)
min(kk - 1) = mink
end do
xx(1:n) = 0
z = 0
profit = 0
lold = n
ii = 1
next_code_block = 4
cycle dispatch_loop
end if
case(2)
! TRY TO INSERT THE II-TH ITEM INTO THE CURRENT SOLUTION.
do while ( w(ii)>ch )
ii1 = ii + 1
if( z>=ch*p(ii1)/w(ii1) + profit )then
next_code_block = 5
cycle dispatch_loop
end if
ii = ii1
end do
! BUILD A NEW CURRENT SOLUTION.
ip = psign(ii)
chs = ch - wsign(ii)
in = zsign(ii)
ll = in
do while ( ll<=n )
if( w(ll)>chs )then
iu = chs*p(ll)/w(ll)
ll = ll - 1
if( iu==0 )then
next_code_block = 3
cycle dispatch_loop
end if
if( z>=profit + ip + iu )then
next_code_block = 5
cycle dispatch_loop
end if
next_code_block = 4
cycle dispatch_loop
else
ip = ip + p(ll)
chs = chs - w(ll)
end if
end do
ll = n
next_code_block = 3
case(3)
if( z>=ip + profit )then
next_code_block = 5
cycle dispatch_loop
end if
z = ip + profit
nn = ii - 1
x(1:nn) = xx(1:nn)
x(ii:ll) = 1
if( ll/=n )then
nn = ll + 1
x(nn:n) = 0
end if
if( z/=lim )then
next_code_block = 5
cycle dispatch_loop
end if
return
case(4)
! SAVE THE CURRENT SOLUTION.
wsign(ii) = ch - chs
psign(ii) = ip
zsign(ii) = ll + 1
xx(ii) = 1
nn = ll - 1
if( nn>=ii )then
do j = ii , nn
wsign(j + 1) = wsign(j) - w(j)
psign(j + 1) = psign(j) - p(j)
zsign(j + 1) = ll + 1
xx(j + 1) = 1
end do
end if
j1 = ll + 1
wsign(j1:lold) = 0
psign(j) = 0
zsign(j1:lold) = [(jtemp, jtemp = j1,lold)]
lold = ll
ch = chs
profit = profit + ip
if( ll<(n - 2) )then
ii = ll + 2
if( ch>=min(ii - 1) )then
next_code_block = 2
cycle dispatch_loop
end if
else if( ll==(n - 2) )then
if( ch>=w(n) )then
ch = ch - w(n)
profit = profit + p(n)
xx(n) = 1
end if
ii = n - 1
else
ii = n
end if
! SAVE THE CURRENT OPTIMAL SOLUTION.
if( z<profit )then
z = profit
x(1:n) = xx(1:n)
if( z==lim )return
end if
if( xx(n)/=0 )then
xx(n) = 0
ch = ch + w(n)
profit = profit - p(n)
end if
next_code_block = 5
case(5)
outer_loop: do ! BACKTRACK.
nn = ii - 1
if( nn==0 )return
middle_loop: do j = 1 , nn
kk = ii - j
if( xx(kk)==1 )then
r = ch
ch = ch + w(kk)
profit = profit - p(kk)
xx(kk) = 0
if( r<min(kk) )then
nn = kk + 1
ii = kk
! TRY TO SUBSTITUTE THE NN-TH ITEM FOR THE KK-TH.
inner_loop: do while ( z<profit + ch*p(nn)/w(nn) )
diff = w(nn) - w(kk)
if( diff<0 )then
t = r - diff
if( t>=min(nn) )then
if( z>=profit + p(nn) + t*p(nn + 1)/w(nn + 1) )exit inner_loop
ch = ch - w(nn)
profit = profit + p(nn)
xx(nn) = 1
ii = nn + 1
wsign(nn) = w(nn)
psign(nn) = p(nn)
zsign(nn) = ii
n1 = nn + 1
wsign(n1:lold) = 0
psign(n1:lold) = 0
zsign(n1:lold) = [(jtemp, jtemp = n1,lold)]
lold = nn
next_code_block = 2
cycle dispatch_loop
end if
else if( diff/=0 )then
if( diff<=r )then
if( z<profit + p(nn) )then
z = profit + p(nn)
x(1:kk) = xx(1:kk)
jj = kk + 1
x(jj:n) = 0
x(nn) = 1
if( z==lim )return
r = r - diff
kk = nn
nn = nn + 1
cycle inner_loop
end if
end if
end if
nn = nn + 1
end do inner_loop
cycle outer_loop
else
ii = kk + 1
next_code_block = 2
cycle dispatch_loop
end if
end if
end do middle_loop
exit outer_loop
end do outer_loop
exit dispatch_loop
end select
end do dispatch_loop
end subroutine mt1
!
subroutine chmt1(n , p , w , c , z , jdim)
integer , intent(in) :: jdim
integer , intent(in) :: n
integer , intent(in) , dimension(jdim) :: p
integer , intent(in) , dimension(jdim) :: w
integer , intent(in) :: c
integer , intent(out) :: z
!
! Local variable declarations
!
integer :: j
integer :: jsw
real :: r
real :: rr
!
! CHECK THE INPUT DATA.
!
if(( n<2) .or. (n>jdim - 1) )then
z = -1
return
else if( c>0 )then
jsw = 0
rr = float(p(1))/float(w(1))
do j = 1 , n
r = rr
if(( p(j)<=0 ).or.( w(j)<=0 ))then
z = -2
return
end if
jsw = jsw + w(j)
if( w(j)<=c )then
rr = float(p(j))/float(w(j))
if( rr>r )then
z = -5
return
end if
else
z = -3
return
end if
end do
if( jsw>c )return
z = -4
return
end if
z = -2
return
end subroutine chmt1
 
subroutine start_knapsack(n , profit , weight , capacity , result_val , members)
!
! Dummy argument declarations
!
integer , intent(in) :: n
integer , intent(inout) , dimension(n) :: profit
integer , intent(inout) , dimension(n) :: weight
integer , intent(in) :: capacity
integer , intent(inout) :: result_val
integer , intent(inout) , dimension(n) :: members
!
! Local variable declarations
integer :: bigger
integer :: jck
integer , allocatable , dimension(:) :: mini
integer , allocatable , dimension(:) :: psign
integer , allocatable , dimension(:) :: wsign
integer , allocatable , dimension(:) :: xx
integer , allocatable , dimension(:) :: zsign
!
!Designed to invoke MT1
!MT1 NEEDS 8 ARRAYS ( P , W , X , XX , MIN , PSIGN , WSIGN
! AND ZSIGN ) OF LENGTH AT LEAST N + 1 .
 
! MEANING OF THE INPUT PARAMETERS:
! N = NUMBER OF ITEMS;
! P(J) = PROFIT OF ITEM J (J=1,...,N);
! W(J) = WEIGHT OF ITEM J (J=1,...,N);
! C = CAPACITY OF THE KNAPSACK;
! JDIM = DIMENSION OF THE 8 ARRAYS;
! JCK = 1 IF CHECK ON THE INPUT DATA IS DESIRED,
! = 0 OTHERWISE.
!
! MEANING OF THE OUTPUT PARAMETERS:
! Z = VALUE OF THE OPTIMAL SOLUTION IF Z .GT. 0 ,
! = ERROR IN THE INPUT DATA (WHEN JCK=1) IF Z .LT. 0 : CONDI-
! TION - Z IS VIOLATED;
! X(J) = 1 IF ITEM J IS IN THE OPTIMAL SOLUTION,
! = 0 OTHERWISE.
!
! ARRAYS XX, MIN, PSIGN, WSIGN AND ZSIGN ARE DUMMY.
!
! ALL THE PARAMETERS ARE INTEGER. ON RETURN OF MT1 ALL THE INPUT
! PARAMETERS ARE UNCHANGED.
!
jck = 1 !Set parameter checking on
bigger = n + 100
!
! Allocate the dummy arrays
allocate(xx(bigger))
allocate(mini(bigger))
allocate(psign(bigger))
allocate(wsign(bigger))
allocate(zsign(bigger))
call mt1(n , profit , weight , capacity , result_val , members , bigger , jck , xx , mini , psign , wsign , zsign)
deallocate(xx)
deallocate(mini)
deallocate(psign)
deallocate(wsign)
deallocate(zsign)
 
end subroutine start_knapsack
end module ksack2
!
program serious_knapsack
use ksack2
integer, parameter :: list_size=22
integer:: p(list_size) ! The weights
integer::n,profit(list_size),capacity,result_val,members(size(p)),valuez,t1,t2,j
character(len=25) :: names(list_size),tempnam
real :: ratio(list_size),rats
logical :: swapped
capacity =400
members = 0
result_val = 0
n = list_size
p(1:list_size) = (/13,153, 50,15,68,27,39,23,52,11,32,24,48,73,43,42,22,07,18,009,04,30/)
profit(1:list_size) =(/35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,150,50,10/)
 
names(1:22) =[character(len=25) ::'compass','water','sandwich','glucose','tin','banana','apple', 'cheese', &
'beer','suntan cream','camera','T-shirt','trousers','umbrella','waterproof trousers', 'waterproof overclothes', &
'note-case','sunglasses','towel','map','socks', 'book']
ratio(1:22) = float(profit(1:22))/float(p(1:22))
! The mt1 algorithm wants the data sorted downwards(large-->small) by the ration of profit/weight
! So, I implemented a quick bubble sort to order the lists
swapped = .true.
do while (swapped)
swapped = .false.
do j = 1,21
if(ratio(j).lt.ratio(j+1))then ! Swaps everywhere
swapped = .true.
t1 = p(j+1) ! Swap the weights
p(j+1) = p(j)
p(j) = t1
t2 = profit(j+1) !Swap the profits
profit(j+1) = profit(j)
profit(j) = t2
tempnam = names(j+1) ! Swap the names around
names(j+1) = names(j)
names(j) = tempnam
rats = ratio(j+1) ! Swap the ratios
ratio(j+1) = ratio(j)
ratio(j) = rats
endif
end do
end do
!
call system_clock(count=xx)
call startup(n,profit(1:22),p(1:22),capacity,result_val,members)
call system_clock(count=yy)
print*,'Total of the sack = ',result_val
capacity = 0
valuez = 0
n = 0
do i = 1,size(members)
if(members(i) /=0)then
capacity = capacity +p(i)
valuez = profit(i) + valuez
n = n+1
print*, names(i),p(i),profit(i)
endif
 
end do
print*,'Filled capacity = ',capacity,'Value = ',valuez!,'No items = ',n,sum(profit(1:22)),sum(p(1:22))
print*
print*,'First knapsack time = ',(yy-xx),'Milliseconds'
stop 'All done'
end program serious_knapsack
 
</syntaxhighlight>
{{out}}
<pre>
map 9 150
socks 4 50
suntan cream 11 70
glucose 15 60
note-case 22 80
sandwich 50 160
sunglasses 7 20
compass 13 35
banana 27 60
waterproof overclothes 42 75
waterproof trousers 43 70
water 153 200
Filled capacity = 396 Value = 1030
 
First knapsack time = 0 Milliseconds
 
</pre>
 
=={{header|FreeBASIC}}==
{{trans|XPL0}}
<syntaxhighlight lang="freebasic">#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</syntaxhighlight>
{{out}}
<pre>Same as XLP0 entry.</pre>
 
=={{header|Free Pascal}}==
Dynamic programming solution(tested with FPC 3.2.2).
<syntaxhighlight lang="pascal">
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.
</syntaxhighlight>
{{out}}
<pre>
bagged:
socks
sunglasses
note-case
waterproof overclothes
waterproof trousers
suntan cream
banana
glucose
sandwich
water
compass
map
value = 1030
weight = 396
</pre>
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">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</syntaxhighlight>
 
{{output}}
<pre>
Item Weight Value
water 153 200
sandwich 50 160
map 9 150
note-case 22 80
waterproof overclothes 43 75
suntan cream 11 70
waterproof trousers 42 70
glucose 15 60
banana 27 60
socks 4 50
compass 13 35
sunglasses 7 20
 
knapsack 396 1030
 
There's just enough room for extra socks!
</pre>
 
=={{header|Go}}==
From WP, "0-1 knapsack problem" under [http://en.wikipedia.org/wiki/Knapsack_problem#Dynamic_Programming_Algorithm|Solving The Knapsack Problem], although the solution here simply follows the recursive defintion and doesn't even use the array optimization.
Another WP punch and run.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,224 ⟶ 4,082:
{"book", 30, 10},
}
 
const maxWt = 400
 
func main() {
items, w, v := m(len(wants)-1, 400maxWt)
fmt.Println(items)
fmt.Println("weight:", w)
Line 1,245 ⟶ 4,105:
}
return i0, w0, v0
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,251 ⟶ 4,111:
weight: 396
value: 1030
</pre>
'''Alternative test case'''
 
Data for which a greedy algorithm might give an incorrect result:
<syntaxhighlight lang="go">
var wants = []item{
{"sunscreen", 15, 2},
{"GPS", 25, 2},
{"beer", 35, 3},
}
 
const maxWt = 40
</syntaxhighlight>
{{out}}
<pre>
[sunscreen GPS]
weight: 40
value: 4
</pre>
 
=={{header|Groovy}}==
Solution #1: brute force
<langsyntaxhighlight lang="groovy">def totalWeight = { list -> list*.weight.sum() }
def totalValue = { list -> list*.value.sum() }
Line 1,263 ⟶ 4,141:
350 < w && w < 401
}.max(totalValue)
}</langsyntaxhighlight>
Solution #2: dynamic programming
<langsyntaxhighlight lang="groovy">def knapsack01dp = { possibleItems ->
def n = possibleItems.size()
def m = (0..n).collect{ i -> (0..400).collect{ w -> []} }
Line 1,275 ⟶ 4,153:
}
m[n][400]
}</langsyntaxhighlight>
Test:
<langsyntaxhighlight lang="groovy">def items = [
[name:"map", weight:9, value:150],
[name:"compass", weight:13, value:35],
Line 1,313 ⟶ 4,191:
printf (" item: %-25s weight:%4d value:%4d\n", it.name, it.weight, it.value)
}
}</langsyntaxhighlight>
{{out}}
<pre>Elapsed Time: 132.267 s
Line 1,351 ⟶ 4,229:
=={{header|Haskell}}==
Brute force:
<syntaxhighlight lang="haskell">inv = [("map",9,150), ("compass",13,35), ("water",153,200), ("sandwich",50,160),
<lang haskell>import Data.List
("glucose",15,60), ("tin",68,45), ("banana",27,60), ("apple",39,40),
import Data.Ord
("cheese",23,30), ("beer",52,10), ("cream",11,70), ("camera",32,30),
import Control.Monad
("tshirt",24,15), ("trousers",48,10), ("umbrella",73,40), ("trousers",42,70),
import Control.Arrow
("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
inv :: [(String,Int,Int)]
combs [] _ = [ (0, []) ]
inv = map ((\[i,w,v] -> (i,read w, read v)).words) $ lines $
combs ((name,w,v):rest) cap = combs rest cap ++
"map\t9\t150\ncompass\t13\t35\nwater\t153\t200\nsandwich\t50\t160\n" ++
if w > cap then [] else map (prepend (name,w,v)) (combs rest (cap - w))
"glucose\t15\t60\ntin\t68\t45\nbanana\t27\t60\napple\t39\t40\ncheese\t23\t30\n" ++
where prepend (name,w,v) (v2, lst) = (v2 + v, (name,w,v):lst)
"beer\t52\t10\nsuntan_cream\t11\t70\ncamera\t32\t30\ntshirt\t24\t15\n" ++
"trousers\t48\t10\numbrella\t73\t40\nwaterproof_trousers\t42\t70\n" ++
"waterproof_overclothes\t43\t75\nnotecase\t22\t80\nsunglasses\t7\t20\n" ++
"towel\t18\t12\nsocks\t4\t50\nbook\t30\t10"
 
int2bin :: Int -> [Int]
int2bin = unfoldr(\x -> if x==0 then Nothing
else Just (uncurry(flip(,)) (divMod x 2)))
main = do
putStr "Total value: "; print value
let fwv = foldl (\(wc,vc) (i,w,v) ->(wc+w,vc+v))(0,0). map (inv!!). elemIndices 1
mapM_ print items
where (value, items) = maximum $ combs inv 400</syntaxhighlight>
fmt wb ib (n,w,v) = ns ++ f w ++ f v where
{{out}}
ns = (n ++) $ replicate (wb-length n) ' '
f n = reverse. take ib $ reverse (show n) ++ repeat ' '
 
((wc,vc),ii) =
foldl' ((.(fwv.int2bin &&& id)).
(\o@((_,vo),_) n@((wn,vn),_) ->
if wn<=400 && vn>vo then n else o) ) ((1000,0),0) [1..(2^length inv)-1]
 
mapM_ (putStrLn.fmt 30 5 .(inv!!)). elemIndices 1 $ int2bin ii
putStrLn $ fmt 30 5 ("Total",wc,vc)</lang>
Compile and execute in GHCi:
<pre>
Total value: 1030
*Main> :! ghc --make ./Rosetta/knapsack01.hs
("map",9,150)
[1 of 1] Compiling Main ( Rosetta/knapsack01.hs, Rosetta/knapsack01.o )
("compass",13,35)
Linking Rosetta/knapsack01 ...
("water",153,200)
*Main> :! ./Rosetta/knapsack01
("sandwich",50,160)
map 9 150
("glucose",15,60)
compass 13 35
("banana",27,60)
water 153 200
("cream",11,70)
sandwich 50 160
("trousers",42,70)
glucose 15 60
("overclothes",43,75)
banana 27 60
("notecase",22,80)
suntan_cream 11 70
("sunglasses",7,20)
waterproof_trousers 42 70
("socks",4,50)
waterproof_overclothes 43 75
notecase 22 80
sunglasses 7 20
socks 4 50
Total 396 1030
</pre>
Much faster brute force solution that computes the maximum before prepending, saving most of the prepends:
<syntaxhighlight lang="haskell">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</syntaxhighlight>
{{out}}
<pre>(1030,[("map",9,150),("compass",13,35),("water",153,200),("sandwich",50,160),("glucose",15,60),("banana",27,60),("cream",11,70),("trousers",42,70),("overclothes",43,75),("notecase",22,80),("sunglasses",7,20),("socks",4,50)])</pre>
 
Dynamic programming with a list for caching (this can be adapted to bounded problem easily):
<syntaxhighlight lang="haskell">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</syntaxhighlight>
{{out}}
(1030,["map","compass","water","sandwich","glucose","banana","cream","waterproof trousers","overclothes","notecase","sunglasses","socks"])
 
=={{header|Icon}} and {{header|Unicon}}==
Translation from Wikipedia pseudo-code. Memoization can be enabled with a command line argument that causes the procedure definitions to be swapped which effectively hooks the procedure.
<langsyntaxhighlight Iconlang="icon">link printf
 
global wants # items wanted for knapsack
Line 1,481 ⟶ 4,375:
packing(["socks"], 4, 50),
packing(["book"], 30, 10) ]
end</langsyntaxhighlight>
{{libheader|Icon Programming Library}}
[http://www.cs.arizona.edu/icon/library/src/procs/printf.icn printf.icn provides printf]
Line 1,495 ⟶ 4,389:
=={{header|J}}==
Static solution:
<langsyntaxhighlight Jlang="j">'names values'=:|:".;._2]0 :0
'map'; 9 150
'compass'; 13 35
Line 1,522 ⟶ 4,416:
X=: +/ .*"1
plausible=: (] (] #~ 400 >: X) #:@i.@(2&^)@#)@:({."1)
best=: (plausible ([ {~ [ (i. >./)@:X {:"1@]) ]) values</langsyntaxhighlight>
Illustration of answer:
<langsyntaxhighlight Jlang="j"> +/best#values NB. total weight and value
396 1030
best#names
Line 1,538 ⟶ 4,432:
notecase
sunglasses
socks </langsyntaxhighlight>
 
'''Alternative test case'''
 
<syntaxhighlight lang="j">'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</syntaxhighlight>
 
Illustration:
 
<syntaxhighlight lang="j"> +/best#values
40 4
best#names
sunscreen
GPS </syntaxhighlight>
 
=={{header|Java}}==
General dynamic solution after [[wp:Knapsack_problem#0-1_knapsack_problem|wikipedia]].
<langsyntaxhighlight lang="java">package hu.pj.alg.test;
 
import hu.pj.alg.ZeroOneKnapsack;
Line 1,625 ⟶ 4,539:
}
 
} // class</langsyntaxhighlight>
<langsyntaxhighlight lang="java">package hu.pj.alg;
 
import hu.pj.obj.Item;
Line 1,779 ⟶ 4,693:
}
 
} // class</langsyntaxhighlight>
<langsyntaxhighlight lang="java">package hu.pj.obj;
 
public class Item {
Line 1,850 ⟶ 4,764:
public int getBounding() {return bounding;}
 
} // class</langsyntaxhighlight>
{{out}}
<pre>
Line 1,870 ⟶ 4,784:
sunglasses 7 dag (value = 20)
socks 4 dag (value = 50)
</pre>
 
=={{header|JavaScript}}==
Also available at [https://gist.github.com/truher/4715551|this gist].
<syntaxhighlight lang="javascript">/*global portviz:false, _:false */
/*
* 0-1 knapsack solution, recursive, memoized, approximate.
*
* credits:
*
* the Go implementation here:
* http://rosettacode.org/mw/index.php?title=Knapsack_problem/0-1
*
* approximation details here:
* http://math.mit.edu/~goemans/18434S06/knapsack-katherine.pdf
*/
portviz.knapsack = {};
(function() {
this.combiner = function(items, weightfn, valuefn) {
// approximation guarantees result >= (1-e) * optimal
var _epsilon = 0.01;
var _p = _.max(_.map(items,valuefn));
var _k = _epsilon * _p / items.length;
var _memo = (function(){
var _mem = {};
var _key = function(i, w) {
return i + '::' + w;
};
return {
get: function(i, w) {
return _mem[_key(i,w)];
},
put: function(i, w, r) {
_mem[_key(i,w)]=r;
return r;
}
};
})();
var _m = function(i, w) {
i = Math.round(i);
w = Math.round(w);
if (i < 0 || w === 0) {
// empty base case
return {items: [], totalWeight: 0, totalValue: 0};
}
var mm = _memo.get(i,w);
if (!_.isUndefined(mm)) {
return mm;
}
var item = items[i];
if (weightfn(item) > w) {
//item does not fit, try the next item
return _memo.put(i, w, _m(i-1, w));
}
// this item could fit.
// are we better off excluding it?
var excluded = _m(i-1, w);
// or including it?
var included = _m(i-1, w - weightfn(item));
if (included.totalValue + Math.floor(valuefn(item)/_k) > excluded.totalValue) {
// better off including it
// make a copy of the list
var i1 = included.items.slice();
i1.push(item);
return _memo.put(i, w,
{items: i1,
totalWeight: included.totalWeight + weightfn(item),
totalValue: included.totalValue + Math.floor(valuefn(item)/_k)});
}
//better off excluding it
return _memo.put(i,w, excluded);
};
return {
/* one point */
one: function(maxweight) {
var scaled = _m(items.length - 1, maxweight);
return {
items: scaled.items,
totalWeight: scaled.totalWeight,
totalValue: scaled.totalValue * _k
};
},
/* the entire EF */
ef: function(maxweight, step) {
return _.map(_.range(0, maxweight+1, step), function(weight) {
var scaled = _m(items.length - 1, weight);
return {
items: scaled.items,
totalWeight: scaled.totalWeight,
totalValue: scaled.totalValue * _k
};
});
}
};
};
}).apply(portviz.knapsack);
 
/*global portviz:false, _:false */
/*
* after rosettacode.org/mw/index.php?title=Knapsack_problem/0-1
*/
var allwants = [
{name:"map", weight:9, value: 150},
{name:"compass", weight:13, value: 35},
{name:"water", weight:153, value: 200},
{name:"sandwich", weight: 50, value: 160},
{name:"glucose", weight:15, value: 60},
{name:"tin", weight:68, value: 45},
{name:"banana", weight:27, value: 60},
{name:"apple", weight:39, value: 40},
{name:"cheese", weight:23, value: 30},
{name:"beer", weight:52, value: 10},
{name:"suntan cream", weight:11, value: 70},
{name:"camera", weight:32, value: 30},
{name:"T-shirt", weight:24, value: 15},
{name:"trousers", weight:48, value: 10},
{name:"umbrella", weight:73, value: 40},
{name:"waterproof trousers", weight:42, value: 70},
{name:"waterproof overclothes", weight:43, value: 75},
{name:"note-case", weight:22, value: 80},
{name:"sunglasses", weight:7, value: 20},
{name:"towel", weight:18, value: 12},
{name:"socks", weight:4, value: 50},
{name:"book", weight:30, value: 10}
];
var near = function(actual, expected, tolerance) {
if (expected === 0 && actual === 0) return true;
if (expected === 0) {
return Math.abs(expected - actual) / actual < tolerance;
}
return Math.abs(expected - actual) / expected < tolerance;
};
test("one knapsack", function() {
var combiner =
portviz.knapsack.combiner(allwants,
function(x){return x.weight;},
function(x){return x.value;});
var oneport = combiner.one(400);
ok(near(oneport.totalValue, 1030, 0.01), "correct total value");
ok(near(oneport.totalValue, 1030, 0.01), "correct total value");
equal(oneport.totalWeight, 396, "correct total weight");
});
test("frontier", function() {
var combiner =
portviz.knapsack.combiner(allwants,
function(x){return x.weight;},
function(x){return x.value;});
var ef = combiner.ef(400, 1);
equal(ef.length, 401, "401 because it includes the endpoints");
ef = combiner.ef(400, 40);
equal(ef.length, 11, "11 because it includes the endpoints");
var expectedTotalValue = [
0,
330,
445,
590,
685,
755,
810,
860,
902,
960,
1030
] ;
_.each(ef, function(element, index) {
// 15% error! bleah!
ok(near(element.totalValue, expectedTotalValue[index], 0.15),
'actual ' + element.totalValue + ' expected ' + expectedTotalValue[index]);
});
deepEqual(_.pluck(ef, 'totalWeight'), [
0,
39,
74,
118,
158,
200,
236,
266,
316,
354,
396
]);
deepEqual(_.map(ef, function(x){return x.items.length;}), [
0,
4,
6,
7,
9,
10,
10,
12,
14,
11,
12
]);
});</syntaxhighlight>
 
 
=={{header|JavaScript}}==
 
Knapsack 0-1 JavaScript Russian Binary ciphers
 
Russian Knapsack 0-1 synthesizes all ciphers from 0 & 1 adding left +1 register and 0 remain on left in cipher
 
Copy and save as knapsackda.htm
 
<syntaxhighlight lang="javascript">
<!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>
 
</syntaxhighlight>
 
=={{header|jq}}==
{{ works with|jq|1.4}}
 
"dynamic_knapsack(W)" implements a dynamic programming algorithm based
on computing m[i,W] as the maximum value that can be attained with
weight no greater than W using the first i items (with i = 0
corresponding to no items). Here, m[i,W] is set to [V, ary]
where ary is an array of the names of the accepted items.
<syntaxhighlight lang="jq"># 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];</syntaxhighlight>
'''Example''':
<syntaxhighlight lang="jq">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)[]</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">$jq -M -c -n -f knapsack.jq
1030
["map","compass","water","sandwich","glucose","banana","suntancream","waterproof trousers","waterproof overclothes","note-case","sunglasses","socks"]</syntaxhighlight>
 
=={{header|Julia}}==
This solution uses the [https://github.com/JuliaOpt/MathProgBase.jl MathProgBase] package (with the [https://github.com/JuliaOpt/Cbc.jl Cbc] solver package installed). It is the <code>mixintprog</code> function from this package that does the heavy lifting of this solution.
 
<code>KPDSupply</code> has one more field than is needed, <code>quant</code>. This field is may be useful in a solution to the bounded version of this task.
 
'''Type and Functions''':
<syntaxhighlight lang="julia">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</syntaxhighlight>
 
'''Main''':
<syntaxhighlight lang="julia">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), " €")</syntaxhighlight>
 
{{out}}
<pre>The hicker should pack:
- 1 map (9 kg, 150 €)
- 1 compass (13 kg, 35 €)
- 1 water (153 kg, 200 €)
- 1 sandwich (50 kg, 160 €)
- 1 glucose (15 kg, 60 €)
- 1 banana (27 kg, 60 €)
- 1 suntan cream (11 kg, 70 €)
- 1 waterproof trousers (42 kg, 70 €)
- 1 waterproof overclothes (43 kg, 75 €)
- 1 note-case (22 kg, 80 €)
- 1 sunglasses (7 kg, 20 €)
- 1 socks (4 kg, 50 €)
 
Packed weight: 396 kg
Packed value: 1030 €</pre>
 
=={{header|Kotlin}}==
{{trans|Go}}
<syntaxhighlight lang="scala">// 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")
}</syntaxhighlight>
 
{{out}}
<pre>
Knapsack Item Chosen Weight Value
---------------------- ------ -----
water 153 200
sandwich 50 160
map 9 150
note-case 22 80
waterproof overclothes 43 75
suntan cream 11 70
waterproof trousers 42 70
glucose 15 60
banana 27 60
socks 4 50
compass 13 35
sunglasses 7 20
---------------------- ------ -----
Total 12 Items Chosen 396 1030
</pre>
 
=={{header|LSL}}==
To test it yourself, rez a box on the ground, add the following as a New Script, create a notecard named "Knapsack_Problem_0_1_Data.txt" with the data shown below.
<langsyntaxhighlight LSLlang="lsl">string sNOTECARD = "Knapsack_Problem_0_1_Data.txt";
integer iMAX_WEIGHT = 400;
integer iSTRIDE = 4;
Line 1,923 ⟶ 5,336:
}
}
}</langsyntaxhighlight>
Notecard:
<pre>map, 9, 150
Line 1,947 ⟶ 5,360:
socks, 4, 50
book, 30, 10</pre>
{{out}}
Output:
<pre>Reading 'Knapsack_Problem_0_1_Data.txt'
0: map, 9, 150
Line 1,963 ⟶ 5,376:
iTotalWeight=396
iTotalValue=1030</pre>
 
=={{Header|Lua}}==
This version is adapted from the Clojure version.
<syntaxhighlight lang="lua">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)
</syntaxhighlight>
 
{{out}}
<pre>items to pack: map, compass, water, sandwich, glucose, banana, suntan cream, waterproof trousers, waterproof overclothes, note-case, sunglasses, socks
total value: 1030
total weight: 396
 
(memo count: 5329; mm call count: 9485)
</pre>
=={{header|Maple}}==
<syntaxhighlight lang="maple">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):</syntaxhighlight>
{{Out}}
<pre>Total Value is 1030
Item: socks
Item: sunglasses
Item: note-case
Item: waterproof overclothes
Item: waterproof trousers
Item: suntan cream
Item: banana
Item: glucose
Item: sandwich
Item: water
Item: compass
Item: map
Total Weight is 396</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Used the
<syntaxhighlight lang="mathematica">#[[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}}</syntaxhighlight>
{{Out}}
<pre>{"map", "compass", "water", "sandwich", "glucose", "banana", "suntan cream", "waterproof trousers", "waterproof overclothes", "note-case", "sunglasses", "socks"}</pre>
 
=={{header|Mathprog}}==
<langsyntaxhighlight lang="mathprog">/*Knapsack
This model finds the integer optimal packing of a knapsack
Line 2,010 ⟶ 5,595:
;
 
end;</langsyntaxhighlight>
The solution may be found at [[Knapsack problem/0-1/Mathprog]].
Activity=1 means take, Activity=0 means don't take.
 
=={{header|MAXScript}}==
<syntaxhighlight lang="maxscript">
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
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="maxscript">
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
</syntaxhighlight>
 
=={{header|MiniZinc}}==
<syntaxhighlight lang="minizinc">
%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)"]
</syntaxhighlight>
{{out}}
<pre>
Take {map, compass, water, sandwich, glucose, banana, suntan_cream, waterproof_trousers, waterproof_overclothes, note_case, sunglasses, socks}
Total Weight=396 Total Value=1030
</pre>
=={{header|Nim}}==
This solution uses the same algorithm as Go and Kotlin, with some modifications to improve performance:
:– use item indexes rather than items themselves;
:– rather than using sequences of item indexes, use sets of item indexes which are represented as bit sets;
:– use a cache for memoization.
 
<syntaxhighlight lang="nim">
# 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
</syntaxhighlight>
 
{{out}}
<pre>
List of items:
– map
– compass
– water
– sandwich
– glucose
– banana
– suntan cream
– waterproof trousers
– waterproof overclothes
– note-case
– sunglasses
– socks
 
Total weight: 396
Total value: 1030
</pre>
 
=={{header|OCaml}}==
A brute force solution:
<langsyntaxhighlight lang="ocaml">let items = [
"map", 9, 150;
"compass", 13, 35;
Line 2,056 ⟶ 5,856:
(List.hd poss) (List.tl poss) in
List.iter (fun (name,_,_) -> print_endline name) res;
;;</langsyntaxhighlight>
 
=={{header|Oz}}==
Using constraint programming.
<langsyntaxhighlight lang="oz">declare
%% maps items to pairs of Weight(hectogram) and Value
Problem = knapsack('map':9#150
Line 2,123 ⟶ 5,923:
{System.printInfo "\n"}
{System.showInfo "total value: "#{Value Best}}
{System.showInfo "total weight: "#{Weight Best}}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,144 ⟶ 5,944:
</pre>
Typically runs in less than 150 milliseconds.
 
=={{header|Pascal}}==
Uses a stringlist to store the items. I used the algorithm given on Wikipedia (Knapsack problem) to find the maximum value. It is written in pseudocode that translates very easily to Pascal.
<syntaxhighlight lang="pascal">
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.
</syntaxhighlight>
 
Output
<pre>
Highest total value : 1030
Number of items : 12
-------------------------
map 9 150
compass 13 35
water 153 200
sandwich 50 160
glucose 15 60
banana 27 60
suntancreme 11 70
waterprooftrousers 42 70
waterproofoverclothes 43 75
notecase 22 80
sunglasses 7 20
socks 4 50
-------------------------
done
</pre>
 
=={{header|Perl}}==
The dynamic programming solution from Wikipedia.
<langsyntaxhighlight lang="perl">my $raw = <<'TABLE';
map 9 150
compass 13 35
Line 2,174 ⟶ 6,088:
my (@name, @weight, @value);
for (split "\n", $raw) {
for ([ split /\t+/ ]) {
push @name, $_->[0];
push @weight, $_->[1];
push @value, $_->[2];
}
}
 
my $max_weight = 400;
my @p = (map([[0, []], map undef, 0 .. 1+$max_weight], 0 .. $#name),;
[ map([0, []], 0 .. $max_weight + 1)]);
 
sub optimal {
my ($i, $w) = @_;
return [0, []] if $i < 0;
return $p[$i][$w] if $p[$i][$w];
 
if (!defined $pweight[$i][ > $w]) {
if ($weightp[$i][$w] >= optimal($i - 1, $w) {
} else {
$p[$i][$w] = optimal($i - 1, $w)
my $x = optimal($i - 1, } else {$w);
my $xy = optimal($i - 1, $w - $weight[$i]);
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] ]]
[ @{$y->[1]}, $name[$i] ]]
}
}
}
}
return $p[$i][$w]
return $p[$i][$w]
}
 
my $solsolution = optimal($#name, $max_weight);
print "$solsolution->[0]: @{$solsolution->[1]}\n";</syntaxhighlight>
{{out}}
<pre>1030: map compass water sandwich glucose banana suntancream waterproof trousers waterproof overclothes note-case sunglasses socks</pre>
 
=={{header|Phix}}==
# prints:
Trivial simplification of the [[Knapsack_problem/Bounded#Phix|Knapsack/Bounded]] solution. By careful ordering we can ensure we find the optimal solution first (see terminate flag).
# 1030: map compass water sandwich glucose banana suntancream waterproof trousers
<!--<syntaxhighlight lang="phix">(phixonline)-->
# waterproof overclothes note-case sunglasses socks</lang>
<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>
=={{header|Perl 6}}==
{{works with|niecza|2012-02-17}}
<lang perl6>my class KnapsackItem { has $.name; has $.weight; has $.unit; }
<span style="color: #004080;">bool</span> <span style="color: #000000;">terminate</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
multi sub pokem ([], $, $v = 0) { $v }
multi sub pokem ([$, *@], 0, $v = 0) { $v }
multi sub pokem ([$i, *@rest], $w, $v = 0) {
my $key = "{+@rest} $w $v";
(state %cache){$key} or do {
my @skip = pokem @rest, $w, $v;
if $w >= $i.weight { # next one fits
my @put = pokem @rest, $w - $i.weight, $v + $i.unit;
return (%cache{$key} = @put, $i.name).list if @put[0] > @skip[0];
}
return (%cache{$key} = @skip).list;
}
}
<span style="color: #004080;">integer</span> <span style="color: #000000;">attempts</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
my $MAX_WEIGHT = 400;
<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>
my @table = map -> $name, $weight, $unit {
<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>
KnapsackItem.new: :$name, :$weight, :$unit;
<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>
'map', 9, 150,
<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>
'compass', 13, 35,
<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>
'water', 153, 200,
<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>
'sandwich', 50, 160,
<span style="color: #000000;">attempts</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
'glucose', 15, 60,
<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>
'tin', 68, 45,
<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>
'banana', 27, 60,
<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>
'apple', 39, 40,
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
'cheese', 23, 30,
<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>
'beer', 52, 10,
<span style="color: #008080;">else</span>
'suntan cream', 11, 70,
<span style="color: #000080;font-style:italic;">-- while n&gt;=0 do -- full exhaustive search</span>
'camera', 32, 30,
<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>
'T-shirt', 24, 15,
<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>
'trousers', 48, 10,
<span style="color: #000000;">n</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
'umbrella', 73, 40,
<span style="color: #000000;">chosen</span><span style="color: #0000FF;">[$]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
'waterproof trousers', 42, 70,
<span style="color: #000000;">points</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">pitem</span>
'waterproof overclothes', 43, 75,
<span style="color: #000000;">weight</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">witem</span>
'note-case', 22, 80,
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
'sunglasses', 7, 20,
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
'towel', 18, 12,
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
'socks', 4, 50,
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
'book', 30, 10;
<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>
my ($value, @result) = pokem @table, $MAX_WEIGHT;
<span style="color: #000080;font-style:italic;">-- sort by weight/value</span>
say "Value = $value\nTourist put in the bag:\n " ~ @result;</lang>
<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>
<!--</syntaxhighlight>-->
{{out}}
<pre>
<pre>% perl6 knapsack1.p6
Value = 1030, weight 396 [9 attempts, 0.00s]:
map
Tourist put in the bag:
socks
socks sunglasses note-case waterproof overclothes waterproof trousers suntan cream banana glucose sandwich water compass map</pre>
suntan cream
glucose
note-case
sandwich
sunglasses
compass
banana
waterproof overclothes
waterproof trousers
water
</pre>
without the optimisation (ie "and not terminate" removed, full exhaustive search, further lines as above):
<pre>
Value 1030, weight 396 [1216430 attempts, 0.84s]:
</pre>
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php">#########################################################
# 0-1 Knapsack Problem Solve with memoization optimize and index returns
# $w = weight of item
Line 2,276 ⟶ 6,230:
# PHP Translation from Python, Memoization,
# and index return functionality added by Brian Berneker
#
#It works uncorrectly! For examle if $aw=4. Max value is true, but no "Array Indices" and its parameters are displayed
#
#########################################################
 
function knapSolveFast2($w, $v, $i, $aW, &$m) {
 
global $numcalls;
Line 2,309 ⟶ 6,261:
// Not at end of decision branch..
// Get the result of the next branch (without this one)
list ($without_i, $without_PI) = knapSolveFast2($w, $v, $i-1, $aW, $m,$pickedItems);
 
if ($w[$i] > $aW) { // Does it return too many?
$m[$i][$aW] = $without_i; // Memo without including this one
$m['picked'][$i][$aW] = array()$without_PI; // and a blank array entry...
return array($without_i,array() $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,$pickedItems);
$with_i += $v[$i]; // ..and add the value of this one..
Line 2,350 ⟶ 6,302:
 
## Solve
list ($m4,$pickedItems) = knapSolveFast2($w4, $v4, sizeof($v4) -1, 400, $m,$pickedItems);
 
# Display Result
Line 2,361 ⟶ 6,313:
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];
Line 2,367 ⟶ 6,320:
}
echo "<tr><td align=right><b>Totals</b></td><td>$totalVal</td><td>$totalWt</td></tr>";
echo "</table><hr>";</langsyntaxhighlight>
{{out}}
<div class="solutionoutput">
Line 2,373 ⟶ 6,326:
</div>
Minimal PHP Algorithm for totals only translated from Python version as discussed in the YouTube posted video at: http://www.youtube.com/watch?v=ZKBUu_ahSR4
<langsyntaxhighlight lang="php">#########################################################
# 0-1 Knapsack Problem Solve
# $w = weight of item
Line 2,466 ⟶ 6,419:
$m3 = knapSolve($w3, $v3, sizeof($v3) -1, 54 );
print_r($w3); echo "<br>";
echo "<b>Max: $m3</b> ($numcalls calls)<br><br>";</langsyntaxhighlight>
{{out}}
<pre>
Line 2,475 ⟶ 6,428:
Max: 54 (828 calls)
</pre>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">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.</syntaxhighlight>
 
{{out}}
<pre>These are the items to pick:
Item Weight Value
* map 9 150
* compass 13 35
* water 153 200
* sandwich 50 160
* glucose 15 60
* banana 27 60
* suntancream 11 70
* waterproof trousers 42 70
* waterproof overclothes 43 75
* note-case 22 80
* sunglasses 7 20
* socks 4 50
 
Total weight: 396
Total value: 1030</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de *Items
("map" 9 150) ("compass" 13 35)
("water" 153 200) ("sandwich" 50 160)
Line 2,493 ⟶ 6,536:
(de knapsack (Lst W)
(when Lst
(cache '*KnapCache (packcons (lengthW Lst) ":" W)
(let X (knapsack (cdr Lst) W)
(if (ge0 (- W (cadar Lst)))
Line 2,503 ⟶ 6,546:
(for I K
(apply tab I (3 -24 6 6) NIL) )
(tab (27 6 6) NIL (sum cadr K) (sum caddr K)) )</langsyntaxhighlight>
{{out}}
<pre>
Line 2,525 ⟶ 6,568:
===Using the clpfd library===
{{libheader|clpfd}}
<langsyntaxhighlight Prologlang="prolog">:- use_module(library(clpfd)).
 
knapsack :-
Line 2,594 ⟶ 6,637:
sformat(W3, A3, [V]),
format('~w~w~w~n', [W1,W2,W3]),
print_results(A1, A2, A3, T, TR, WM, VM).</langsyntaxhighlight>
{{out}}
<pre>
Line 2,615 ⟶ 6,658:
{{libheader|simplex}}
Library written by <b>Markus Triska</b>. The problem is solved in about 3 seconds.
<langsyntaxhighlight Prologlang="prolog">:- use_module(library(simplex)).
 
knapsack :-
Line 2,692 ⟶ 6,735:
W2 is W1 + W,
V2 is V1 + V),
print_results(S, A1, A2, A3, T, TN, W2, V2).</langsyntaxhighlight>
 
=={{header|PureBasic}}==
Solution uses memoization.
<langsyntaxhighlight PureBasiclang="purebasic">Structure item
name.s
weight.i ;units are dekagrams (dag)
Line 2,811 ⟶ 6,854:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf </langsyntaxhighlight>
{{out}}
<pre>
Line 2,829 ⟶ 6,872:
TOTALS: 396 1030
</pre>
 
=={{header|QB64}}==
Russian Knapsack 0-1 synthesizes all ciphers from 0 & 1
adding left +1 register and 0 remain on left in cipher
 
Number of comparisons decreases from N! to 2^N
for example N=8 N!=40320 >> 2^N=256
 
Random values origin are automatically assigned
create integral of quantity and quality
 
Program write results to qb64 directory
<syntaxhighlight lang="qbasic">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</syntaxhighlight>
 
Main thing is very brief and clear to even all<br/><br/>
 
Results is reduced manually:
{{out}}
<pre> # Mass Cost
1 2 17
2 2 14
3 2 17
4 1 11
5 2 18
6 3 14
7 3 10
 
Mass Cost Chifer
5 73 1101000
2 28 0100000
5 81 0011100 !!!
3 45 0011000
5 76 0010010
2 36 0000100
 
Mass MAX Chifer
5 81 0011100</pre>
 
=={{header|Python}}==
===Brute force algorithm===
<langsyntaxhighlight lang="python">from itertools import combinations
 
def anycomb(items):
Line 2,862 ⟶ 6,965:
'\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))</langsyntaxhighlight>
{{out}}
<pre>
Line 2,881 ⟶ 6,984:
</pre>
=== Dynamic programming solution ===
<langsyntaxhighlight lang="python">try:
xrange
except:
Line 2,933 ⟶ 7,036:
'\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))</langsyntaxhighlight>
===Recursive dynamic programming algorithm===
<syntaxhighlight lang="python">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)
=={{header|REXX}}==
print "items:"
Originally, the combination generator/checker subroutine (SIM) was recursive and made the program solution generic (and very concise).
for x in solution:
print x[0]
print "value:", total_value(solution, max_weight)
print "weight:", sum([x[1] for x in solution])</syntaxhighlight>
 
However, a recursive solution also made the solution much more slower, so the combination generator/checker was "unrolled" and converted into discrete combination checks (based on the number of items). The unused combinatorial checks were discarded and only the pertinent code was retained. It made no sense to include all the unused subroutines here as space appears to be a premium for some entries in Rosetta Code.
<lang rexx>/*REXX pgm solves a knapsack problem (22 items with weight restriction).*/
@.=''
@.1 = 'map 9 150'
@.2 = 'compass 13 35'
@.3 = 'water 153 200'
@.4 = 'sandwich 50 160'
@.5 = 'glucose 15 60'
@.6 = 'tin 68 45'
@.7 = 'banana 27 60'
@.8 = 'apple 39 40'
@.9 = 'cheese 23 30'
@.10 = 'beer 52 10'
@.11 = 'suntan_cream 11 70'
@.12 = 'camera 32 30'
@.13 = 'T-shirt 24 15'
@.14 = 'trousers 48 10'
@.15 = 'umbrella 73 40'
@.16 = 'waterproof_trousers 42 70'
@.17 = 'waterproof_overclothes 43 75'
@.18 = 'note-case 22 80'
@.19 = 'sunglasses 7 20'
@.20 = 'towel 18 12'
@.21 = 'socks 4 50'
@.22 = 'book 30 10'
 
maxWeight=400 /*the maximum weight for knapsack*/
say 'maximum weight allowed for a knapsack:' comma(maxWeight); say
maxL=length('item') /*maximum width for table names. */
maxL=length('knapsack items') /*maximum width for table names. */
maxW=length('weight') /* " " " " weights*/
maxV=length('value') /* " " " " values.*/
maxQ=length('pieces') /* " " " " quant. */
highQ=0 /*max quantity specified (if any)*/
items=0; i.=''; w.=0; v.=0; q.=0; Tw=0; Tv=0; Tq=0 /*initialize stuff.*/
 
===Python Russian Binary ciphers===
/*────────────────────────────────sort the choices by decreasing weight.*/
do j=1 while @.j\=='' /*process each choice and sort. */
_=@.j; _wt=word(_,2) /*choose first item (arbitrary). */
_wt=word(_,2)
do k=j+1 while @.k\=='' /*find a possible heavier item. */
?wt=word(@.k,2)
if ?wt>_wt then do; _=@.k; @.k=@.j; @.j=_; _wt=?wt; end
end /*k*/
end /*j*/
 
Russian Knapsack 0-1 synthesizes all ciphers from 0 & 1 adding left +1 register and 0 remain on left in cipher
obj=j-1 /*adjust for the DO loop index. */
 
Number of comparisons decreases from N! to 2^N for example N=8 N!=40320 >> 2^N=256
/*────────────────────────────────build list of choices.────────────────*/
do j=1 for obj /*build a list of choices. */
_=space(@.j) /*remove superflous blanks. */
parse var _ item w v q . /*parse original choice for table*/
Tw=Tw+w; Tv=Tv+v; Tq=Tq+1 /*add totals up (for alignment). */
if w>maxWeight then iterate /*ignore if the weight > maximum.*/
maxL=max(maxL,length(item)) /*find maximum width for item. */
if q=='' then q=1
highQ=max(highQ,q)
items=items+1 /*bump the item counter. */
@@.items=translate(_,','," ") /*make: item,weight,value */
i.items=item; w.items=w; v.items=v; q.items=q
do k=2 to q
items=items+1 /*bump the item counter. */
i.items=item; w.items=w; v.items=v; q.items=q
Tw=Tw+w; Tv=Tv+v; Tq=Tq+1
_=item# w v
@@.items=translate(_,','," ")
end /*k*/
end /*j*/
 
Random values origin are automatically assigned create integral of quantity and quality
maxW=max(maxW,length(comma(Tw))) /*find maximum width for weight. */
maxV=max(maxV,length(comma(Tv))) /* " " " " value. */
maxQ=max(maxQ,length(comma(Tq))) /* " " " " quantity*/
maxL=maxL+maxL%4+4 /*extend width of name for table.*/
 
<syntaxhighlight lang="python">n=5; N=n+1; G=5; a=2**N # KNAPSACK 0-1 DANILIN
/*────────────────────────────────show the list of choices.─────────────*/
L=[];C=[];e=[];j=[];q=[];s=[] # rextester.com/BCKP19591
call hdr
d=[];L=[1]*n;C=[1]*n;e=[1]*a
do j=1 for obj /*show all choices, nice format. */
j=[1]*n;q=[0]*a;s=[0]*a;d=[0]*a
parse var @.j item weight value q .
if highq==1 then q=''
else if q=='' then q=1
call show item,weight,value,q
end /*j*/
say
say 'number of items:' items
say
 
from random import randint
/*─────────────────────────────────────examine the possible choices. */
for i in range(0,n):
h=items; ho=h+1; m=maxWeight; $=0; call sim22
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):
/*─────────────────────────────────────show the best choice (weidht,val)*/
b=str(bin(h))
do h-1; ?=strip(strip(?),"L",0); end
e[h]=b[3:len(b)]
bestC=?
bestW=0
for k in range (n):
bestV=$
j[k]=int(e[h][k])
highQ=0
q[h]=q[h]+L[k]*j[k]*C[k]
call hdr 'best choice'
d[h]=d[h]+L[k]*j[k]
totP=words(bestC)
do j=1 to totP /*J is modified within DO loop. */
if d[h]<= G:
_=word(bestC,j); _w=w._; _v=v._; q=1
print(e[h], G, d[h], q[h])
do k=j+1 to totP
print()
__=word(bestC,k); if i._\==i.__ then leave
j=j+1; w._=w._+_w; v._=v._+_v; q=q+1
end /*k*/
call show i._,w._,v._,q
bestW=bestw+w._
end /*j*/
call hdr2; say
call show 'best weight' ,bestW /*show a nicely formatted winnerW*/
call show 'best value' ,,bestV /*show a nicely formatted winnerV*/
call show 'knapsack items',,,totP /*show a nicely formatted pieces.*/
exit /*stick a fork in it, we're done.*/
 
max=0; m=1
/*────────────────────────────────COMMA subroutine──────────────────────*/
for i in range(a):
comma: procedure; parse arg _,c,p,t; arg ,cu; c=word(c ",",1)
if d[i]<=G and q[i]>max:
if cu=='BLANK' then c=' '; o=word(p 3,1); p=abs(o); t=word(t 999999999,1)
max=q[i]; m=i
if \datatype(p,'W') | \datatype(t,"W")|p==0|arg()>4 then return _; n=_'.9'
print (d[m], q[m], e[m])</syntaxhighlight>
#=123456789; k=0; if o<0 then do; b=verify(_,' '); if b==0 then return _
e=length(_) - verify(reverse(_),' ') + 1; end; else do; b=verify(n,#,"M")
e=verify(n,#'0',,verify(n,#"0.",'M'))-p-1; end
do j=e to b by -p while k<t; _=insert(c,_,j); k=k+1; end; return _
/*────────────────────────────────HDR subroutine────────────────────────*/
hdr: say; _=''; if highq\==1 then _=center('pieces',maxq)
_item_=arg(1); if _item_=='' then _item_='item'
call show center( _item_ ,maxL),,
center('weight',maxW),,
center('value' ,maxV),,
center(_ ,maxQ)
call hdr2
return
/*────────────────────────────────HDR2 subroutine───────────────────────*/
hdr2: _=maxQ; if highq==1 then _=0
call show copies('=',maxL),,
copies('=',maxW),,
copies('=',maxV),,
copies('=',_ )
return
/*────────────────────────────────J? subroutine─────────────────────────*/
j?: parse arg _,?; $=value('V'_); do j=1 for _; ?=? value('J'j); end; return
/*────────────────────────────────SHOW subroutine───────────────────────*/
show: parse arg _item,_weight,_value,_quant
say translate(left(_item,maxL,'─'),,'_'),
right(comma(_weight),maxW),
right(comma(_value ),maxV),
right(comma(_quant ),maxQ)
return
/*────────────────────────────────SIM22 subroutine──────────────────────*/
sim22: do j1=0 for h+1
w1=w.j1;v1=v.j1;if v1>$ then call j? 1
do j2=j1+(j1\==0) to h
if w.j2+w1>m then iterate j1;w2=w1+w.j2;v2=v1+v.j2;if v2>$ then call j? 2
do j3=j2+(j2\==0) to h
if w.j3+w2>m then iterate j2;w3=w2+w.j3;v3=v2+v.j3;if v3>$ then call j? 3
do j4=j3+(j3\==0) to h
if w.j4+w3>m then iterate j3;w4=w3+w.j4;v4=v3+v.j4;if v4>$ then call j? 4
do j5=j4+(j4\==0) to h
if w.j5+w4>m then iterate j4;w5=w4+w.j5;v5=v4+v.j5;if v5>$ then call j? 5
do j6=j5+(j5\==0) to h
if w.j6+w5>m then iterate j5;w6=w5+w.j6;v6=v5+v.j6;if v6>$ then call j? 6
do j7=j6+(j6\==0) to h
if w.j7+w6>m then iterate j6;w7=w6+w.j7;v7=v6+v.j7;if v7>$ then call j? 7
do j8=j7+(j7\==0) to h
if w.j8+w7>m then iterate j7;w8=w7+w.j8;v8=v7+v.j8;if v8>$ then call j? 8
do j9=j8+(j8\==0) to h
if w.j9+w8>m then iterate j8;w9=w8+w.j9;v9=v8+v.j9;if v9>$ then call j? 9
do j10=j9+(j9\==0) to h
if w.j10+w9>m then iterate j9;w10=w9+w.j10;v10=v9+v.j10;if v10>$ then call j? 10
do j11=j10+(j10\==0) to h
if w.j11+w10>m then iterate j10;w11=w10+w.j11;v11=v10+v.j11;if v11>$ then call j? 11
do j12=j11+(j11\==0) to h
if w.j12+w11>m then iterate j11;w12=w11+w.j12;v12=v11+v.j12;if v12>$ then call j? 12
do j13=j12+(j12\==0) to h
if w.j13+w12>m then iterate j12;w13=w12+w.j13;v13=v12+v.j13;if v13>$ then call j? 13
do j14=j13+(j13\==0) to h
if w.j14+w13>m then iterate j13;w14=w13+w.j14;v14=v13+v.j14;if v14>$ then call j? 14
do j15=j14+(j14\==0) to h
if w.j15+w14>m then iterate j14;w15=w14+w.j15;v15=v14+v.j15;if v15>$ then call j? 15
do j16=j15+(j15\==0) to h
if w.j16+w15>m then iterate j15;w16=w15+w.j16;v16=v15+v.j16;if v16>$ then call j? 16
do j17=j16+(j16\==0) to h
if w.j17+w16>m then iterate j16;w17=w16+w.j17;v17=v16+v.j17;if v17>$ then call j? 17
do j18=j17+(j17\==0) to h
if w.j18+w17>m then iterate j17;w18=w17+w.j18;v18=v17+v.j18;if v18>$ then call j? 18
do j19=j18+(j18\==0) to h
if w.j19+w18>m then iterate j18;w19=w18+w.j19;v19=v18+v.j19;if v19>$ then call j? 19
do j20=j19+(j19\==0) to h
if w.j20+w19>m then iterate j19;w20=w19+w.j20;v20=v19+v.j20;if v20>$ then call j? 20
do j21=j20+(j20\==0) to h
if w.j21+w20>m then iterate j20;w21=w20+w.j21;v21=v20+v.j21;if v21>$ then call j? 21
do j22=j21+(j21\==0) to h
if w.j22+w21>m then iterate j21;w22=w21+w.j22;v22=v21+v.j22;if v22>$ then call j? 22
end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end
return</lang>
{{out}}
<pre># Mass Cost
<pre style="height:40ex;overflow:scroll">
1 2 12
2 3 17
3 1 14
4 3 17
5 1 13
Chifer Mass Cost
11000 5 5 75
10101 5 4 51
01001 5 4 64
00111 5 5 78 !!!
00110 5 4 65
00101 5 2 27
00000 5 0 0
Mass MAX Chifer
5 78 00111</pre>
 
=={{header|R}}==
<syntaxhighlight lang="r">
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)
 
</syntaxhighlight>
 
{{out}}
<syntaxhighlight lang="text">
[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"
</syntaxhighlight>
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
#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)))
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="racket">
'(1030 396 (map compass water sandwich glucose banana cream trousers overclothes notecase glasses socks))
</syntaxhighlight>
Brute Force and Memoized Recursive Alternate
<syntaxhighlight lang="racket">
#lang racket
 
(define items '((map 9 150) (compass 13 35) (water 153 200) (sandwich 50 160)
(glucose 15 60) (tin 68 45)(banana 27 60) (apple 39 40)
(cheese 23 30) (beer 52 10) (cream 11 70) (camera 32 30)
(T-shirt 24 15) (trousers 48 10) (umbrella 73 40)
(trousers 42 70) (overclothes 43 75) (notecase 22 80)
(glasses 7 20) (towel 18 12) (socks 4 50) (book 30 10)))
 
(define max-weight 400)
 
(define (item-value item)
(caddr item))
 
(define (item-weight item)
(cadr item))
 
(define (pack-weight pack)
(apply + (map item-weight pack)))
 
(define (pack-value pack)
(apply + (map item-value pack)))
 
(define (max-pack-value pack-with pack-without max-weight)
(if (and
(not (> (pack-weight pack-with) max-weight))
(> (pack-value pack-with) (pack-value pack-without)))
pack-with pack-without))
 
(define (display-solution pack)
(displayln (list 'weight: (pack-weight pack)
'value: (pack-value pack)
'items: (map car pack))))
</syntaxhighlight>
Brute Force
<syntaxhighlight lang="racket">
(define (show-brute)
 
(define empty-accumulator '())
(define (knapsack-brute included items)
(cond
((null? items) included)
(else
(max-pack-value
(knapsack-brute (cons (car items) included) (cdr items))
(knapsack-brute included (cdr items))
max-weight
))))
(display-solution (reverse (knapsack-brute empty-accumulator items))))
 
(show-brute); takes around five seconds on my machine
</syntaxhighlight>
Recursive Alternate
<syntaxhighlight lang="racket">
(define (show-memoized)
 
(define (memoize func)
(let ([result-ht (make-hash)])
(lambda args ; this is the rest-id pattern
(when (not (hash-has-key? result-ht args))
(hash-set! result-ht args (apply func args)))
(hash-ref result-ht args))))
(define knapsack
(memoize
(lambda (max-weight items)
(cond
((null? items) '())
(else
(let ([item (car items)] [items (cdr items)])
(max-pack-value
(cons item (knapsack (- max-weight (item-weight item)) items))
(knapsack max-weight items)
max-weight)))))))
(display-solution (knapsack max-weight items)))
 
(show-memoized)
</syntaxhighlight>
 
{{out}}
<syntaxhighlight lang="racket">
(weight: 396 value: 1030 items: (map compass water sandwich glucose banana cream trousers overclothes notecase glasses socks))
</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
==== Brute force ====
{{works with|Rakudo|2017.01}}
<syntaxhighlight lang="raku" line>my class KnapsackItem { has $.name; has $.weight; has $.unit; }
 
multi sub pokem ([], $, $v = 0) { $v }
multi sub pokem ([$, *@], 0, $v = 0) { $v }
multi sub pokem ([$i, *@rest], $w, $v = 0) {
my $key = "{+@rest} $w $v";
(state %cache){$key} or do {
my @skip = pokem @rest, $w, $v;
if $w >= $i.weight { # next one fits
my @put = pokem @rest, $w - $i.weight, $v + $i.unit;
return (%cache{$key} = |@put, $i.name).list if @put[0] > @skip[0];
}
return (%cache{$key} = |@skip).list;
}
}
 
my $MAX_WEIGHT = 400;
my @table = flat map -> $name, $weight, $unit {
KnapsackItem.new: :$name, :$weight, :$unit;
},
'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;
 
my ($value, @result) = pokem @table, $MAX_WEIGHT;
say "Value = $value\nTourist put in the bag:\n " ~ @result;</syntaxhighlight>
{{out}}
<pre>Value = 1030
Tourist put in the bag:
socks sunglasses note-case waterproof overclothes waterproof trousers suntan cream banana glucose sandwich water compass map</pre>
 
==== Dynamic programming ====
Much faster than the previous example.
{{trans|Perl}}
<syntaxhighlight lang="raku" line>my $raw = q:to/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 $raw.lines.sort({-($_ ~~ m/\d+/)}).comb(/\S+[\s\S+]*/) -> $n, $w, $v {
@name.push: $n;
@weight.push: $w;
@value.push: $v;
}
 
my $sum = 400;
 
my @subset;
 
sub optimal ($item, $sub-sum) {
return 0, [] if $item < 0;
return |@subset[$item][$sub-sum] if @subset[$item][$sub-sum];
 
my @next = optimal($item-1, $sub-sum);
 
if @weight[$item] > $sub-sum {
@subset[$item][$sub-sum] = @next
} else {
my @skip = optimal($item-1, $sub-sum - @weight[$item]);
 
if (@next[0] > @skip[0] + @value[$item] ) {
@subset[$item][$sub-sum] = @next;
} else {
@subset[$item][$sub-sum] = @skip[0] + @value[$item], [|@skip[1], @name[$item]];
}
}
 
|@subset[$item][$sub-sum]
}
 
my @solution = optimal(@name.end, $sum);
put "@solution[0]: ", @solution[1].sort.join(', ');</syntaxhighlight>
{{out}}
<pre>1030: banana, compass, glucose, map, note-case, sandwich, socks, sunglasses, suntancream, water, waterproof overclothes, waterproof trousers
</pre>
 
=={{header|REXX}}==
Originally, the combination generator/checker subroutine was recursive and made the program solution generic (and more concise).
 
However, a recursive solution also made the solution much more slower, so the combination generator/checker was "unrolled" and converted into discrete combination checks (based on the number of allowable items). &nbsp; The unused combinatorial checks were discarded and only the pertinent code was retained. &nbsp; It made no sense to include all the unused subroutines here as space appears to be a premium for some entries in Rosetta Code.
 
The term &nbsp; ''allowable items'' &nbsp; refers to all items that are of allowable weight (those that weigh within the weight criteria). &nbsp; An half metric─ton anvil was added to the list to show how overweight items are pruned from the list of items.
<syntaxhighlight lang="rexx">/*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*/</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
maximum weight allowed for a knapsack: 400
 
item weight value
=============================== ====== =====
water────────────────────────── 153 200
umbrella─────────────────────── 73 40
tin──────────────────────────── 68 45
beer─────────────────────────── 52 10
sandwich─────────────────────── 50 160
trousers─────────────────────── 48 10
waterproof overclothes───────── 43 75
waterproof trousers──────────── 42 70
apple────────────────────────── 39 40
camera───────────────────────── 32 30
book─────────────────────────── 30 10
banana───────────────────────── 27 60
T-shirt──────────────────────── 24 15
cheese───────────────────────── 23 30
note-case────────────────────── 22 80
towel────────────────────────── 18 12
glucose──────────────────────── 15 60
compass──────────────────────── 13 35
suntan cream─────────────────── 11 70
map──────────────────────────── 9 150
sunglasses───────────────────── 7 20
socks────────────────────────── 4 50
 
potential knapsack items weight value
number of items: 22
══════════════════════════════════ ══════ ═════
water───────────────────────────── 153 200
umbrella────────────────────────── 73 40
tin─────────────────────────────── 68 45
beer────────────────────────────── 52 10
sandwich────────────────────────── 50 160
trousers────────────────────────── 48 10
waterproof overclothes──────────── 43 75
waterproof trousers─────────────── 42 70
apple───────────────────────────── 39 40
camera──────────────────────────── 32 30
book────────────────────────────── 30 10
banana──────────────────────────── 27 60
T-shirt─────────────────────────── 24 15
cheese──────────────────────────── 23 30
note-case───────────────────────── 22 80
towel───────────────────────────── 18 12
glucose─────────────────────────── 15 60
compass─────────────────────────── 13 35
suntan cream────────────────────── 11 70
map─────────────────────────────── 9 150
sunglasses──────────────────────── 7 20
socks───────────────────────────── 4 50
 
number of allowable items: 22
 
 
best choice weight value pieces
══════════════════════════════════ ══════ ═════
=============================== ====== ===== ======
water───────────────────────────── 153 200
water────────────────────────── 153 200 1
sandwich────────────────────────── 50 160
sandwich─────────────────────── 50 160 1
waterproof overclothes─────────overclothes──────────── 43 75 1
waterproof trousers────────────trousers─────────────── 42 70 1
banana──────────────────────────── 27 60
banana───────────────────────── 27 60 1
note-case───────────────────────── 22 80
note-case────────────────────── 22 80 1
glucose─────────────────────────── 15 60
glucose──────────────────────── 15 60 1
compass─────────────────────────── 13 35
compass──────────────────────── 13 35 1
suntan cream───────────────────cream────────────────────── 11 70 1
map─────────────────────────────── 9 150
map──────────────────────────── 9 150 1
sunglasses──────────────────────── 7 20
sunglasses───────────────────── 7 20 1
socks───────────────────────────── 4 50
socks────────────────────────── 4 50 1
══════════════════════════════════ ══════ ═════
=============================== ====== ===== ======
 
best total knapsack weight──────── 396
best weight──────────────────── 396
best value─────────────────────total knapsack value───────── 1,030
best total knapsack items───────── 12
knapsack items───────────────── 12
</pre>
 
=={{header|Ruby}}==
=== Brute force ===
<langsyntaxhighlight lang="ruby">KnapsackItem = Struct.new(:name, :weight, :value)
potential_items = [
KnapsackItem.new(['map', 9, 150)], KnapsackItem.new(['compass', 13, 35)],
KnapsackItem.new(['water', 153, 200)], KnapsackItem.new(['sandwich', 50, 160)],
KnapsackItem.new(['glucose', 15, 60)], KnapsackItem.new(['tin', 68, 45)],
KnapsackItem.new(['banana', 27, 60)], KnapsackItem.new(['apple', 39, 40)],
KnapsackItem.new(['cheese', 23, 30)], KnapsackItem.new(['beer', 52, 10)],
KnapsackItem.new(['suntan cream', 11, 70)], KnapsackItem.new(['camera', 32, 30)],
KnapsackItem.new(['t-shirt', 24, 15)], KnapsackItem.new(['trousers', 48, 10)],
KnapsackItem.new(['umbrella', 73, 40)], KnapsackItem.new(['waterproof trousers', 42, 70)],
KnapsackItem.new(['waterproof overclothes', 43, 75)], KnapsackItem.new(['note-case', 22, 80)],
KnapsackItem.new(['sunglasses', 7, 20)], KnapsackItem.new(['towel', 18, 12)],
KnapsackItem.new(['socks', 4, 50)], KnapsackItem.new(['book', 30, 10)],
]
knapsack_capacity = 400
Line 3,206 ⟶ 7,690:
yield [] if block_given?
self.inject([[]]) do |ps, elem|
r = ps.each_with_object([]) do |i,r|
ps.each do |i|
r << i
new_subset = i + [elem]
Line 3,213 ⟶ 7,696:
r << new_subset
end
r
end
end
end
 
maxval, solutions = potential_items.power_set.group_by {|subset|
maxval = 0
weight = subset.inject(0) {|w, elem| w + elem.weight}
solutions = []
weight>knapsack_capacity ? 0 : subset.inject(0){|v, elem| v + elem.value}
 
}.max
potential_items.power_set do |subset|
weight = subset.inject(0) {|w, elem| w += elem.weight}
next if weight > knapsack_capacity
 
value = subset.inject(0) {|v, elem| v += elem.value}
if value == maxval
solutions << subset
elsif value > maxval
maxval = value
solutions = [subset]
end
end
 
puts "value: #{maxval}"
solutions.each do |set|
wt, items = 0, []
wt = 0
set.each {|elem| wt += elem.weight; items << elem.name}
puts "weight: #{wt}"
puts "items: #{items.sort.join(',')}"
end</langsyntaxhighlight>
 
{{out}}
<pre style='width: full; overflow: scroll'>
value: 1030
weight: 396
items: bananamap,compass,glucose,map,note-casewater,sandwich,socksglucose,sunglassesbanana,suntan cream,water,waterproof overclothestrousers,waterproof trousersoverclothes,note-case,sunglasses,socks
</pre>
 
=== Dynamic Programming ===
Translated from http://sites.google.com/site/mikescoderama/Home/0-1-knapsack-problem-in-p
<langsyntaxhighlight lang="ruby">KnapsackItem = Struct.new(:name, :costweight, :value)
KnapsackProblem = Struct.new(:items, :max_cost)
 
def dynamic_programming_knapsack(problem)
num_items = problem.items.size
items = problem.items
max_cost = problem.max_cost
 
cost_matrix = zeros(num_items, max_cost+1)
 
def dynamic_programming_knapsack(items, max_weight)
num_items = items.size
cost_matrix = Array.new(num_items){Array.new(max_weight+1, 0)}
num_items.times do |i|
(max_costmax_weight + 1).times do |j|
if(items[i].costweight > j)
cost_matrix[i][j] = cost_matrix[i-1][j]
else
cost_matrix[i][j] = [cost_matrix[i-1][j], items[i].value + cost_matrix[i-1][j-items[i].costweight]].max
end
end
end
used_items = get_used_items(items, cost_matrix)
 
[get_list_of_used_items_names(items, used_items), # used items names
cost_matrix
items.zip(used_items).map{|item,used| item.weight*used}.inject(:+), # total weight
cost_matrix.last.last] # total value
end
 
def get_used_items(problemitems, cost_matrix)
i = cost_matrix.size - 1
currentCost = cost_matrix[0].size - 1
marked = Array.new(cost_matrix.size, map{0) }
 
while(i >= 0 && currentCost >= 0)
if(i == 0 && cost_matrix[i][currentCost] > 0 ) || (cost_matrix[i][currentCost] != cost_matrix[i-1][currentCost])
marked[i] = 1
currentCost -= problem.items[i].costweight
end
i -= 1
Line 3,288 ⟶ 7,758:
end
 
def get_list_of_used_items_names(problemitems, cost_matrixused_items)
items.zip(used_items).map{|item,used| item.name if used>0}.compact.join(', ')
items = problem.items
used_items = get_used_items(problem, cost_matrix)
 
result = []
 
used_items.each_with_index do |item,i|
if item > 0
result << items[i].name
end
end
 
result.sort.join(', ')
end
 
def zeros(rows, cols)
Array.new(rows) do |row|
Array.new(cols, 0)
end
end
 
if $0 == __FILE__
items = [
 
KnapsackItem['map' , 9, 150], KnapsackItem['compass' , 13, 35],
items = [
KnapsackItem.new(['mapwater' , 9 153, 150) 200], KnapsackItem.new(['compasssandwich' , 13 50, 35) 160],
KnapsackItem.new(['waterglucose' , 153 15, 200) 60], KnapsackItem.new(['sandwichtin' , 50 , 160) 68, 45],
KnapsackItem.new(['glucosebanana' , 15 27, 60) ], KnapsackItem.new(['tinapple' , 68 39, 45) 40],
KnapsackItem.new(['bananacheese' , 27 23, 60) 30], KnapsackItem.new(['applebeer' , 39 52, 40) 10],
KnapsackItem.new(['cheesesuntan cream' , 23 11, 30) 70], KnapsackItem.new(['beercamera' , 52 32, 10) 30],
KnapsackItem.new(['suntan creamt-shirt' , 11 , 70) 24, 15], KnapsackItem.new(['cameratrousers' , 32 48, 30) 10],
KnapsackItem.new(['t-shirtumbrella' , 24 73, 15) 40], KnapsackItem.new(['waterproof trousers' , 48 42, 10) 70],
KnapsackItem.new(['umbrellawaterproof overclothes', 43, 75], KnapsackItem['note-case' , 73 22, 40) 80], KnapsackItem.new('waterproof trousers' , 42 , 70) ,
KnapsackItem.new(['waterproof overclothessunglasses' , 43 , 75) 7, 20], KnapsackItem.new(['note-casetowel' , 22 , 80)18, 12],
KnapsackItem.new(['sunglassessocks' , 7 , 20) 4, 50], KnapsackItem.new(['towelbook' , 18 30, 12) , 10]
]
KnapsackItem.new('socks' , 4 , 50) , KnapsackItem.new('book' , 30 , 10)
]
names, weight, value = dynamic_programming_knapsack(items, 400)
 
problem = KnapsackProblem.new(items, 400)
 
cost_matrix = dynamic_programming_knapsack problem
puts
puts 'Dynamic Programming:'
puts
puts '"Found solution: ' + get_list_of_used_items_names(problem, cost_matrix)#{names}"
puts "total weight: #{weight}"
puts 'With value: ' + cost_matrix.last.last.to_s
puts "total value: #{value}"
end</lang>
end</syntaxhighlight>
{{out}}
<pre style='width: full; overflow: scroll'>
Dynamic Programming:
 
Found solution: bananamap, compass, glucose, map, note-casewater, sandwich, socksglucose, sunglassesbanana, suntan cream, waterwaterproof trousers, waterproof overclothes, waterproofnote-case, trouserssunglasses, socks
total weight: 396
With value: 1030
total value: 1030
</pre>
 
=={{header|Rust}}==
Dynamic Programming solution.
<syntaxhighlight lang="rust">use std::cmp;
 
struct Item {
name: &'static str,
weight: usize,
value: usize
}
 
fn knapsack01_dyn(items: &[Item], max_weight: usize) -> Vec<&Item> {
let mut best_value = vec![vec![0; max_weight + 1]; items.len() + 1];
for (i, it) in items.iter().enumerate() {
for w in 1 .. max_weight + 1 {
best_value[i + 1][w] =
if it.weight > w {
best_value[i][w]
} else {
cmp::max(best_value[i][w], best_value[i][w - it.weight] + it.value)
}
}
}
 
let mut result = Vec::with_capacity(items.len());
let mut left_weight = max_weight;
 
for (i, it) in items.iter().enumerate().rev() {
if best_value[i + 1][left_weight] != best_value[i][left_weight] {
result.push(it);
left_weight -= it.weight;
}
}
 
result
}
 
 
fn main () {
const MAX_WEIGHT: usize = 400;
 
const ITEMS: &[Item] = &[
Item { name: "map", weight: 9, value: 150 },
Item { name: "compass", weight: 13, value: 35 },
Item { name: "water", weight: 153, value: 200 },
Item { name: "sandwich", weight: 50, value: 160 },
Item { name: "glucose", weight: 15, value: 60 },
Item { name: "tin", weight: 68, value: 45 },
Item { name: "banana", weight: 27, value: 60 },
Item { name: "apple", weight: 39, value: 40 },
Item { name: "cheese", weight: 23, value: 30 },
Item { name: "beer", weight: 52, value: 10 },
Item { name: "suntancream", weight: 11, value: 70 },
Item { name: "camera", weight: 32, value: 30 },
Item { name: "T-shirt", weight: 24, value: 15 },
Item { name: "trousers", weight: 48, value: 10 },
Item { name: "umbrella", weight: 73, value: 40 },
Item { name: "waterproof trousers", weight: 42, value: 70 },
Item { name: "waterproof overclothes", weight: 43, value: 75 },
Item { name: "note-case", weight: 22, value: 80 },
Item { name: "sunglasses", weight: 7, value: 20 },
Item { name: "towel", weight: 18, value: 12 },
Item { name: "socks", weight: 4, value: 50 },
Item { name: "book", weight: 30, value: 10 }
];
 
let items = knapsack01_dyn(ITEMS, MAX_WEIGHT);
 
// We reverse the order because we solved the problem backward.
for it in items.iter().rev() {
println!("{}", it.name);
}
 
println!("Total weight: {}", items.iter().map(|w| w.weight).sum::<usize>());
println!("Total value: {}", items.iter().map(|w| w.value).sum::<usize>());
}</syntaxhighlight>
{{out}}
<pre>map
compass
water
sandwich
glucose
banana
suntancream
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
Total weight: 396
Total value: 1030</pre>
 
=={{header|SAS}}==
 
Use MILP solver in SAS/OR:
<syntaxhighlight lang="sas">/* create SAS data set */
data mydata;
input item $1-23 weight value;
datalines;
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
;
 
/* call OPTMODEL procedure in SAS/OR */
proc optmodel;
/* declare sets and parameters, and read input data */
set <str> ITEMS;
num weight {ITEMS};
num value {ITEMS};
read data mydata into ITEMS=[item] weight value;
 
/* declare variables, objective, and constraints */
var NumSelected {ITEMS} binary;
max TotalValue = sum {i in ITEMS} value[i] * NumSelected[i];
con WeightCon:
sum {i in ITEMS} weight[i] * NumSelected[i] <= 400;
 
/* call mixed integer linear programming (MILP) solver */
solve;
 
/* print optimal solution */
print TotalValue;
print {i in ITEMS: NumSelected[i].sol > 0.5} NumSelected;
quit;</syntaxhighlight>
 
Output:
<pre>
TotalValue
1030
 
[1] NumSelected
banana 1
compass 1
glucose 1
map 1
note-case 1
sandwich 1
socks 1
sunglasses 1
suntan cream 1
water 1
waterproof overclothes 1
waterproof trousers 1
</pre>
 
=={{header|Scala}}==
{{works with|Scala|2.9.2}}
<syntaxhighlight lang="scala">object Knapsack extends App {
 
case class Item(name: String, weight: Int, value: Int)
 
val elapsed: (=> Unit) => Long = f => {val s = System.currentTimeMillis; f; (System.currentTimeMillis - s)/1000}
 
//===== brute force (caution: increase the heap!) ====================================
val ks01b: List[Item] => Unit = loi => {
val tw:Set[Item]=>Int=ps=>(ps:\0)((a,b)=>a.weight+b) //total weight
val tv:Set[Item]=>Int=ps=>(ps:\0)((a,b)=>a.value+b) //total value
val pis = (loi.toSet.subsets).toList.filterNot(_==Set())
 
#[test]
fn test_dp_results() {
let dp_results = knap_01_dp(items, 400);
let dp_weights= dp_results.iter().fold(0, |a, &b| a + b.weight);
let dp_values = dp_results.iter().fold(0, |a, &b| a + b.value);
assert_eq!(dp_weights, 396);
assert_eq!(dp_values, 1030);
} val res = pis.map(ss=>Pair(ss,tw(ss)))
.filter(p=>p._2>350 && p._2<401).map(p=>Pair(p,tv(p._1)))
.sortWith((s,t)=>s._2.compareTo(t._2) < 0)
.last
println{val h = "packing list of items (brute force):"; h+"\n"+"="*h.size}
res._1._1.foreach{p=>print(" "+p.name+": weight="+p.weight+" value="+p.value+"\n")}
println("\n"+" resulting items: "+res._1._1.size+" of "+loi.size)
println(" total weight: "+res._1._2+", total value: "+res._2)
}
 
//===== dynamic programming ==========================================================
val ks01d: List[Item] => Unit = loi => {
val W = 400
val N = loi.size
 
val m = Array.ofDim[Int](N+1,W+1)
val plm = (List((for {w <- 0 to W} yield Set[Item]()).toArray)++(
for {
n <- 0 to N-1
colN = (for {w <- 0 to W} yield Set[Item](loi(n))).toArray
} yield colN)).toArray
 
1 to N foreach {n =>
0 to W foreach {w =>
def in = loi(n-1)
def wn = loi(n-1).weight
def vn = loi(n-1).value
if (w<wn) {
m(n)(w) = m(n-1)(w)
plm(n)(w) = plm(n-1)(w)
}
else {
if (m(n-1)(w)>=m(n-1)(w-wn)+vn) {
m(n)(w) = m(n-1)(w)
plm(n)(w) = plm(n-1)(w)
}
else {
m(n)(w) = m(n-1)(w-wn)+vn
plm(n)(w) = plm(n-1)(w-wn)+in
}
}
}
}
 
println{val h = "packing list of items (dynamic programming):"; h+"\n"+"="*h.size}
plm(N)(W).foreach{p=>print(" "+p.name+": weight="+p.weight+" value="+p.value+"\n")}
println("\n"+" resulting items: "+plm(N)(W).size+" of "+loi.size)
println(" total weight: "+(0/:plm(N)(W).toVector.map{item=>item.weight})(_+_)+", total value: "+m(N)(W))
}
 
val items = List(
Item("map", 9, 150)
,Item("compass", 13, 35)
,Item("water", 153, 200)
,Item("sandwich", 50, 160)
,Item("glucose", 15, 60)
,Item("tin", 68, 45)
,Item("banana", 27, 60)
,Item("apple", 39, 40)
,Item("cheese", 23, 30)
,Item("beer", 52, 10)
,Item("suntan cream", 11, 70)
,Item("camera", 32, 30)
,Item("t-shirt", 24, 15)
,Item("trousers", 48, 10)
,Item("umbrella", 73, 40)
,Item("waterproof trousers", 42, 70)
,Item("waterproof overclothes", 43, 75)
,Item("note-case", 22, 80)
,Item("sunglasses", 7, 20)
,Item("towel", 18, 12)
,Item("socks", 4, 50)
,Item("book", 30, 10)
)
 
List(ks01b, ks01d).foreach{f=>
val t = elapsed{f(items)}
println(" elapsed time: "+t+" sec"+"\n")
}
}</syntaxhighlight>
{{out}}
<pre>packing list of items (brute force):
====================================
waterproof overclothes: weight=43 value=75
note-case: weight=22 value=80
socks: weight=4 value=50
sandwich: weight=50 value=160
banana: weight=27 value=60
glucose: weight=15 value=60
map: weight=9 value=150
water: weight=153 value=200
suntan cream: weight=11 value=70
sunglasses: weight=7 value=20
waterproof trousers: weight=42 value=70
compass: weight=13 value=35
 
resulting items: 12 of 22
total weight: 396, total value: 1030
elapsed time: 19 sec
 
packing list of items (dynamic programming):
============================================
waterproof overclothes: weight=43 value=75
note-case: weight=22 value=80
socks: weight=4 value=50
sandwich: weight=50 value=160
banana: weight=27 value=60
glucose: weight=15 value=60
map: weight=9 value=150
water: weight=153 value=200
suntan cream: weight=11 value=70
sunglasses: weight=7 value=20
waterproof trousers: weight=42 value=70
compass: weight=13 value=35
 
resulting items: 12 of 22
total weight: 396, total value: 1030
elapsed time: 0 sec</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">var 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
 
struct KnapsackItem {
String name,
Number weight,
Number value,
}
 
var items = []
raw.each_line{ |row|
var fields = row.split(/\s*,\s*/)
items << KnapsackItem(
name: fields[0],
weight: fields[1].to_n,
value: fields[2].to_n,
)
}
 
var max_weight = 400
var p = [
items.len.of { [[0, []], max_weight.of(nil)...] }...,
max_weight.inc.of {[0, []]}
]
 
func optimal(i, w) {
if (!defined p[i][w]) {
var item = items[i];
if (item.weight > w) {
p[i][w] = optimal(i.dec, w)
}
else {
var x = optimal(i.dec, w)
var y = optimal(i.dec, w - item.weight)
 
if (x[0] > (y[0] + item.value)) {
p[i][w] = x;
}
else {
p[i][w] = [y[0] + item.value, [y[1]..., item.name]]
}
}
}
return p[i][w]
}
 
var sol = optimal(items.end, max_weight)
say "#{sol[0]}: #{sol[1]}"</syntaxhighlight>
{{out}}
<pre>
1030: map compass water sandwich glucose banana suntancream waterproof trousers waterproof overclothes note-case sunglasses socks
</pre>
 
=={{header|SQL}}==
A brute force solution that runs in SQL Server 2005 or later using a recursive CTE.
Displays the top 5 solutions and runs in about 39 seconds.
 
<syntaxhighlight lang="sql">
WITH KnapsackItems (item, [weight], value) AS
(
SELECT 'map',9, 150
UNION ALL SELECT 'compass',13, 35
UNION ALL SELECT 'water',153, 200
UNION ALL SELECT 'sandwich',50, 160
UNION ALL SELECT 'glucose',15, 60
UNION ALL SELECT 'tin',68, 45
UNION ALL SELECT 'banana',27, 60
UNION ALL SELECT 'apple',39, 40
UNION ALL SELECT 'cheese',23, 30
UNION ALL SELECT 'beer',52, 10
UNION ALL SELECT 'suntan cream',11, 70
UNION ALL SELECT 'camera',32, 30
UNION ALL SELECT 'T-shirt',24, 15
UNION ALL SELECT 'trousers',48, 10
UNION ALL SELECT 'umbrella',73, 40
UNION ALL SELECT 'waterproof trousers',42, 70
UNION ALL SELECT 'waterproof overclothes',43, 75
UNION ALL SELECT 'note-case',22, 80
UNION ALL SELECT 'sunglasses',7, 20
UNION ALL SELECT 'towel',18, 12
UNION ALL SELECT 'socks',4, 50
UNION ALL SELECT 'book',30, 10
)
SELECT *
INTO #KnapsackItems
FROM KnapsackItems;
 
WITH UNIQUEnTuples (n, Tuples, ID, [weight], value) AS (
SELECT 1, CAST(item AS VARCHAR(8000)), item, [weight], value
FROM #KnapsackItems
UNION ALL
SELECT 1 + n.n, t.item + ',' + n.Tuples, item, n.[weight] + t.[weight], n.value + t.value
FROM UNIQUEnTuples n
CROSS APPLY (
SELECT item, [weight], value
FROM #KnapsackItems t
WHERE t.item < n.ID AND n.[weight] + t.[weight] < 400) t
)
SELECT TOP 5 *
FROM UNIQUEnTuples
ORDER BY value DESC, n, Tuples;
 
GO
DROP TABLE #KnapsackItems;
</syntaxhighlight>
{{out}}
<pre>
weight value Solution
396 1030 banana,compass,glucose,map,note-case,sandwich,socks,sunglasses,suntan cream,water,waterproof overclothes,waterproof trousers
389 1010 banana,compass,glucose,map,note-case,sandwich,socks,suntan cream,water,waterproof overclothes,waterproof trousers
399 1005 banana,cheese,glucose,map,note-case,sandwich,socks,suntan cream,water,waterproof overclothes,waterproof trousers
395 1002 banana,cheese,compass,glucose,map,note-case,sandwich,socks,sunglasses,suntan cream,towel,water,waterproof overclothes
393 1000 apple,banana,compass,glucose,map,note-case,sandwich,socks,sunglasses,suntan cream,water,waterproof overclothes
</pre>
 
=={{header|Swift}}==
 
{{trans|Python}}
 
=== Dynamic Programming ===
 
<syntaxhighlight lang="swift">struct KnapsackItem {
var name: String
var weight: Int
var value: Int
}
 
func knapsack(items: [KnapsackItem], limit: Int) -> [KnapsackItem] {
var table = Array(repeating: Array(repeating: 0, count: limit + 1), count: items.count + 1)
for j in 1..<items.count+1 {
let item = items[j-1]
for w in 1..<limit+1 {
if item.weight > w {
table[j][w] = table[j-1][w]
} else {
table[j][w] = max(table[j-1][w], table[j-1][w-item.weight] + item.value)
}
}
}
var result = [KnapsackItem]()
var w = limit
for j in stride(from: items.count, to: 0, by: -1) where table[j][w] != table[j-1][w] {
let item = items[j-1]
result.append(item)
w -= item.weight
}
return result
}
 
let items = [
KnapsackItem(name: "map", weight: 9, value: 150), KnapsackItem(name: "compass", weight: 13, value: 35),
KnapsackItem(name: "water", weight: 153, value: 200), KnapsackItem(name: "sandwich", weight: 50, value: 160),
KnapsackItem(name: "glucose", weight: 15, value: 60), KnapsackItem(name: "tin", weight: 68, value: 45),
KnapsackItem(name: "banana", weight: 27, value: 60), KnapsackItem(name: "apple", weight: 39, value: 40),
KnapsackItem(name: "cheese", weight: 23, value: 30), KnapsackItem(name: "beer", weight: 52, value: 10),
KnapsackItem(name: "suntan cream", weight: 11, value: 70), KnapsackItem(name: "camera", weight: 32, value: 30),
KnapsackItem(name: "t-shirt", weight: 24, value: 15), KnapsackItem(name: "trousers", weight: 48, value: 10),
KnapsackItem(name: "umbrella", weight: 73, value: 40), KnapsackItem(name: "waterproof trousers", weight: 42, value: 70),
KnapsackItem(name: "waterproof overclothes", weight: 43, value: 75), KnapsackItem(name: "note-case", weight: 22, value: 80),
KnapsackItem(name: "sunglasses", weight: 7, value: 20), KnapsackItem(name: "towel", weight: 18, value: 12),
KnapsackItem(name: "socks", weight: 4, value: 50), KnapsackItem(name: "book", weight: 30, value: 10)
]
 
let kept = knapsack(items: items, limit: 400)
 
print("Kept: ")
 
for item in kept {
print(" \(item.name)")
}
 
let (tValue, tWeight) = kept.reduce((0, 0), { ($0.0 + $1.value, $0.1 + $1.weight) })
 
print("For a total value of \(tValue) and a total weight of \(tWeight)")</syntaxhighlight>
 
{{out}}
 
<pre>Kept:
socks
sunglasses
note-case
waterproof overclothes
waterproof trousers
suntan cream
banana
glucose
sandwich
water
compass
map
For a total value of 1030 and a total weight of 396</pre>
 
=={{header|Tcl}}==
As the saying goes, “when in doubt, try brute force”. Since there's only 22 items we can simply iterate over all possible choices.
<langsyntaxhighlight lang="tcl"># The list of items to consider, as list of lists
set items {
{map 9 150}
Line 3,417 ⟶ 8,397:
# Pretty-print the results
puts "Best filling has weight of [expr {[weight $best]/100.0}]kg and score [value $best]"
puts "Best items:\n\t[join [lsort [names $best]] \n\t]"</langsyntaxhighlight>
{{out}}
<pre>
Line 3,438 ⟶ 8,418:
=={{header|Ursala}}==
This solution follows a very similar approach to the one used in [[Knapsack problem/Bounded#Ursala]], which is to treat it as a mixed integer programming problem and solve it using an off-the-shelf library ([http://lpsolve.sourceforge.net lpsolve]).
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
#import flo
Line 3,481 ⟶ 8,461:
#show+
 
main = ~&tnS solution system items</langsyntaxhighlight>
Binary valued variables are a more specific constraint than the general mixed integer programming problem, but can be accommodated as shown using the <code>binaries</code> field in the <code>linear_system</code> specification. The additional <code>slack</code> variable is specified as continuous and non-negative with no cost or benefit so as to make the constraint equation solvable without affecting the solution.
{{out}}
Line 3,497 ⟶ 8,477:
waterproof overclothes
waterproof trousers
</pre>
 
=={{header|VBA}}==
<syntaxhighlight lang="vb">'Knapsack problem/0-1 - 12/02/2017
Option Explicit
Const maxWeight = 400
Dim DataList As Variant
Dim xList(64, 3) As Variant
Dim nItems As Integer
Dim s As String, xss As String
Dim xwei As Integer, xval As Integer, nn As Integer
 
Sub Main()
Dim i As Integer, j As Integer
DataList = Array("map", 9, 150, "compass", 13, 35, "water", 153, 200, "sandwich", 50, 160, _
"glucose", 15, 60, "tin", 68, 45, "banana", 27, 60, "apple", 39, 40, _
"cheese", 23, 30, "beer", 52, 10, "suntan cream", 11, 70, "camera", 32, 30, _
"T-shirt", 24, 15, "trousers", 48, 10, "umbrella", 73, 40, "book", 30, 10, _
"waterproof trousers", 42, 70, "waterproof overclothes", 43, 75, _
"note-case", 22, 80, "sunglasses", 7, 20, "towel", 18, 12, "socks", 4, 50)
nItems = (UBound(DataList) + 1) / 3
j = 0
For i = 1 To nItems
xList(i, 1) = DataList(j)
xList(i, 2) = DataList(j + 1)
xList(i, 3) = DataList(j + 2)
j = j + 3
Next i
s = ""
For i = 1 To nItems
s = s & Chr(i)
Next
nn = 0
Call ChoiceBin(1, "")
For i = 1 To Len(xss)
j = Asc(Mid(xss, i, 1))
Debug.Print xList(j, 1)
Next i
Debug.Print "count=" & Len(xss), "weight=" & xwei, "value=" & xval
End Sub 'Main
 
Private Sub ChoiceBin(n As String, ss As String)
Dim r As String
Dim i As Integer, j As Integer, iwei As Integer, ival As Integer
Dim ipct As Integer
If n = Len(s) + 1 Then
iwei = 0: ival = 0
For i = 1 To Len(ss)
j = Asc(Mid(ss, i, 1))
iwei = iwei + xList(j, 2)
ival = ival + xList(j, 3)
Next
If iwei <= maxWeight And ival > xval Then
xss = ss: xwei = iwei: xval = ival
End If
Else
r = Mid(s, n, 1)
Call ChoiceBin(n + 1, ss & r)
Call ChoiceBin(n + 1, ss)
End If
End Sub 'ChoiceBin</syntaxhighlight>
{{out}}
<pre>
map
compass
water
sandwich
glucose
banana
suntan cream
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
count=12 weight=396 value=1030
</pre>
 
=={{header|VBScript}}==
Non recurvive unfolded force version. Created by an other script. It runs 13 times faster than the recursive one.
<syntaxhighlight lang="vb">' Knapsack problem/0-1 - 13/02/2017
dim w(22),v(22),m(22)
data=array( "map", 9, 150, "compass", 13, 35, "water", 153, 200, _
"sandwich", 50, 160 , "glucose", 15, 60, "tin", 68, 45, _
"banana", 27, 60, "apple", 39, 40 , "cheese", 23, 30, "beer", 52, 10, _
"suntan cream", 11, 70, "camera", 32, 30 , "T-shirt", 24, 15, _
"trousers", 48, 10, "umbrella", 73, 40, "book", 30, 10 , _
"waterproof trousers", 42, 70, "waterproof overclothes", 43, 75 , _
"note-case", 22, 80, "sunglasses", 7, 20, "towel", 18, 12, "socks", 4, 50)
ww=400
xw=0:iw=0:iv=0
w(1)=iw:v(1)=iv
for i1=0 to 1:m(1)=i1:j=0
if i1=1 then
iw=w(1)+data(j*3+1):iv=v(1)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i1
if iw<=ww then
w(2)=iw: v(2)=iv
for i2=0 to 1:m(2)=i2:j=1
if i2=1 then
iw=w(2)+data(j*3+1):iv=v(2)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i2
if iw<=ww then
w(3)=iw: v(3)=iv
for i3=0 to 1:m(3)=i3:j=2
if i3=1 then
iw=w(3)+data(j*3+1):iv=v(3)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i3
if iw<=ww then
w(4)=iw: v(4)=iv
for i4=0 to 1:m(4)=i4:j=3
if i4=1 then
iw=w(4)+data(j*3+1):iv=v(4)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i4
if iw<=ww then
w(5)=iw: v(5)=iv
for i5=0 to 1:m(5)=i5:j=4
if i5=1 then
iw=w(5)+data(j*3+1):iv=v(5)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i5
if iw<=ww then
w(6)=iw: v(6)=iv
for i6=0 to 1:m(6)=i6:j=5
if i6=1 then
iw=w(6)+data(j*3+1):iv=v(6)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i6
if iw<=ww then
w(7)=iw: v(7)=iv
for i7=0 to 1:m(7)=i7:j=6
if i7=1 then
iw=w(7)+data(j*3+1):iv=v(7)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i7
if iw<=ww then
w(8)=iw: v(8)=iv
for i8=0 to 1:m(8)=i8:j=7
if i8=1 then
iw=w(8)+data(j*3+1):iv=v(8)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i8
if iw<=ww then
w(9)=iw: v(9)=iv
for i9=0 to 1:m(9)=i9:j=8
if i9=1 then
iw=w(9)+data(j*3+1):iv=v(9)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i9
if iw<=ww then
w(10)=iw: v(10)=iv
for i10=0 to 1:m(10)=i10:j=9
if i10=1 then
iw=w(10)+data(j*3+1):iv=v(10)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i10
if iw<=ww then
w(11)=iw: v(11)=iv
for i11=0 to 1:m(11)=i11:j=10
if i11=1 then
iw=w(11)+data(j*3+1):iv=v(11)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i11
if iw<=ww then
w(12)=iw: v(12)=iv
for i12=0 to 1:m(12)=i12:j=11
if i12=1 then
iw=w(12)+data(j*3+1):iv=v(12)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i12
if iw<=ww then
w(13)=iw: v(13)=iv
for i13=0 to 1:m(13)=i13:j=12
if i13=1 then
iw=w(13)+data(j*3+1):iv=v(13)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i13
if iw<=ww then
w(14)=iw: v(14)=iv
for i14=0 to 1:m(14)=i14:j=13
if i14=1 then
iw=w(14)+data(j*3+1):iv=v(14)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i14
if iw<=ww then
w(15)=iw: v(15)=iv
for i15=0 to 1:m(15)=i15:j=14
if i15=1 then
iw=w(15)+data(j*3+1):iv=v(15)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i15
if iw<=ww then
w(16)=iw: v(16)=iv
for i16=0 to 1:m(16)=i16:j=15
if i16=1 then
iw=w(16)+data(j*3+1):iv=v(16)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i16
if iw<=ww then
w(17)=iw: v(17)=iv
for i17=0 to 1:m(17)=i17:j=16
if i17=1 then
iw=w(17)+data(j*3+1):iv=v(17)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i17
if iw<=ww then
w(18)=iw: v(18)=iv
for i18=0 to 1:m(18)=i18:j=17
if i18=1 then
iw=w(18)+data(j*3+1):iv=v(18)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i18
if iw<=ww then
w(19)=iw: v(19)=iv
for i19=0 to 1:m(19)=i19:j=18
if i19=1 then
iw=w(19)+data(j*3+1):iv=v(19)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i19
if iw<=ww then
w(20)=iw: v(20)=iv
for i20=0 to 1:m(20)=i20:j=19
if i20=1 then
iw=w(20)+data(j*3+1):iv=v(20)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i20
if iw<=ww then
w(21)=iw: v(21)=iv
for i21=0 to 1:m(21)=i21:j=20
if i21=1 then
iw=w(21)+data(j*3+1):iv=v(21)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i21
if iw<=ww then
w(22)=iw: v(22)=iv
for i22=0 to 1:m(22)=i22:j=21
nn=nn+1
if i22=1 then
iw=w(22)+data(j*3+1):iv=v(22)+data(j*3+2)
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
end if 'i22
if iw<=ww then
end if 'i22
next:m(22)=0
end if 'i21
next:m(21)=0
end if 'i20
next:m(20)=0
end if 'i19
next:m(19)=0
end if 'i18
next:m(18)=0
end if 'i17
next:m(17)=0
end if 'i16
next:m(16)=0
end if 'i15
next:m(15)=0
end if 'i14
next:m(14)=0
end if 'i13
next:m(13)=0
end if 'i12
next:m(12)=0
end if 'i11
next:m(11)=0
end if 'i10
next:m(10)=0
end if 'i9
next:m(9)=0
end if 'i8
next:m(8)=0
end if 'i7
next:m(7)=0
end if 'i6
next:m(6)=0
end if 'i5
next:m(5)=0
end if 'i4
next:m(4)=0
end if 'i3
next:m(3)=0
end if 'i2
next:m(2)=0
end if 'i1
next:m(1)=0
for i=1 to 22
if l(i)=1 then wlist=wlist&vbCrlf&data((i-1)*3)
next
Msgbox mid(wlist,3)&vbCrlf&vbCrlf&"weight="&xw&vbCrlf&"value="&xv,,"Knapsack - nn="&nn</syntaxhighlight>
{{out}}
<pre>
map
compass
water
sandwich
glucose
banana
suntan cream
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
 
weight=396
value=1030
</pre>
 
=={{header|Visual Basic}}==
{{works with|Visual Basic|VB6 Standard}}
<syntaxhighlight lang="vb">'Knapsack problem/0-1 - 12/02/2017
Option Explicit
Const maxWeight = 400
Dim DataList As Variant
Dim xList(64, 3) As Variant
Dim nItems As Integer
Dim s As String, xss As String
Dim xwei As Integer, xval As Integer, nn As Integer
 
Private Sub Form_Load()
Dim i As Integer, j As Integer
DataList = Array("map", 9, 150, "compass", 13, 35, "water", 153, 200, "sandwich", 50, 160, _
"glucose", 15, 60, "tin", 68, 45, "banana", 27, 60, "apple", 39, 40, _
"cheese", 23, 30, "beer", 52, 10, "suntan cream", 11, 70, "camera", 32, 30, _
"T-shirt", 24, 15, "trousers", 48, 10, "umbrella", 73, 40, "book", 30, 10, _
"waterproof trousers", 42, 70, "waterproof overclothes", 43, 75, _
"note-case", 22, 80, "sunglasses", 7, 20, "towel", 18, 12, "socks", 4, 50)
nItems = (UBound(DataList) + 1) / 3
j = 0
For i = 1 To nItems
xList(i, 1) = DataList(j)
xList(i, 2) = DataList(j + 1)
xList(i, 3) = DataList(j + 2)
j = j + 3
Next i
For i = 1 To nItems
xListBox.AddItem xList(i, 1)
Next i
End Sub
 
Private Sub cmdOK_Click()
Dim i As Integer, j As Integer
For i = 1 To xListBox.ListCount
xListBox.RemoveItem 0
Next i
s = ""
For i = 1 To nItems
s = s & Chr(i)
Next
nn = 0
Call ChoiceBin(1, "")
For i = 1 To Len(xss)
j = Asc(Mid(xss, i, 1))
xListBox.AddItem xList(j, 1)
Next i
xListBox.AddItem "*Total* " & xwei & " " & xval
End Sub
 
Private Sub ChoiceBin(n As String, ss As String)
Dim r As String
Dim i As Integer, j As Integer, iwei As Integer, ival As Integer
Dim ipct As Integer
If n = Len(s) + 1 Then
iwei = 0: ival = 0
For i = 1 To Len(ss)
j = Asc(Mid(ss, i, 1))
iwei = iwei + xList(j, 2)
ival = ival + xList(j, 3)
Next
If iwei <= maxWeight And ival > xval Then
xss = ss: xwei = iwei: xval = ival
End If
Else
r = Mid(s, n, 1)
Call ChoiceBin(n + 1, ss & r)
Call ChoiceBin(n + 1, ss)
End If
End Sub 'ChoiceBin</syntaxhighlight>
{{out}}
<pre>
map
compass
water
sandwich
glucose
banana
suntan cream
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
*Total* weight=396 val=1030
</pre>
 
=={{header|Visual Basic .NET}}==
{{works with|Visual Basic .NET|2013}}
<syntaxhighlight lang="vbnet">'Knapsack problem/0-1 - 12/02/2017
Public Class KnapsackBin
Const knam = 0, kwei = 1, kval = 2
Const maxWeight = 400
Dim xList(,) As Object = { _
{"map", 9, 150}, _
{"compass", 13, 35}, _
{"water", 153, 200}, _
{"sandwich", 50, 160}, _
{"glucose", 15, 60}, _
{"tin", 68, 45}, _
{"banana", 27, 60}, _
{"ChoiceBinle", 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}}
Dim s, xss As String, xwei, xval, nn As Integer
 
Private Sub KnapsackBin_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim i As Integer
xListView.View = View.Details
xListView.Columns.Add("item", 120, HorizontalAlignment.Left)
xListView.Columns.Add("weight", 50, HorizontalAlignment.Right)
xListView.Columns.Add("value", 50, HorizontalAlignment.Right)
For i = 0 To UBound(xList, 1)
xListView.Items.Add(New ListViewItem(New String() {xList(i, 0), _
xList(i, 1).ToString, xList(i, 2).ToString}))
Next i
End Sub 'KnapsackBin_Load
 
Private Sub cmdOK_Click(sender As Object, e As EventArgs) Handles cmdOK.Click
Dim i, j, nItems As Integer
For i = xListView.Items.Count - 1 To 0 Step -1
xListView.Items.RemoveAt(i)
Next i
Me.Refresh()
nItems = UBound(xList, 1) + 1
s = ""
For i = 1 To nItems
s = s & Chr(i - 1)
Next
nn = 0
Call ChoiceBin(1, "")
For i = 1 To Len(xss)
j = Asc(Mid(xss, i, 1))
xListView.Items.Add(New ListViewItem(New String() {xList(j, 0), _
xList(j, 1).ToString, xList(j, 2).ToString}))
Next i
xListView.Items.Add(New ListViewItem(New String() {"*Total*", xwei, xval}))
End Sub 'cmdOK_Click
 
Private Sub ChoiceBin(n As String, ss As String)
Dim r As String, i, j, iwei, ival As Integer
Dim ipct As Integer
If n = Len(s) + 1 Then
iwei = 0 : ival = 0
For i = 1 To Len(ss)
j = Asc(Mid(ss, i, 1))
iwei = iwei + xList(j, 1)
ival = ival + xList(j, 2)
Next
If iwei <= maxWeight And ival > xval Then
xss = ss : xwei = iwei : xval = ival
End If
Else
r = Mid(s, n, 1)
Call ChoiceBin(n + 1, ss & r)
Call ChoiceBin(n + 1, ss)
End If
End Sub 'ChoiceBin
 
End Class 'KnapsackBin
</syntaxhighlight>
{{out}}
<pre>
KnapsackBin_Load
cmdOK_Click
map
compass
water
sandwich
glucose
banana
suntan cream
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
*Total* weight=396 val=1030
</pre>
 
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="go">struct Item {
name string
w int
v int
}
 
const wants = [
Item{'map', 9, 150},
Item{'compass', 13, 35},
Item{'water', 153, 200},
Item{'sandwich', 50, 60},
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{'suntancream', 11, 70},
Item{'camera', 32, 30},
Item{'T-shirt', 24, 15},
Item{'trousers', 48, 10},
Item{'umbrella', 73, 40},
Item{'w-trousers', 42, 70},
Item{'w-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 max_wt = 400
 
fn main(){
items, w, v := m(wants.len-1, max_wt)
println(items)
println('weight: $w')
println('value: $v')
}
 
fn m(i int, w int) ([]string, int, int) {
if i<0 || w==0{
return []string{}, 0, 0
} else if wants[i].w > w {
return m(i-1, w)
}
i0, w0, v0 := m(i-1, w)
mut i1, w1, mut v1 := m(i-1, w-wants[i].w)
v1 += wants[i].v
if v1 > v0 {
i1 << wants[i].name
return i1, w1+wants[i].w, v1
}
return i0, w0, v0
}</syntaxhighlight>
{{out}}
<pre>
['map', 'compass', 'water', 'sandwich', 'glucose', 'banana', 'suntancream', 'w-trousers', 'w-overclothes', 'note-case', 'sunglasses', 'socks']
weight: 396
value: 930
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
Based on the Go example, though modified to give output in tabular form.
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var wants = [
["map", 9, 150],
["compass", 13, 35],
["water", 153, 200],
["sandwich", 50, 160],
["glucose", 15, 60],
["tin", 68, 45],
["banana", 27, 60],
["apple", 39, 40],
["cheese", 23, 30],
["beer", 52, 10],
["suntan cream", 11, 70],
["camera", 32, 30],
["T-shirt", 24, 15],
["trousers", 48, 10],
["umbrella", 73, 40],
["waterproof trousers", 42, 70],
["waterproof overclothes", 43, 75],
["note-case", 22, 80],
["sunglasses", 7, 20],
["towel", 18, 12],
["socks", 4, 50],
["book", 30, 10]
]
 
var m
m = Fn.new { |i, w|
if (i < 0 || w == 0) return [[], 0, 0]
if (wants[i][1] > w) return m.call(i-1, w)
System.write("") // guard against VM recursion bug
var res = m.call(i-1, w)
var i0 = res[0]
var w0 = res[1]
var v0 = res[2]
res = m.call(i-1, w - wants[i][1])
var i1 = res[0]
var w1 = res[1]
var v1 = res[2] + wants[i][2]
if (v1 > v0) {
i1.add(wants[i])
return [i1, w1 + wants[i][1], v1]
}
return [i0, w0, v0]
}
 
var maxWt = 400
var res = m.call(wants.count-1, maxWt)
var items = res[0]
var tw = res[1]
var tv = res[2]
System.print("Max weight: %(maxWt)\n")
System.print("Item Weight Value")
System.print("------------------------------------")
for (i in 0...items.count) {
Fmt.print("$-22s $3d $4s", items[i][0], items[i][1], items[i][2])
}
System.print(" --- ----")
Fmt.print("totals $3d $4d", tw, tv)</syntaxhighlight>
 
{{out}}
<pre>
Max weight: 400
 
Item Weight Value
------------------------------------
map 9 150
compass 13 35
water 153 200
sandwich 50 160
glucose 15 60
banana 27 60
suntan cream 11 70
waterproof trousers 42 70
waterproof overclothes 43 75
note-case 22 80
sunglasses 7 20
socks 4 50
--- ----
Totals 396 1030
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \include 'code' declarations
 
int Item, Items, Weights, Values,
Line 3,556 ⟶ 9,190:
IntOut(0, W); ChOut(0, Tab);
IntOut(0, V); CrLf(0);
]</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
map 9 150
Line 3,575 ⟶ 9,209:
</pre>
 
=={{omit fromheader|GUISSzkl}}==
{{trans|Haskell}}{{trans|D}}
<syntaxhighlight lang="zkl">fcn addItem(pairs,it){ // pairs is list of (cost of:,names), it is (name,w,v)
w,left,right:=it[1],pairs[0,w],pairs[w,*];
left.extend(right.zipWith(
fcn([(t1,_)]a,[(t2,_)]b){ t1>t2 and a or b },
pairs.apply('wrap([(tot,names)]){ T(tot + it[2], names + it[0]) })))
}//--> new list of pairs</syntaxhighlight>
<syntaxhighlight lang="zkl">items:=T(T("apple", 39, 40),T("banana", 27,60), // item: (name,weight,value)
T("beer", 52, 10),T("book", 30,10),T("camera", 32, 30),
T("cheese", 23, 30),T("compass", 13,35),T("glucose", 15, 60),
T("map", 9,150),T("note-case",22,80),T("sandwich", 50,160),
T("socks", 4, 50),T("sunglasses",7,20),T("suntan cream",11, 70),
T("t-shirt", 24, 15),T("tin", 68,45),T("towel", 18, 12),
T("trousers", 48, 10),T("umbrella", 73,40),T("water", 153,200),
T("overclothes",43, 75),T("waterproof trousers",42,70) );
const MAX_WEIGHT=400;
knapsack:=items.reduce(addItem,
(MAX_WEIGHT).pump(List,T(0,T).copy))[-1]; // nearest to max weight
weight:=items.apply('wrap(it){ knapsack[1].holds(it[0]) and it[1] }).sum(0);
knapsack.println(weight);</syntaxhighlight>
{{out}}
<pre>
L(1030,L("banana","compass","glucose","map","note-case","sandwich","socks","sunglasses","suntan cream","water","overclothes","waterproof trousers"))396
</pre>
20

edits