2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -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], and their total value is maximized.
|
||||
|
||||
[dag = decagram = 10 grams]
|
||||
|
||||
;See also:
|
||||
* [[Knapsack problem/Unbounded]]
|
||||
* [[Knapsack problem/Bounded]]
|
||||
|
||||
;Related tasks:
|
||||
* [[Knapsack problem/Unbounded]]
|
||||
* [[Knapsack problem/Bounded]]
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
71
Task/Knapsack-problem-0-1/Erlang/knapsack-problem-0-1.erl
Normal file
71
Task/Knapsack-problem-0-1/Erlang/knapsack-problem-0-1.erl
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
-module(knapsack_0_1).
|
||||
|
||||
-export([go/0,
|
||||
solve/5]).
|
||||
|
||||
-define(STUFF,
|
||||
[{"map", 9, 150},
|
||||
{"compass", 13, 35},
|
||||
{"water", 153, 200},
|
||||
{"sandwich", 50, 160},
|
||||
{"glucose", 15, 60},
|
||||
{"tin", 68, 45},
|
||||
{"banana", 27, 60},
|
||||
{"apple", 39, 40},
|
||||
{"cheese", 23, 30},
|
||||
{"beer", 52, 10},
|
||||
{"suntan cream", 11, 70},
|
||||
{"camera", 32, 30},
|
||||
{"T-shirt", 24, 15},
|
||||
{"trousers", 48, 10},
|
||||
{"umbrella", 73, 40},
|
||||
{"waterproof trousers", 42, 70},
|
||||
{"waterproof overclothes", 43, 75},
|
||||
{"note-case", 22, 80},
|
||||
{"sunglasses", 7, 20},
|
||||
{"towel", 18, 12},
|
||||
{"socks", 4, 50},
|
||||
{"book", 30, 10}
|
||||
]).
|
||||
|
||||
-define(MAX_WEIGHT, 400).
|
||||
|
||||
go() ->
|
||||
StartTime = os:timestamp(),
|
||||
{ItemList, TotalValue, TotalWeight} =
|
||||
solve(?STUFF, ?MAX_WEIGHT, [], 0, 0),
|
||||
TimeElapsed = timer:now_diff(os:timestamp(), StartTime),
|
||||
io:format("Items: ~n"),
|
||||
[io:format("~p~n", [Item]) || Item <- ItemList],
|
||||
io:format(
|
||||
"Total value: ~p~nTotal weight: ~p~nTime elapsed in milliseconds: ~p~n",
|
||||
[TotalValue, TotalWeight, TimeElapsed/1000]).
|
||||
|
||||
solve([], _TotalWeight, ItemAcc, ValueAcc, WeightAcc) ->
|
||||
{ItemAcc, ValueAcc, WeightAcc};
|
||||
solve([{_Item, ItemWeight, _ItemValue} | T],
|
||||
TotalWeight,
|
||||
ItemAcc,
|
||||
ValueAcc,
|
||||
WeightAcc) when ItemWeight > TotalWeight ->
|
||||
solve(T, TotalWeight, ItemAcc, ValueAcc, WeightAcc);
|
||||
solve([{ItemName, ItemWeight, ItemValue} | T],
|
||||
TotalWeight,
|
||||
ItemAcc,
|
||||
ValueAcc,
|
||||
WeightAcc) ->
|
||||
{_TailItemAcc, TailValueAcc, _TailWeightAcc} = TailRes =
|
||||
solve(T, TotalWeight, ItemAcc, ValueAcc, WeightAcc),
|
||||
{_HeadItemAcc, HeadValueAcc, _HeadWeightAcc} = HeadRes =
|
||||
solve(T,
|
||||
TotalWeight - ItemWeight,
|
||||
[ItemName | ItemAcc],
|
||||
ValueAcc + ItemValue,
|
||||
WeightAcc + ItemWeight),
|
||||
|
||||
case TailValueAcc > HeadValueAcc of
|
||||
true ->
|
||||
TailRes;
|
||||
false ->
|
||||
HeadRes
|
||||
end.
|
||||
|
|
@ -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)
|
||||
7
Task/Knapsack-problem-0-1/Go/knapsack-problem-0-1-2.go
Normal file
7
Task/Knapsack-problem-0-1/Go/knapsack-problem-0-1-2.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
var wants = []item{
|
||||
{"sunscreen", 15, 2},
|
||||
{"GPS", 25, 2},
|
||||
{"beer", 35, 3},
|
||||
}
|
||||
|
||||
const maxWt = 40
|
||||
9
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-3.j
Normal file
9
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-3.j
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
'names values'=:|:".;._2]0 :0
|
||||
'sunscreen'; 15 2
|
||||
'GPS'; 25 2
|
||||
'beer'; 35 3
|
||||
)
|
||||
|
||||
X=: +/ .*"1
|
||||
plausible=: (] (] #~ 40 >: X) #:@i.@(2&^)@#)@:({."1)
|
||||
best=: (plausible ([ {~ [ (i. >./)@:X {:"1@]) ]) values
|
||||
5
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-4.j
Normal file
5
Task/Knapsack-problem-0-1/J/knapsack-problem-0-1-4.j
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
+/best#values
|
||||
40 4
|
||||
best#names
|
||||
sunscreen
|
||||
GPS
|
||||
|
|
@ -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
|
||||
|
|
|
|||
49
Task/Knapsack-problem-0-1/SAS/knapsack-problem-0-1.sas
Normal file
49
Task/Knapsack-problem-0-1/SAS/knapsack-problem-0-1.sas
Normal 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;
|
||||
Loading…
Add table
Add a link
Reference in a new issue