Subset sum problem: Difference between revisions
Content added Content deleted
(→version 1: optimized part of the combN subroutine for faster execution. -- ~~~~) |
(→version 2: optimized the previous version, it's faster by a facter of four or so. -- ~~~~) |
||
Line 813: | Line 813: | ||
===version 2=== |
===version 2=== |
||
This version requires the data to be in ascending order (by weight). |
This version requires the data to be in ascending order (by weight). |
||
Code could've been included to sort the table, but the extra code would've made the |
<br>Code could've been included to sort the table, but the extra code would've made the |
||
program more bulkier, so the list was just sorted externally. |
program more bulkier, so the list was just sorted externally. |
||
It's |
<br>It's quite a bit faster because it takes advantage of short-circuiting the summing process, |
||
<br>and is an order of magnitude faster than the brute-force method (version 1). |
|||
<lang rexx>/*REXX pgm finds some non-null subsets of a weighted list whose sum=0. |
<lang rexx>/*REXX pgm finds some non-null subsets of a weighted list whose sum = 0.*/ |
||
arg target stopAt . /*get arguments from command line*/ |
arg target stopAt . /*get arguments from command line*/ |
||
if target=='' then target=0 /*No TARGET given? Use default.*/ |
if target=='' then target=0 /*No TARGET given? Use default.*/ |
||
Line 855: | Line 855: | ||
@.=0; y=0; do N=1 until zzz=''; parse var zzz @.N #.N zzz |
@.=0; y=0; do N=1 until zzz=''; parse var zzz @.N #.N zzz |
||
call |
call tello right('['N']',30) right(@.N,11) right(#.N,5) |
||
end /*N*/ |
end /*N*/ |
||
solutions=0 |
solutions=0 |
||
call |
call tello 'There are' N "entries in the table." |
||
do chunk=1 for N |
do chunk=1 for N |
||
call combN N,chunk |
call combN N,chunk |
||
end /*chunk*/ |
end /*chunk*/ |
||
if solutions==0 then solutions='no' |
if solutions==0 then solutions='no' |
||
call |
call tello 'Found' solutions "subsets whose summed weights =" target |
||
exit |
exit |
||
/*─────────────────────────────────────telly subroutine─────────────────*/ |
/*─────────────────────────────────────telly subroutine─────────────────*/ |
||
Line 875: | Line 875: | ||
end /*g*/ |
end /*g*/ |
||
call |
call tello '['y" names]" space(names) |
||
if solutions>=stopAt &, |
if solutions>=stopAt &, |
||
stopAt\==0 then do |
stopAt\==0 then do |
||
call |
call tello 'Stopped after finding' solutions "subsets." |
||
exit |
exit |
||
end |
end |
||
return |
return |
||
tello: say arg(1); call lineout 'SUBSET.'y,arg(1) /*write to file*/; return |
|||
/*─────────────────────────────────────combN subroutine─────────────────*/ |
/*─────────────────────────────────────combN subroutine─────────────────*/ |
||
combN: procedure expose @. #. solutions stopAt target; parse arg x,y; !.=0 |
combN: procedure expose @. #. solutions stopAt target; parse arg x,y; !.=0 |
||
base=x+1; bbase=base-y; ym=y-1 /*!.n are the combination digits*/ |
base=x+1; bbase=base-y; ym=y-1 /*!.n are the combination digits*/ |
||
do n=1 for y; |
do n=1 for y; !.n=n; end /*build 1st combination*/ |
||
do j=1 |
|||
do j=1; L=!.d; do d=2 for ym; L=L !.d; end /*d*/ |
|||
_=!.1; s=#._ |
_=!.1; s=#._; if s>target then leave |
||
⚫ | |||
⚫ | |||
⚫ | |||
end |
|||
⚫ | |||
if s>target then do; if .combUp(k-1) then return; iterate j; end |
|||
end /*k*/ |
|||
⚫ | |||
⚫ | |||
end /*j*/ |
|||
return |
return |
||