September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -79,6 +79,7 @@ exceed 400 dag [4 kg], and their total value is maximized.
|
|||
|
||||
|
||||
;Related tasks:
|
||||
* [[Knapsack problem/Unbounded]]
|
||||
* [[Knapsack problem/Bounded]]
|
||||
* [[Knapsack problem/Unbounded]]
|
||||
* [[Knapsack problem/Continuous]]
|
||||
<br><br>
|
||||
|
|
|
|||
124
Task/Knapsack-problem-0-1/360-Assembly/knapsack-problem-0-1.360
Normal file
124
Task/Knapsack-problem-0-1/360-Assembly/knapsack-problem-0-1.360
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
* Knapsack problem/0-1 16/02/2017
|
||||
KNAPSA01 CSECT
|
||||
USING KNAPSA01,R13
|
||||
B 72(R15)
|
||||
DC 17F'0'
|
||||
STM R14,R12,12(R13)
|
||||
ST R13,4(R15)
|
||||
ST R15,8(R13)
|
||||
LR R13,R15 end of prolog
|
||||
L R0,N n
|
||||
LA R1,1
|
||||
POWER MH R1,=H'2' *2
|
||||
BCT R0,POWER
|
||||
BCTR R1,0 -1
|
||||
ST R1,IMAX imax=2**n-1
|
||||
SR R6,R6 i=0
|
||||
DO WHILE=(C,R6,LE,IMAX) do i=0 to imax
|
||||
SR R10,R10 im=0
|
||||
SR R8,R8 iw=0
|
||||
SR R9,R9 iv=0
|
||||
LA R7,1 j=1
|
||||
DO WHILE=(C,R7,LE,N) do j=1 to n
|
||||
LR R1,R6 i
|
||||
LR R2,R7 j
|
||||
BAL R14,TSTBIT call tstbit(i,j)
|
||||
IF C,R0,EQ,=F'1' THEN if tstbit(i,j)=1 then
|
||||
LA R10,1(R10) im=im+1
|
||||
LR R3,R7 j
|
||||
BCTR R3,0
|
||||
SLA R3,5
|
||||
LA R1,24(R3)
|
||||
A R8,DATA(R1) iw=iw+data(j).w
|
||||
LA R1,28(R3)
|
||||
A R9,DATA(R1) iv=iv+data(j).v
|
||||
ENDIF , endif
|
||||
LA R7,1(R7) j=j+1
|
||||
ENDDO , enddo j
|
||||
IF C,R8,LE,MAXW,AND,C,R9,GT,XV THEN if w<=maxw and iv>xv then
|
||||
ST R6,XB xb=i
|
||||
ST R10,XM xm=im
|
||||
ST R8,XW xw=iw
|
||||
ST R9,XV xv=iv
|
||||
ENDIF , endif
|
||||
LA R6,1(R6) i=i+1
|
||||
ENDDO , enddo i
|
||||
MVC PG(2),=C'n='
|
||||
L R1,N n
|
||||
XDECO R1,XDEC edit n
|
||||
MVC PG+2(2),XDEC+10
|
||||
XPRNT PG,L'PG print buffer
|
||||
LA R6,1
|
||||
DO WHILE=(C,R6,LE,N) do i=1 to n
|
||||
L R1,XB xb
|
||||
LR R2,R6 i
|
||||
BAL R14,TSTBIT call tstbit(xb,i)
|
||||
IF C,R0,EQ,=F'1' THEN if tstbit(xb,i)=1 then
|
||||
LR R1,R6 i
|
||||
BCTR R1,0
|
||||
SLA R1,5
|
||||
LA R2,DATA(R1) @data(i).n
|
||||
MVC PG(24),0(R2)
|
||||
XPRNT PG,24 print item
|
||||
ENDIF , endif
|
||||
LA R6,1(R6) i=i+1
|
||||
ENDDO , enddo i
|
||||
L R1,XM xm
|
||||
XDECO R1,XDEC edit xm
|
||||
MVC PGT+6(2),XDEC+10
|
||||
L R1,XW xw
|
||||
XDECO R1,XDEC edit xw
|
||||
MVC PGT+16(3),XDEC+9
|
||||
L R1,XV xv
|
||||
XDECO R1,XDEC edit xv
|
||||
MVC PGT+26(4),XDEC+8
|
||||
XPRNT PGT,L'PGT print buffer
|
||||
L R13,4(0,R13) epilog
|
||||
LM R14,R12,12(R13)
|
||||
XR R15,R15
|
||||
BR R14 exit
|
||||
TSTBIT EQU * R1 value to test the R2 bit
|
||||
LA R3,32 32
|
||||
SR R3,R2 (32-i)
|
||||
STC R3,XSLL+3
|
||||
LR R0,R1 n
|
||||
EX 0,XSLL SLL R0,(32-i)
|
||||
SRL R0,31
|
||||
BR R14 return R0
|
||||
XSLL SLL R0,0 shift left logical
|
||||
*
|
||||
MAXW DC F'400' maximum weight
|
||||
N DC A((DATAE-DATA)/32)
|
||||
IMAX DS F number of combinations
|
||||
XB DS F max vector
|
||||
XM DS F max items
|
||||
XW DS F max weight
|
||||
XV DS F max value
|
||||
PG DC CL80' '
|
||||
PGT DC CL32'items=.. weight=... value=....'
|
||||
XDEC DS CL12
|
||||
DATA DC CL24'map',F'9',F'150'
|
||||
DC CL24'compass',F'13',F'35'
|
||||
DC CL24'water',F'153',F'200'
|
||||
DC CL24'sandwich',F'50',F'160'
|
||||
DC CL24'glucose',F'15',F'60'
|
||||
DC CL24'tin',F'68',F'45'
|
||||
DC CL24'banana',F'27',F'60'
|
||||
DC CL24'apple',F'39',F'40'
|
||||
DC CL24'cheese',F'23',F'30'
|
||||
DC CL24'beer',F'52',F'10'
|
||||
DC CL24'suntan cream',F'11',F'70'
|
||||
DC CL24'camera',F'32',F'30'
|
||||
DC CL24'T-shirt',F'24',F'15'
|
||||
DC CL24'trousers',F'48',F'10'
|
||||
DC CL24'umbrella',F'73',F'40'
|
||||
DC CL24'book',F'30',F'10'
|
||||
DC CL24'waterproof trousers',F'42',F'70'
|
||||
DC CL24'waterproof overclothes',F'43',F'75'
|
||||
DC CL24'note-case',F'22',F'80'
|
||||
DC CL24'sunglasses',F'7',F'20'
|
||||
DC CL24'towel',F'18',F'12'
|
||||
DC CL24'socks',F'4',F'50'
|
||||
DATAE DC 0C
|
||||
YREGS
|
||||
END KNAPSA01
|
||||
43
Task/Knapsack-problem-0-1/AWK/knapsack-problem-0-1.awk
Normal file
43
Task/Knapsack-problem-0-1/AWK/knapsack-problem-0-1.awk
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# syntax: GAWK -f KNAPSACK_PROBLEM_0-1.AWK
|
||||
BEGIN {
|
||||
# arr["item,weight"] = value
|
||||
arr["map,9"] = 150
|
||||
arr["compass,13"] = 35
|
||||
arr["water,153"] = 200
|
||||
arr["sandwich,50"] = 160
|
||||
arr["glucose,15"] = 60
|
||||
arr["tin,68"] = 45
|
||||
arr["banana,27"] = 60
|
||||
arr["apple,39"] = 40
|
||||
arr["cheese,23"] = 30
|
||||
arr["beer,52"] = 10
|
||||
arr["suntan cream,11"] = 70
|
||||
arr["camera,32"] = 30
|
||||
arr["T-shirt,24"] = 15
|
||||
arr["trousers,48"] = 10
|
||||
arr["umbrella,73"] = 40
|
||||
arr["waterproof trousers,42"] = 70
|
||||
arr["waterproof overclothes,43"] = 75
|
||||
arr["note-case,22"] = 80
|
||||
arr["sunglasses,7"] = 20
|
||||
arr["towel,18"] = 12
|
||||
arr["socks,4"] = 50
|
||||
arr["book,30"] = 10
|
||||
sack_size = 400 # dag
|
||||
PROCINFO["sorted_in"] = "@val_num_desc"
|
||||
for (i in arr) {
|
||||
if (total_weight >= sack_size) {
|
||||
break
|
||||
}
|
||||
split(i,tmp,",")
|
||||
weight = tmp[2]
|
||||
if (total_weight + weight <= sack_size) {
|
||||
printf("%s\n",tmp[1])
|
||||
total_items++
|
||||
total_value += arr[i]
|
||||
total_weight += weight
|
||||
}
|
||||
}
|
||||
printf("items=%d (out of %d) weight=%d value=%d\n",total_items,length(arr),total_weight,total_value)
|
||||
exit(0)
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
:: Initiate command line environment
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
:: Establish arrays we'll be using
|
||||
set items=map compass water sandwich glucose tin banana apple cheese beer suntancream camera tshirt trousers umbrella waterprooftrousers waterproofoverclothes notecase sunglasses towel socks book
|
||||
set weight=9 13 153 50 15 68 27 39 23 52 11 32 24 48 73 42 43 22 7 18 4 30
|
||||
set importance=150 35 200 160 60 45 60 40 30 10 70 30 15 10 40 70 75 80 20 12 50 10
|
||||
|
||||
:: Put the above 3 arrays into their own variables with the form of "item[]", "w[]" and "i[]"
|
||||
set tempnum=0
|
||||
for %%i in (%items%) do (
|
||||
set /a tempnum+=1
|
||||
set item!tempnum!=%%i
|
||||
)
|
||||
set tempnum=0
|
||||
for %%i in (%weight%) do (
|
||||
set /a tempnum+=1
|
||||
set w!tempnum!=%%i
|
||||
)
|
||||
set tempnum=0
|
||||
for %%i in (%importance%) do (
|
||||
set /a tempnum+=1
|
||||
set i!tempnum!=%%i
|
||||
)
|
||||
:: Define the array "r[]" as the ratio between the importance ("i[]") and the weight ("w[]").
|
||||
for /l %%i in (1,1,22) do set /a r%%i=!i%%i!*100/!w%%i! & rem batch doesn't support decimals, so the numerator is multiplied by 100 to get past this
|
||||
|
||||
set totalimportance=0
|
||||
set totalweight=0
|
||||
set amount=0
|
||||
|
||||
:: Find the largest number in "r[]" and define some temp variables based off it
|
||||
:load
|
||||
set tempr=0
|
||||
set tempitem=0
|
||||
for /l %%i in (1,1,22) do (
|
||||
if !r%%i! gtr !tempr! (
|
||||
set tempr=!r%%i!
|
||||
set tempitem=%%i
|
||||
set /a testweight=%totalweight%+!w%%i!
|
||||
if !tempr!==0 goto end
|
||||
if !testweight! geq 400 goto end
|
||||
)
|
||||
)
|
||||
|
||||
:: Do basic error checking using the temp variables from above and either output and end the program or send back to load
|
||||
set /a totaltempweight=%totalweight%+!w%tempitem%!
|
||||
|
||||
if %totaltempweight% gtr 400 (
|
||||
set !r%tempitem%!=0
|
||||
goto load
|
||||
)
|
||||
|
||||
set totalweight=%totaltempweight%
|
||||
set /a totalimportance+=!i%tempitem%!
|
||||
set taken=%taken% !item%tempitem%!
|
||||
set /a amount+=1
|
||||
set r%tempitem%=0 & rem set the ratio variable of the item we just added to the knapsack as 0 to stop it repeat
|
||||
|
||||
goto load
|
||||
|
||||
:end
|
||||
echo List of things taken [%amount%]: %taken%
|
||||
echo Total Value: %totalimportance% Total Weight: %totalweight%
|
||||
pause>nul
|
||||
61
Task/Knapsack-problem-0-1/Elixir/knapsack-problem-0-1.elixir
Normal file
61
Task/Knapsack-problem-0-1/Elixir/knapsack-problem-0-1.elixir
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
defmodule Knapsack do
|
||||
def solve([], _total_weight, item_acc, value_acc, weight_acc), do:
|
||||
{item_acc, value_acc, weight_acc}
|
||||
def solve([{_item, item_weight, _item_value} | t],
|
||||
total_weight,
|
||||
item_acc,
|
||||
value_acc,
|
||||
weight_acc) when item_weight > total_weight, do:
|
||||
solve(t, total_weight, item_acc, value_acc, weight_acc)
|
||||
def solve([{item_name, item_weight, item_value} | t],
|
||||
total_weight,
|
||||
item_acc,
|
||||
value_acc,
|
||||
weight_acc) do
|
||||
{_tail_item_acc, tail_value_acc, _tail_weight_acc} = tail_res =
|
||||
solve(t, total_weight, item_acc, value_acc, weight_acc)
|
||||
{_head_item_acc, head_value_acc, _head_weight_acc} = head_res =
|
||||
solve(t,
|
||||
total_weight - item_weight,
|
||||
[item_name | item_acc],
|
||||
value_acc + item_value,
|
||||
weight_acc + item_weight)
|
||||
if tail_value_acc > head_value_acc, do: tail_res, else: head_res
|
||||
end
|
||||
end
|
||||
|
||||
stuff = [{"map", 9, 150},
|
||||
{"compass", 13, 35},
|
||||
{"water", 153, 200},
|
||||
{"sandwich", 50, 160},
|
||||
{"glucose", 15, 60},
|
||||
{"tin", 68, 45},
|
||||
{"banana", 27, 60},
|
||||
{"apple", 39, 40},
|
||||
{"cheese", 23, 30},
|
||||
{"beer", 52, 10},
|
||||
{"suntan cream", 11, 70},
|
||||
{"camera", 32, 30},
|
||||
{"T-shirt", 24, 15},
|
||||
{"trousers", 48, 10},
|
||||
{"umbrella", 73, 40},
|
||||
{"waterproof trousers", 42, 70},
|
||||
{"waterproof overclothes", 43, 75},
|
||||
{"note-case", 22, 80},
|
||||
{"sunglasses", 7, 20},
|
||||
{"towel", 18, 12},
|
||||
{"socks", 4, 50},
|
||||
{"book", 30, 10}]
|
||||
max_weight = 400
|
||||
|
||||
go = fn (stuff, max_weight) ->
|
||||
{time, {item_list, total_value, total_weight}} = :timer.tc(fn ->
|
||||
Knapsack.solve(stuff, max_weight, [], 0, 0)
|
||||
end)
|
||||
IO.puts "Items:"
|
||||
Enum.each(item_list, fn item -> IO.inspect item end)
|
||||
IO.puts "Total value: #{total_value}"
|
||||
IO.puts "Total weight: #{total_weight}"
|
||||
IO.puts "Time elapsed in milliseconds: #{time/1000}"
|
||||
end
|
||||
go.(stuff, max_weight)
|
||||
54
Task/Knapsack-problem-0-1/Kotlin/knapsack-problem-0-1.kotlin
Normal file
54
Task/Knapsack-problem-0-1/Kotlin/knapsack-problem-0-1.kotlin
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// version 1.1.2
|
||||
|
||||
data class Item(val name: String, val weight: Int, val value: Int)
|
||||
|
||||
val wants = listOf(
|
||||
Item("map", 9, 150),
|
||||
Item("compass", 13, 35),
|
||||
Item("water", 153, 200),
|
||||
Item("sandwich", 50, 160),
|
||||
Item("glucose", 15, 60),
|
||||
Item("tin", 68, 45),
|
||||
Item("banana", 27, 60),
|
||||
Item("apple", 39, 40),
|
||||
Item("cheese", 23, 30),
|
||||
Item("beer", 52, 10),
|
||||
Item("suntan cream", 11, 70),
|
||||
Item("camera", 32, 30),
|
||||
Item("T-shirt", 24, 15),
|
||||
Item("trousers", 48, 10),
|
||||
Item("umbrella", 73, 40),
|
||||
Item("waterproof trousers", 42, 70),
|
||||
Item("waterproof overclothes", 43, 75),
|
||||
Item("note-case", 22, 80),
|
||||
Item("sunglasses", 7, 20),
|
||||
Item("towel", 18, 12),
|
||||
Item("socks", 4, 50),
|
||||
Item("book", 30, 10)
|
||||
)
|
||||
|
||||
const val MAX_WEIGHT = 400
|
||||
|
||||
fun m(i: Int, w: Int): Triple<MutableList<Item>, Int, Int> {
|
||||
val chosen = mutableListOf<Item>()
|
||||
if (i < 0 || w == 0) return Triple(chosen, 0, 0)
|
||||
else if (wants[i].weight > w) return m(i - 1, w)
|
||||
val (l0, w0, v0) = m(i - 1, w)
|
||||
var (l1, w1, v1) = m(i - 1, w - wants[i].weight)
|
||||
v1 += wants[i].value
|
||||
if (v1 > v0) {
|
||||
l1.add(wants[i])
|
||||
return Triple(l1, w1 + wants[i].weight, v1)
|
||||
}
|
||||
return Triple(l0, w0, v0)
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val (chosenItems, totalWeight, totalValue) = m(wants.size - 1, MAX_WEIGHT)
|
||||
println("Knapsack Item Chosen Weight Value")
|
||||
println("---------------------- ------ -----")
|
||||
for (item in chosenItems.sortedByDescending { it.value} )
|
||||
println("${item.name.padEnd(24)} ${"%3d".format(item.weight)} ${"%3d".format(item.value)}")
|
||||
println("---------------------- ------ -----")
|
||||
println("Total ${chosenItems.size} Items Chosen $totalWeight $totalValue")
|
||||
}
|
||||
|
|
@ -8,11 +8,9 @@
|
|||
# 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, &$pickedItems) {
|
||||
function knapSolveFast2($w, $v, $i, $aW, &$m) {
|
||||
|
||||
global $numcalls;
|
||||
$numcalls ++;
|
||||
|
|
@ -40,18 +38,18 @@ function knapSolveFast2($w, $v, $i, $aW, &$m, &$pickedItems) {
|
|||
|
||||
// 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);
|
||||
list ($without_i, $without_PI) = knapSolveFast2($w, $v, $i-1, $aW, $m);
|
||||
|
||||
if ($w[$i] > $aW) { // Does it return too many?
|
||||
|
||||
$m[$i][$aW] = $without_i; // Memo without including this one
|
||||
$m['picked'][$i][$aW] = array(); // and a blank array entry...
|
||||
return array($without_i,array()); // and return it
|
||||
$m['picked'][$i][$aW] = $without_PI; // and a blank array entry...
|
||||
return array($without_i, $without_PI); // and return it
|
||||
|
||||
} else {
|
||||
|
||||
// Get the result of the next branch (WITH this one picked, so available weight is reduced)
|
||||
list ($with_i,$with_PI) = knapSolveFast2($w, $v, ($i-1), ($aW - $w[$i]),$m,$pickedItems);
|
||||
list ($with_i,$with_PI) = knapSolveFast2($w, $v, ($i-1), ($aW - $w[$i]), $m);
|
||||
$with_i += $v[$i]; // ..and add the value of this one..
|
||||
|
||||
// Get the greater of WITH or WITHOUT
|
||||
|
|
@ -81,7 +79,7 @@ $v4 = array(150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,50,10
|
|||
$numcalls = 0; $m = array(); $pickedItems = array();
|
||||
|
||||
## Solve
|
||||
list ($m4,$pickedItems) = knapSolveFast2($w4, $v4, sizeof($v4) -1, 400,$m,$pickedItems);
|
||||
list ($m4,$pickedItems) = knapSolveFast2($w4, $v4, sizeof($v4) -1, 400, $m);
|
||||
|
||||
# Display Result
|
||||
echo "<b>Items:</b><br>".join(", ",$items4)."<br>";
|
||||
|
|
|
|||
83
Task/Knapsack-problem-0-1/Pascal/knapsack-problem-0-1.pascal
Normal file
83
Task/Knapsack-problem-0-1/Pascal/knapsack-problem-0-1.pascal
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
program project1;
|
||||
uses
|
||||
sysutils, classes, math;
|
||||
|
||||
const
|
||||
MaxWeight = 400;
|
||||
N = 21;
|
||||
|
||||
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, Sum : 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 ,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
|
||||
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.
|
||||
|
|
@ -8,15 +8,15 @@ multi sub pokem ([$i, *@rest], $w, $v = 0) {
|
|||
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} = |@put, $i.name).list if @put[0] > @skip[0];
|
||||
}
|
||||
return (%cache{$key} = @skip).list;
|
||||
return (%cache{$key} = |@skip).list;
|
||||
}
|
||||
}
|
||||
|
||||
my $MAX_WEIGHT = 400;
|
||||
my @table = map -> $name, $weight, $unit {
|
||||
KnapsackItem.new: :$name, :$weight, :$unit;
|
||||
my @table = flat map -> $name, $weight, $unit {
|
||||
KnapsackItem.new: :$name, :$weight, :$unit;
|
||||
},
|
||||
'map', 9, 150,
|
||||
'compass', 13, 35,
|
||||
|
|
|
|||
68
Task/Knapsack-problem-0-1/Phix/knapsack-problem-0-1.phix
Normal file
68
Task/Knapsack-problem-0-1/Phix/knapsack-problem-0-1.phix
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
integer terminate=0
|
||||
|
||||
integer attempts = 0
|
||||
function knapsack(sequence res, goodies, atom points, weight, at=1, sequence chosen={})
|
||||
atom {witem,pitem} = goodies[at][2]
|
||||
integer n = (witem<=weight)
|
||||
chosen &= n
|
||||
points += n*pitem -- increase value
|
||||
weight -= n*witem -- decrease weight left
|
||||
if at=length(goodies) then
|
||||
attempts += 1
|
||||
if length(res)=0
|
||||
or res<{points,weight} then
|
||||
res = {points,weight,chosen}
|
||||
end if
|
||||
terminate = (n=1)
|
||||
else
|
||||
while n>=0 and not terminate do
|
||||
res = knapsack(res,goodies,points,weight,at+1,chosen)
|
||||
n -= 1
|
||||
chosen[$] = n
|
||||
points -= pitem
|
||||
weight += witem
|
||||
end while
|
||||
end if
|
||||
return res
|
||||
end function
|
||||
|
||||
function byweightedvalue(object a, b)
|
||||
-- sort by weight/value
|
||||
return compare(a[2][1]/a[2][2],b[2][1]/b[2][2])
|
||||
-- nb other sort orders break the optimisation
|
||||
end function
|
||||
|
||||
constant goodies = custom_sort(routine_id("byweightedvalue"),{
|
||||
-- item weight value
|
||||
{"map", {9, 150}},
|
||||
{"compass", {13, 35 }},
|
||||
{"water", {153, 200}},
|
||||
{"sandwich", {50, 160}},
|
||||
{"glucose", {15, 60 }},
|
||||
{"tin", {68, 45 }},
|
||||
{"banana", {27, 60 }},
|
||||
{"apple", {39, 40 }},
|
||||
{"cheese", {23, 30 }},
|
||||
{"beer", {52, 10 }},
|
||||
{"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 }}})
|
||||
|
||||
atom t0 = time()
|
||||
object {points,weight,counts} = knapsack({},goodies,0,400)
|
||||
printf(1,"Value %d, weight %g [%d attempts, %3.2fs]:\n",{points,400-weight,attempts,time()-t0})
|
||||
for i=1 to length(counts) do
|
||||
integer c = counts[i]
|
||||
if c then
|
||||
printf(1,"%s\n",{goodies[i][1]})
|
||||
end if
|
||||
end for
|
||||
|
|
@ -1,112 +1,102 @@
|
|||
/*REXX program solves a knapsack problem (23 items with a 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'
|
||||
@.23 = 'anvil 1000 1250'
|
||||
maxWeight=400 /*the maximum weight for the knapsack. */
|
||||
say 'maximum weight allowed for a knapsack:' commas(maxWeight); say
|
||||
pot_item= 'potential knapsack items' /*the full name for the header title. */
|
||||
maxL=length(pot_item) /*maximum width for the table names. */
|
||||
maxW=length('weight') /* " " " " " weights. */
|
||||
maxV=length('value') /* " " " " " values. */
|
||||
#=0; i.=; w.=0; v.=0; q.=0; Tw=0; Tv=0 /*initialize some stuff.*/
|
||||
/*══════════════════════════════════════sort the choices by decreasing weight.*/
|
||||
do j=1 while @.j\=='' /*process each of the knapsack choices.*/
|
||||
_=space(@.j); _wt=word(_, 2) /*choose the first item (arbitrary). */
|
||||
do k=j+1 while @.k\=='' /*find a possible heavier knapsack item*/
|
||||
?wt=word(@.k, 2)
|
||||
if ?wt>_wt then do; _=@.k; @.k=@.j; @.j=_; _wt=?wt; end
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
obj=j-1 /*decrement J for the DO loop index*/
|
||||
/*══════════════════════════════════════build list of choices.════════════════*/
|
||||
do j=1 for obj /*construct a list of knapsack choices.*/
|
||||
parse var @.j item w v . /*parse the original choice for table. */
|
||||
if w>maxWeight then iterate /*Is weight greater than max? Ignore.*/
|
||||
Tw=Tw+w; Tv=Tv+v /*add the totals (for output alignment)*/
|
||||
maxL=max(maxL, length(item)) /*determine the maximum width for item.*/
|
||||
#=#+1; i.#=item; w.#=w; v.#=v /*bump the number of items (choices). */
|
||||
end /*j*/
|
||||
|
||||
maxW=max(maxW,length(commas(Tw))) /*find the maximum width for weight. */
|
||||
maxV=max(maxV,length(commas(Tv))) /* " " " " " value. */
|
||||
maxL=maxL + maxL%4 + 4 /*extend the width of name for table. */
|
||||
/*══════════════════════════════════════show the list of choices.═════════════*/
|
||||
call hdr pot_item; do j=1 for obj /*show all choices in a nice format. */
|
||||
parse var @.j item weight value .
|
||||
call show item, weight, value
|
||||
end /*j*/
|
||||
say
|
||||
say 'number of allowable items: ' # /* [↓] examine all possible choices. */
|
||||
$=0; m=maxWeight
|
||||
do j1 =0 for #+1; w1 = w.j1; v1 = v.j1
|
||||
do j2 =j1 +(j1 \==0) to #; if w.j2 +w1 >m then iterate j1 ; w2 =w1 +w.j2; v2 =v1 +v.j2
|
||||
do j3 =j2 +(j2 \==0) to #; if w.j3 +w2 >m then iterate j2 ; w3 =w2 +w.j3; v3 =v2 +v.j3
|
||||
do j4 =j3 +(j3 \==0) to #; if w.j4 +w3 >m then iterate j3 ; w4 =w3 +w.j4; v4 =v3 +v.j4
|
||||
do j5 =j4 +(j4 \==0) to #; if w.j5 +w4 >m then iterate j4 ; w5 =w4 +w.j5; v5 =v4 +v.j5
|
||||
do j6 =j5 +(j5 \==0) to #; if w.j6 +w5 >m then iterate j5 ; w6 =w5 +w.j6; v6 =v5 +v.j6
|
||||
do j7 =j6 +(j6 \==0) to #; if w.j7 +w6 >m then iterate j6 ; w7 =w6 +w.j7; v7 =v6 +v.j7
|
||||
do j8 =j7 +(j7 \==0) to #; if w.j8 +w7 >m then iterate j7 ; w8 =w7 +w.j8; v8 =v7 +v.j8
|
||||
do j9 =j8 +(j8 \==0) to #; if w.j9 +w8 >m then iterate j8 ; w9 =w8 +w.j9; v9 =v8 +v.j9
|
||||
do j10=j9 +(j9 \==0) to #; if w.j10+w9 >m then iterate j9 ; w10=w9 +w.j10;v10=v9 +v.j10
|
||||
do j11=j10+(j10\==0) to #; if w.j11+w10>m then iterate j10; w11=w10+w.j11;v11=v10+v.j11
|
||||
do j12=j11+(j11\==0) to #; if w.j12+w11>m then iterate j11; w12=w11+w.j12;v12=v11+v.j12
|
||||
do j13=j12+(j12\==0) to #; if w.j13+w12>m then iterate j12; w13=w12+w.j13;v13=v12+v.j13
|
||||
do j14=j13+(j13\==0) to #; if w.j14+w13>m then iterate j13; w14=w13+w.j14;v14=v13+v.j14
|
||||
do j15=j14+(j14\==0) to #; if w.j15+w14>m then iterate j14; w15=w14+w.j15;v15=v14+v.j15
|
||||
do j16=j15+(j15\==0) to #; if w.j16+w15>m then iterate j15; w16=w15+w.j16;v16=v15+v.j16
|
||||
do j17=j16+(j16\==0) to #; if w.j17+w16>m then iterate j16; w17=w16+w.j17;v17=v16+v.j17
|
||||
do j18=j17+(j17\==0) to #; if w.j18+w17>m then iterate j17; w18=w17+w.j18;v18=v17+v.j18
|
||||
do j19=j18+(j18\==0) to #; if w.j19+w18>m then iterate j18; w19=w18+w.j19;v19=v18+v.j19
|
||||
do j20=j19+(j19\==0) to #; if w.j20+w19>m then iterate j19; w20=w19+w.j20;v20=v19+v.j20
|
||||
do j21=j20+(j20\==0) to #; if w.j21+w20>m then iterate j20; w21=w20+w.j21;v21=v20+v.j21
|
||||
do j22=j21+(j21\==0) to #; if w.j22+w21>m then iterate j21; w22=w21+w.j22;v22=v21+v.j22
|
||||
if v22>$ then do; _=22; ?=; $=v22; do j=1 for _; ?=? 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
|
||||
|
||||
bestC=?; bestW=0; bestV=$; totP=words(bestC); say
|
||||
call hdr 'best choice'
|
||||
do j=1 for totP; _=word(bestC, j); _w=w._; _v=v._
|
||||
if _==0 then iterate
|
||||
do k=j+1 to totP
|
||||
__=word(bestC, k); if i._\==i.__ then leave
|
||||
j=j+1; w._=w._+_w; v._=v._+_v
|
||||
end /*k*/
|
||||
call show i._,w._,v._; bestW=bestw+w._
|
||||
end /*j*/
|
||||
call hdr2; say; @btk= 'best total knapsack'
|
||||
call show @btk 'weight' , bestW /*display a nicely formatted winnerW. */
|
||||
call show @btk 'value' ,, bestV /* " " " " winnerV. */
|
||||
call show @btk 'items' ,,, totP /* " " " " pieces. */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
commas: procedure; parse arg _; n=_'.9'; #=123456789; b=verify(n, #, "M")
|
||||
e=verify(n, #'0', , verify(n, #"0.", 'M')) - 4
|
||||
do j=e to b by -3; _=insert(',', _, j); end /*j*/; return _
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
hdr: call show center(arg(1),maxL),center('weight',maxW),center("value",maxV)
|
||||
call hdr2; return
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
hdr2: call show copies('═',maxL),copies('═',maxW),copies('═',maxV); return
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
show: parse arg _it,_wt,_val,_p; say translate( left(_it, maxL, '─'),,"_"),
|
||||
right(commas(_wt),maxW) right(commas(_val),maxV) ' ' _p; return
|
||||
/*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*/
|
||||
|
|
|
|||
|
|
@ -1,86 +1,30 @@
|
|||
#![feature(iter_arith)]
|
||||
use std::cmp::max;
|
||||
use std::vec::Vec;
|
||||
use std::cmp;
|
||||
|
||||
|
||||
// This struct is used to store our items that we want in our knap-sack.
|
||||
#[derive(Clone, Debug)]
|
||||
struct Item<'a> {
|
||||
name: &'a str,
|
||||
struct Item {
|
||||
name: &'static str,
|
||||
weight: usize,
|
||||
value: usize
|
||||
}
|
||||
|
||||
|
||||
// This is a bottom-up dynamic programming solution to the 0-1 knap-sack problem.
|
||||
// maximize value
|
||||
// subject to weights <= max_weight
|
||||
fn knapsack01_dyn<'a>(items: &[Item<'a>], max_weight: usize) -> Vec<Item<'a>> {
|
||||
// Imagine we wrote a recursive function(item, max_weight) that returns a
|
||||
// usize corresponding to the maximum cumulative value by considering a
|
||||
// subset of items such that the combined weight <= max_weight.
|
||||
//
|
||||
// fn best_value(item: usize, max_weight: usize) -> usize {
|
||||
// if item == 0 {
|
||||
// return 0;
|
||||
// }
|
||||
// if items[item - 1].weight > max_weight {
|
||||
// return best_value(item - 1, max_weight);
|
||||
// }
|
||||
// return max(best_value(item - 1, max_weight),
|
||||
// best_value(item - 1, max_weight - items[item - 1].weight)
|
||||
// + items[item - 1].value);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// best_value(n_items, max_weight) is equal to the maximum value that
|
||||
// we can add to the bag.
|
||||
//
|
||||
// The problem with using this function is that it performs redundant
|
||||
// calculations.
|
||||
//
|
||||
// The dynamic programming solution is to precompute all of the values
|
||||
// we need and put them into a 2D array.
|
||||
//
|
||||
// In a similar vein, the top-down solution would be to memoize the
|
||||
// function then compute the results on demand.
|
||||
|
||||
let mut best_value = vec![vec![0usize; max_weight + 1]; items.len() + 1];
|
||||
|
||||
// Loop over the items.
|
||||
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() {
|
||||
// Loop over the weights.
|
||||
for w in 1 .. max_weight + 1 {
|
||||
best_value[i + 1][w] =
|
||||
// do we have room in our knapsack?
|
||||
if it.weight > w {
|
||||
// if we don't, then we'll say that the value doesn't change
|
||||
// when considering this item
|
||||
best_value[i][w].clone()
|
||||
best_value[i][w]
|
||||
} else {
|
||||
// If we do, then we have to see if the value we gain by adding
|
||||
// the item, given the weight, is better than not adding the item.
|
||||
max(best_value[i][w].clone(), best_value[i][w - it.weight] + it.value)
|
||||
cmp::max(best_value[i][w], best_value[i][w - it.weight] + it.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A possibly over-allocated dynamically sized vector to push results to.
|
||||
let mut result = Vec::with_capacity(items.len());
|
||||
let mut left_weight = max_weight;
|
||||
|
||||
// Variable representing the weight left in the bag
|
||||
let mut left_weight = max_weight.clone();
|
||||
|
||||
// We built up the solution space through a forward pass over the data,
|
||||
// now we have to traverse backwards to get the solution.
|
||||
for (i, it) in items.iter().enumerate().rev() {
|
||||
// We can check if an item should be added to the knap-sack by
|
||||
// comparing best_value with and without this item. If best_value
|
||||
// added this item then so should we.
|
||||
if best_value[i + 1][left_weight] != best_value[i][left_weight] {
|
||||
result.push(it.clone());
|
||||
// We remove the weight of the object from the remaining weight
|
||||
// we can add to the bag.
|
||||
result.push(it);
|
||||
left_weight -= it.weight;
|
||||
}
|
||||
}
|
||||
|
|
@ -92,9 +36,7 @@ fn knapsack01_dyn<'a>(items: &[Item<'a>], max_weight: usize) -> Vec<Item<'a>> {
|
|||
fn main () {
|
||||
const MAX_WEIGHT: usize = 400;
|
||||
|
||||
// Static immutable allocation of our items.
|
||||
static ITEMS: &'static [Item<'static>] = &[
|
||||
// Too much repetition of field names here!
|
||||
const ITEMS: &[Item] = &[
|
||||
Item { name: "map", weight: 9, value: 150 },
|
||||
Item { name: "compass", weight: 13, value: 35 },
|
||||
Item { name: "water", weight: 153, value: 200 },
|
||||
|
|
@ -123,12 +65,9 @@ fn main () {
|
|||
|
||||
// We reverse the order because we solved the problem backward.
|
||||
for it in items.iter().rev() {
|
||||
println!("{:?}", it);
|
||||
println!("{}", it.name);
|
||||
}
|
||||
|
||||
let tot_weight: usize = items.iter().map(|w| w.weight).sum();
|
||||
println!("Total weight: {}", tot_weight);
|
||||
|
||||
let tot_value: usize = items.iter().map(|w| w.value).sum();
|
||||
println!("Total value: {}", tot_value);
|
||||
println!("Total weight: {}", items.iter().map(|w| w.weight).sum::<usize>());
|
||||
println!("Total value: {}", items.iter().map(|w| w.value).sum::<usize>());
|
||||
}
|
||||
|
|
|
|||
58
Task/Knapsack-problem-0-1/VBA/knapsack-problem-0-1.vba
Normal file
58
Task/Knapsack-problem-0-1/VBA/knapsack-problem-0-1.vba
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
'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
|
||||
214
Task/Knapsack-problem-0-1/VBScript/knapsack-problem-0-1.vb
Normal file
214
Task/Knapsack-problem-0-1/VBScript/knapsack-problem-0-1.vb
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
' Knapsack problem/0-1 - 13/02/2017
|
||||
dim w(22),v(22),m(22)
|
||||
data=array( "map", 9, 150, "compass", 13, 35, "water", 153, 200, _
|
||||
"sandwich", 50, 160 , "glucose", 15, 60, "tin", 68, 45, _
|
||||
"banana", 27, 60, "apple", 39, 40 , "cheese", 23, 30, "beer", 52, 10, _
|
||||
"suntan cream", 11, 70, "camera", 32, 30 , "T-shirt", 24, 15, _
|
||||
"trousers", 48, 10, "umbrella", 73, 40, "book", 30, 10 , _
|
||||
"waterproof trousers", 42, 70, "waterproof overclothes", 43, 75 , _
|
||||
"note-case", 22, 80, "sunglasses", 7, 20, "towel", 18, 12, "socks", 4, 50)
|
||||
ww=400
|
||||
xw=0:iw=0:iv=0
|
||||
w(1)=iw:v(1)=iv
|
||||
for i1=0 to 1:m(1)=i1:j=0
|
||||
if i1=1 then
|
||||
iw=w(1)+data(j*3+1):iv=v(1)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i1
|
||||
if iw<=ww then
|
||||
w(2)=iw: v(2)=iv
|
||||
for i2=0 to 1:m(2)=i2:j=1
|
||||
if i2=1 then
|
||||
iw=w(2)+data(j*3+1):iv=v(2)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i2
|
||||
if iw<=ww then
|
||||
w(3)=iw: v(3)=iv
|
||||
for i3=0 to 1:m(3)=i3:j=2
|
||||
if i3=1 then
|
||||
iw=w(3)+data(j*3+1):iv=v(3)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i3
|
||||
if iw<=ww then
|
||||
w(4)=iw: v(4)=iv
|
||||
for i4=0 to 1:m(4)=i4:j=3
|
||||
if i4=1 then
|
||||
iw=w(4)+data(j*3+1):iv=v(4)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i4
|
||||
if iw<=ww then
|
||||
w(5)=iw: v(5)=iv
|
||||
for i5=0 to 1:m(5)=i5:j=4
|
||||
if i5=1 then
|
||||
iw=w(5)+data(j*3+1):iv=v(5)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i5
|
||||
if iw<=ww then
|
||||
w(6)=iw: v(6)=iv
|
||||
for i6=0 to 1:m(6)=i6:j=5
|
||||
if i6=1 then
|
||||
iw=w(6)+data(j*3+1):iv=v(6)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i6
|
||||
if iw<=ww then
|
||||
w(7)=iw: v(7)=iv
|
||||
for i7=0 to 1:m(7)=i7:j=6
|
||||
if i7=1 then
|
||||
iw=w(7)+data(j*3+1):iv=v(7)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i7
|
||||
if iw<=ww then
|
||||
w(8)=iw: v(8)=iv
|
||||
for i8=0 to 1:m(8)=i8:j=7
|
||||
if i8=1 then
|
||||
iw=w(8)+data(j*3+1):iv=v(8)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i8
|
||||
if iw<=ww then
|
||||
w(9)=iw: v(9)=iv
|
||||
for i9=0 to 1:m(9)=i9:j=8
|
||||
if i9=1 then
|
||||
iw=w(9)+data(j*3+1):iv=v(9)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i9
|
||||
if iw<=ww then
|
||||
w(10)=iw: v(10)=iv
|
||||
for i10=0 to 1:m(10)=i10:j=9
|
||||
if i10=1 then
|
||||
iw=w(10)+data(j*3+1):iv=v(10)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i10
|
||||
if iw<=ww then
|
||||
w(11)=iw: v(11)=iv
|
||||
for i11=0 to 1:m(11)=i11:j=10
|
||||
if i11=1 then
|
||||
iw=w(11)+data(j*3+1):iv=v(11)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i11
|
||||
if iw<=ww then
|
||||
w(12)=iw: v(12)=iv
|
||||
for i12=0 to 1:m(12)=i12:j=11
|
||||
if i12=1 then
|
||||
iw=w(12)+data(j*3+1):iv=v(12)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i12
|
||||
if iw<=ww then
|
||||
w(13)=iw: v(13)=iv
|
||||
for i13=0 to 1:m(13)=i13:j=12
|
||||
if i13=1 then
|
||||
iw=w(13)+data(j*3+1):iv=v(13)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i13
|
||||
if iw<=ww then
|
||||
w(14)=iw: v(14)=iv
|
||||
for i14=0 to 1:m(14)=i14:j=13
|
||||
if i14=1 then
|
||||
iw=w(14)+data(j*3+1):iv=v(14)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i14
|
||||
if iw<=ww then
|
||||
w(15)=iw: v(15)=iv
|
||||
for i15=0 to 1:m(15)=i15:j=14
|
||||
if i15=1 then
|
||||
iw=w(15)+data(j*3+1):iv=v(15)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i15
|
||||
if iw<=ww then
|
||||
w(16)=iw: v(16)=iv
|
||||
for i16=0 to 1:m(16)=i16:j=15
|
||||
if i16=1 then
|
||||
iw=w(16)+data(j*3+1):iv=v(16)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i16
|
||||
if iw<=ww then
|
||||
w(17)=iw: v(17)=iv
|
||||
for i17=0 to 1:m(17)=i17:j=16
|
||||
if i17=1 then
|
||||
iw=w(17)+data(j*3+1):iv=v(17)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i17
|
||||
if iw<=ww then
|
||||
w(18)=iw: v(18)=iv
|
||||
for i18=0 to 1:m(18)=i18:j=17
|
||||
if i18=1 then
|
||||
iw=w(18)+data(j*3+1):iv=v(18)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i18
|
||||
if iw<=ww then
|
||||
w(19)=iw: v(19)=iv
|
||||
for i19=0 to 1:m(19)=i19:j=18
|
||||
if i19=1 then
|
||||
iw=w(19)+data(j*3+1):iv=v(19)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i19
|
||||
if iw<=ww then
|
||||
w(20)=iw: v(20)=iv
|
||||
for i20=0 to 1:m(20)=i20:j=19
|
||||
if i20=1 then
|
||||
iw=w(20)+data(j*3+1):iv=v(20)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i20
|
||||
if iw<=ww then
|
||||
w(21)=iw: v(21)=iv
|
||||
for i21=0 to 1:m(21)=i21:j=20
|
||||
if i21=1 then
|
||||
iw=w(21)+data(j*3+1):iv=v(21)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i21
|
||||
if iw<=ww then
|
||||
w(22)=iw: v(22)=iv
|
||||
for i22=0 to 1:m(22)=i22:j=21
|
||||
nn=nn+1
|
||||
if i22=1 then
|
||||
iw=w(22)+data(j*3+1):iv=v(22)+data(j*3+2)
|
||||
if iv>xv and iw<=ww then xw=iw:xv=iv:l=m
|
||||
end if 'i22
|
||||
if iw<=ww then
|
||||
end if 'i22
|
||||
next:m(22)=0
|
||||
end if 'i21
|
||||
next:m(21)=0
|
||||
end if 'i20
|
||||
next:m(20)=0
|
||||
end if 'i19
|
||||
next:m(19)=0
|
||||
end if 'i18
|
||||
next:m(18)=0
|
||||
end if 'i17
|
||||
next:m(17)=0
|
||||
end if 'i16
|
||||
next:m(16)=0
|
||||
end if 'i15
|
||||
next:m(15)=0
|
||||
end if 'i14
|
||||
next:m(14)=0
|
||||
end if 'i13
|
||||
next:m(13)=0
|
||||
end if 'i12
|
||||
next:m(12)=0
|
||||
end if 'i11
|
||||
next:m(11)=0
|
||||
end if 'i10
|
||||
next:m(10)=0
|
||||
end if 'i9
|
||||
next:m(9)=0
|
||||
end if 'i8
|
||||
next:m(8)=0
|
||||
end if 'i7
|
||||
next:m(7)=0
|
||||
end if 'i6
|
||||
next:m(6)=0
|
||||
end if 'i5
|
||||
next:m(5)=0
|
||||
end if 'i4
|
||||
next:m(4)=0
|
||||
end if 'i3
|
||||
next:m(3)=0
|
||||
end if 'i2
|
||||
next:m(2)=0
|
||||
end if 'i1
|
||||
next:m(1)=0
|
||||
for i=1 to 22
|
||||
if l(i)=1 then wlist=wlist&vbCrlf&data((i-1)*3)
|
||||
next
|
||||
Msgbox mid(wlist,3)&vbCrlf&vbCrlf&"weight="&xw&vbCrlf&"value="&xv,,"Knapsack - nn="&nn
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
'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
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
'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
|
||||
6
Task/Knapsack-problem-0-1/Zkl/knapsack-problem-0-1-1.zkl
Normal file
6
Task/Knapsack-problem-0-1/Zkl/knapsack-problem-0-1-1.zkl
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
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
|
||||
13
Task/Knapsack-problem-0-1/Zkl/knapsack-problem-0-1-2.zkl
Normal file
13
Task/Knapsack-problem-0-1/Zkl/knapsack-problem-0-1-2.zkl
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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);
|
||||
Loading…
Add table
Add a link
Reference in a new issue