2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,12 +1,17 @@
{{omit from|GUISS}}
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 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:
Here is the list:
{| style="text-align: left; width: 80%;" border="4" cellpadding="2" cellspacing="2"
|+ Table of potential knapsack items
|- style="background-color: rgb(255, 204, 255);"
@ -59,16 +64,21 @@ Here is the list:
| knapsack || ≤400 dag || ?
|}
<br>
The tourist can choose to take any combination of items from the list,
but only one of each item is available.
He may not cut or diminish the items, so he can only take whole units of any item.
'''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:
* [[Knapsack problem/Unbounded]]
* [[Knapsack problem/Bounded]]
;Related tasks:
* &nbsp; [[Knapsack problem/Unbounded]]
* &nbsp; [[Knapsack problem/Bounded]]
<br><br>

View file

@ -1,91 +1,78 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct {
const char * name;
int weight, value;
char *name;
int weight;
int value;
} item_t;
item_t item[] = {
{"map", 9, 150},
{"compass", 13, 35},
{"water", 153, 200},
{"sandwich", 50, 160},
{"glucose", 15, 60},
{"tin", 68, 45},
{"banana", 27, 60},
{"apple", 39, 40},
{"cheese", 23, 30},
{"beer", 52, 10},
{"suntancream", 11, 70},
{"camera", 32, 30},
{"T-shirt", 24, 15},
{"trousers", 48, 10},
{"umbrella", 73, 40},
{"waterproof trousers", 42, 70},
{"waterproof overclothes", 43, 75},
{"note-case", 22, 80},
{"sunglasses", 7, 20},
{"towel", 18, 12},
{"socks", 4, 50},
{"book", 30, 10}
item_t items[] = {
{"map", 9, 150},
{"compass", 13, 35},
{"water", 153, 200},
{"sandwich", 50, 160},
{"glucose", 15, 60},
{"tin", 68, 45},
{"banana", 27, 60},
{"apple", 39, 40},
{"cheese", 23, 30},
{"beer", 52, 10},
{"suntan cream", 11, 70},
{"camera", 32, 30},
{"T-shirt", 24, 15},
{"trousers", 48, 10},
{"umbrella", 73, 40},
{"waterproof trousers", 42, 70},
{"waterproof overclothes", 43, 75},
{"note-case", 22, 80},
{"sunglasses", 7, 20},
{"towel", 18, 12},
{"socks", 4, 50},
{"book", 30, 10},
};
#define n_items (sizeof(item)/sizeof(item_t))
typedef struct {
uint32_t bits; /* 32 bits, can solve up to 32 items */
int value;
} solution;
void optimal(int weight, int idx, solution *s)
{
function solve(itemArray, capacity){
matrix = create2DMatrix(itemArray.length, capacity);
keep_matrix = create2DMatrix(itemArray.length, capacity);
for(var c=0; c <= capacity; c++){
matrix[0][c] = 0;
keep_matrix[0][c] = 0;
}
for(var r=1; r<itemArray.length+1; ++r){//rows
for(var c=0; c<=capacity; ++c){
var toMatrix = 0;
//fit in itself?
var fit = items[r-1].weight<= c;
if(fit){//add remaining mini-knapsack if any, and compare to not putting it
var restCap = c-items[r-1].weight;
toMatrix = items[r-1].value+ matrix[r-1][restCap];
if( toMatrix > matrix[r-1][c])
keep_matrix[r][c] = 1;
else
keep_matrix[r][c] = 0;
toMatrix = Math.max(toMatrix, matrix[r-1][c]);
}else{//copy the knapsack from row above
toMatrix = matrix[r-1][c];
keep_matrix[r][c] = 0;
}
matrix[r][c] = toMatrix;
}
}
return matrix;
}
}
int main(void)
{
int i = 0, w = 0;
solution s = {0, 0};
optimal(400, n_items - 1, &s);
for (i = 0; i < n_items; i++) {
if (s.bits & (1 << i)) {
printf("%s\n", item[i].name);
w += item[i].weight;
}
int *knapsack (item_t *items, int n, int w) {
int i, j, a, b, *mm, **m, *s;
mm = calloc((n + 1) * (w + 1), sizeof (int));
m = malloc((n + 1) * sizeof (int *));
m[0] = mm;
for (i = 1; i <= n; i++) {
m[i] = &mm[i * (w + 1)];
for (j = 0; j <= w; j++) {
if (items[i - 1].weight > j) {
m[i][j] = m[i - 1][j];
}
else {
a = m[i - 1][j];
b = m[i - 1][j - items[i - 1].weight] + items[i - 1].value;
m[i][j] = a > b ? a : b;
}
}
printf("Total value: %d; weight: %d\n", s.value, w);
return 0;
}
s = calloc(n, sizeof (int));
for (i = n, j = w; i > 0; i--) {
if (m[i][j] > m[i - 1][j]) {
s[i - 1] = 1;
j -= items[i - 1].weight;
}
}
free(mm);
free(m);
return s;
}
int main () {
int i, n, tw = 0, tv = 0, *s;
n = sizeof (items) / sizeof (item_t);
s = knapsack(items, n, 400);
for (i = 0; i < n; i++) {
if (s[i]) {
printf("%-22s %5d %5d\n", items[i].name, items[i].weight, items[i].value);
tw += items[i].weight;
tv += items[i].value;
}
}
printf("%-22s %5d %5d\n", "totals:", tw, tv);
return 0;
}

View file

@ -0,0 +1,71 @@
-module(knapsack_0_1).
-export([go/0,
solve/5]).
-define(STUFF,
[{"map", 9, 150},
{"compass", 13, 35},
{"water", 153, 200},
{"sandwich", 50, 160},
{"glucose", 15, 60},
{"tin", 68, 45},
{"banana", 27, 60},
{"apple", 39, 40},
{"cheese", 23, 30},
{"beer", 52, 10},
{"suntan cream", 11, 70},
{"camera", 32, 30},
{"T-shirt", 24, 15},
{"trousers", 48, 10},
{"umbrella", 73, 40},
{"waterproof trousers", 42, 70},
{"waterproof overclothes", 43, 75},
{"note-case", 22, 80},
{"sunglasses", 7, 20},
{"towel", 18, 12},
{"socks", 4, 50},
{"book", 30, 10}
]).
-define(MAX_WEIGHT, 400).
go() ->
StartTime = os:timestamp(),
{ItemList, TotalValue, TotalWeight} =
solve(?STUFF, ?MAX_WEIGHT, [], 0, 0),
TimeElapsed = timer:now_diff(os:timestamp(), StartTime),
io:format("Items: ~n"),
[io:format("~p~n", [Item]) || Item <- ItemList],
io:format(
"Total value: ~p~nTotal weight: ~p~nTime elapsed in milliseconds: ~p~n",
[TotalValue, TotalWeight, TimeElapsed/1000]).
solve([], _TotalWeight, ItemAcc, ValueAcc, WeightAcc) ->
{ItemAcc, ValueAcc, WeightAcc};
solve([{_Item, ItemWeight, _ItemValue} | T],
TotalWeight,
ItemAcc,
ValueAcc,
WeightAcc) when ItemWeight > TotalWeight ->
solve(T, TotalWeight, ItemAcc, ValueAcc, WeightAcc);
solve([{ItemName, ItemWeight, ItemValue} | T],
TotalWeight,
ItemAcc,
ValueAcc,
WeightAcc) ->
{_TailItemAcc, TailValueAcc, _TailWeightAcc} = TailRes =
solve(T, TotalWeight, ItemAcc, ValueAcc, WeightAcc),
{_HeadItemAcc, HeadValueAcc, _HeadWeightAcc} = HeadRes =
solve(T,
TotalWeight - ItemWeight,
[ItemName | ItemAcc],
ValueAcc + ItemValue,
WeightAcc + ItemWeight),
case TailValueAcc > HeadValueAcc of
true ->
TailRes;
false ->
HeadRes
end.

View file

@ -32,8 +32,10 @@ var wants = []item{
{"book", 30, 10},
}
const maxWt = 400
func main() {
items, w, v := m(len(wants)-1, 400)
items, w, v := m(len(wants)-1, maxWt)
fmt.Println(items)
fmt.Println("weight:", w)
fmt.Println("value:", v)

View file

@ -0,0 +1,7 @@
var wants = []item{
{"sunscreen", 15, 2},
{"GPS", 25, 2},
{"beer", 35, 3},
}
const maxWt = 40

View file

@ -0,0 +1,9 @@
'names values'=:|:".;._2]0 :0
'sunscreen'; 15 2
'GPS'; 25 2
'beer'; 35 3
)
X=: +/ .*"1
plausible=: (] (] #~ 40 >: X) #:@i.@(2&^)@#)@:({."1)
best=: (plausible ([ {~ [ (i. >./)@:X {:"1@]) ]) values

View file

@ -0,0 +1,5 @@
+/best#values
40 4
best#names
sunscreen
GPS

View file

@ -1,4 +1,4 @@
/*REXX program solves a knapsack problem (22 items with a weight restriction).*/
/*REXX program solves a knapsack problem (23 items with a weight restriction).*/
@.=; @.1 = 'map 9 150'
@.2 = 'compass 13 35'
@.3 = 'water 153 200'
@ -21,124 +21,92 @@
@.20 = 'towel 18 12'
@.21 = 'socks 4 50'
@.22 = 'book 30 10'
maxWeight=400 /*maximum weight for the knapsack*/
say; say 'maximum weight allowed for a knapsack:' commas(maxWeight); say
maxL=length('item') /*maximum width for table names. */
maxL=length('knapsack items') /*maximum width for table names. */
maxW=length('weight') /* " " " " weights*/
maxV=length('value') /* " " " " values.*/
maxQ=length('pieces') /* " " " " quant. */
highQ=0 /*max quantity specified (if any)*/
items=0; i.=; w.=0; v.=0; q.=0; Tw=0; Tv=0; Tq=0 /*initialize stuff.*/
/*════════════════════════════════sort the choices by decreasing weight.*/
do j=1 while @.j\=='' /*process each choice and sort. */
_=space(@.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
@.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*/ /*adjust for the DO loop index.*/
obj=j-1
/*════════════════════════════════build list of choices.════════════════*/
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*/
do j=1 for obj /*build a list of choices. */
parse var @.j item w v q . /*parse original choice for table*/
if w>maxWeight then iterate /*if the weight > maximum, ignore*/
Tw=Tw+w; Tv=Tv+v; Tq=Tq+1 /*add totals up (for alignment). */
maxL=max(maxL,length(item)) /*find maximum width for item. */
if q=='' then q=1
highQ=max(highQ,q)
items=items+1 /*bump # items.*/
i.items=item; w.items=w; v.items=v; q.items=q
do k=2 to q; items=items+1 /*bump # items.*/
i.items=item; w.items=w; v.items=v; q.items=q
Tw=Tw+w; Tv=Tv+v; Tq=Tq+1
end /*k*/
end /*j*/
maxW=max(maxW,length(commas(Tw))) /*find maximum width for weight. */
maxV=max(maxV,length(commas(Tv))) /* " " " " value. */
maxQ=max(maxQ,length(commas(Tq))) /* " " " " quantity*/
maxL=maxL+maxL%4+4 /*extend width of name for table.*/
/*════════════════════════════════show the list of choices.═════════════*/
call hdr 'item'; do j=1 for obj /*show all choices, nice format. */
parse var @.j item weight value q .
if highq==1 then q=
else if q=='' then q=1
call show item, weight, value, q
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
say; say 'number of items:' items; say
/*═════════════════════════════════════examine all the possible choices.*/
h=items; ho=h+1; m=maxWeight; $=0; call sim22
/*═════════════════════════════════════show the best choice (weight,val)*/
do h-1; ?=strip(strip(?),"L",0); end
bestC=?; bestW=0; bestV=$; highQ=0; totP=words(bestC)
bestC=?; bestW=0; bestV=$; totP=words(bestC); say
call hdr 'best choice'
do j=1 to totP /*J is modified within DO loop. */
_=word(bestC,j); _w=w._; _v=v._; q=1
if _==0 then iterate
do k=j+1 to totP
__=word(bestC,k); if i._\==i.__ then leave
j=j+1; w._=w._+_w; v._=v._+_v; q=q+1
end /*k*/
call show i._,w._,v._,q; bestW=bestw+w._
end /*j*/
call hdr2; say
call show 'best weight' ,bestW /*show a nicely formatted winnerW. */
call show 'best value' ,,bestV /*show a nicely formatted winnerV. */
call show 'knapsack items',,,totP /*show a nicely formatted pieces. */
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: parse arg _item_,_; if highq\==1 then _=center('pieces',maxq)
call show center(_item_,maxL),center('weight',maxW),center('value',maxV),center(_,maxQ)
call hdr2; return
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 _
/*────────────────────────────────────────────────────────────────────────────*/
hdr2: _=maxQ; if highq==1 then _=0
call show copies('',maxL),copies('',maxW),copies('',maxV),copies('',_)
return
/*─────────────────────────────────────────────────────────────────────────────────────*/
j?: parse arg _,?; $=value('V'_); do j=1 for _; ?=? value('J'j); end; return
hdr: call show center(arg(1),maxL),center('weight',maxW),center("value",maxV)
call hdr2; return
/*────────────────────────────────────────────────────────────────────────────*/
show: parse arg _item,_weight,_value,_quant
say translate(left(_item,maxL,''),,'_') right(commas(_weight),maxW),
right(commas(_value ),maxV),
right(commas(_quant ),maxQ)
return
/*───────────────────────────────────────────────────────────────────────────────────────────────────────────*/
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
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

View file

@ -0,0 +1,49 @@
/* 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;