Knapsack problem/Continuous: Difference between revisions
Content added Content deleted
(→version 1: displayed the numbers better, increased precision to three digits, added comments, created a descending sort subroutine (instead of in-line code), indicated {all} when items were taken in entirety.) |
|||
Line 1,975: | Line 1,975: | ||
Originally used the Fortran program as a prototype. |
Originally used the Fortran program as a prototype. |
||
<br>Some amount of code was added to make the output pretty. |
<br>Some amount of code was added to make the output pretty. |
||
<lang rexx>/*REXX program solves the burglar's knapsack |
<lang rexx>/*REXX program solves the (continuous) burglar's knapsack problem. */ |
||
@.= |
@.= /*═══════ name weight value ══════*/ |
||
@.1 = 'flitch 4 30 ' |
|||
@.2 = 'beef 3.8 36 ' |
|||
@.3 = 'pork 5.4 43 ' |
|||
@.4 = 'greaves 2.4 45 ' |
|||
@.5 = 'brawn 2.5 56 ' |
|||
@.6 = 'welt 3.7 67 ' |
|||
@.7 = 'ham 3.6 90 ' |
|||
@.8 = 'salami 3 95 ' |
|||
@.9 = 'sausage 5.9 98 ' |
|||
parse arg maxW |
parse arg maxW d . /*get possible args from the C.L.*/ |
||
if maxW=='' | maxW==',' then maxW=15 /*burglar's knapsack max weight. */ |
if maxW=='' | maxW==',' then maxW=15 /*burglar's knapsack max weight. */ |
||
if |
if d=='' | d==',' then d= 3 /*# of decimal digits in FORMAT. */ |
||
wL=length(' |
wL=d+length('weight'); nL=d+length('total weight'); vL=d+length('value') |
||
totW=0; totV=0 |
totW=0; totV=0 |
||
do #=1 while @.#\==''; parse var @.# n.# w.# v.# . |
|||
end /*#*/ /* [↑] assign to separate lists.*/ |
|||
#=#-1 /*#: number of items in @ list.*/ |
|||
call show 'unsorted item list' /*display |
call show 'unsorted item list' /*display header and the @ list.*/ |
||
call sortD /*invoke using a descending sort.*/ |
|||
⚫ | |||
do sorts=2 to items /*sort: descending value/unit wt.*/ |
|||
⚫ | |||
_n=n.sorts; _w=w.sorts; _v=v.sorts /*calc. placeholders for DO loop.*/ |
|||
if totW+w.j>=maxW then f=(maxW-totW)/w.j /*calc fract*/ |
|||
totW=totW+w.j*f; totV=totV+v.j*f /*add──►tots*/ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
call sep; say /* [↓] $ supresses trailing Θs.*/ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
if totW+w.j>=maxW then f=(maxW-totW)/w.j |
|||
totW=totW+w.j*f; totV=totV+v.j*f |
|||
⚫ | |||
⚫ | |||
call sep |
|||
⚫ | |||
⚫ | |||
exit /*stick a fork in it, we're done.*/ |
exit /*stick a fork in it, we're done.*/ |
||
/*──────────────────────────────────one─liner |
/*──────────────────────────────────one─liner subroutines──────────────────────*/ |
||
hdr: say; say center(arg(1),50,'─'); |
hdr: say; say; say center(arg(1),50,'─'); say; call title; call sep; return |
||
sep: call sy copies('═',nL), copies("═",wL), copies('═',vL); return |
sep: call sy copies('═',nL), copies("═",wL), copies('═',vL); return |
||
show: call hdr arg(1); do j=1 for |
show: call hdr arg(1); do j=1 for #; call syf n.j,w.j,v.j; end; return |
||
sy: say left('',9) left(arg(1),nL) right(arg(2),wL) right(arg(3),vL); return |
sy: say left('',9) left(arg(1),nL) right(arg(2),wL) right(arg(3),vL); return |
||
syf: call sy arg(1), format(arg(2),, |
syf: call sy arg(1), $(format(arg(2),,d)), $(format(arg(3),,d)); return |
||
title: call sy center('item',nL),center("weight",wL),center('value',vL); return |
title: call sy center('item',nL), center("weight",wL), center('value',vL); return |
||
$:x=arg(1);if pos(.,x)>1 then x=left(strip(strip(x,'T',0),,.),length(x));return x |
|||
⚫ | |||
/*──────────────────────────────────SORTD subroutine───────────────────────────*/ |
|||
<pre style="height:50ex"> |
|||
sortD: do sort=2 to #; _n=n.sort; _w=w.sort; _v=v.sort /*descending. */ |
|||
do k=sort-1 by -1 to 1 while v.k/w.k<_v/_w /*order items.*/ |
|||
p=k+1; n.p=n.k; w.p=w.k; v.p=v.k /*shuffle 'em.*/ |
|||
end /*k*/ /*[↓] last one*/ |
|||
⚫ | |||
⚫ | |||
return /* ↑ ↑ ↑ algorithm is OK for smallish arrays.*/</lang> |
|||
⚫ | |||
<pre> |
|||
────────────────unsorted item list──────────────── |
────────────────unsorted item list──────────────── |
||
item weight value |
item weight value |
||
═══════════════ ═════════ ════════ |
|||
════════════ ════════ ═══════ |
|||
flitch 4 |
flitch 4 30 |
||
beef 3. |
beef 3.8 36 |
||
pork 5. |
pork 5.4 43 |
||
greaves 2. |
greaves 2.4 45 |
||
brawn 2. |
brawn 2.5 56 |
||
welt 3. |
welt 3.7 67 |
||
ham 3. |
ham 3.6 90 |
||
salami 3 |
salami 3 95 |
||
sausage 5. |
sausage 5.9 98 |
||
───────────burglar's knapsack contents──────────── |
───────────burglar's knapsack contents──────────── |
||
item weight value |
item weight value |
||
═══════════════ ═════════ ════════ |
|||
════════════ ════════ ═══════ |
|||
salami |
{all} salami 3 95 |
||
ham |
{all} ham 3.6 90 |
||
brawn |
{all} brawn 2.5 56 |
||
greaves |
{all} greaves 2.4 45 |
||
welt 3.5 63.378 |
|||
═══════════════ ═════════ ════════ |
|||
════════════ ════════ ═══════ |
|||
total weight 15.00 |
|||
total |
total weight─── 15 |
||
total value─── 349.378 |
|||
</pre> |
</pre> |
||