Jump to content

Subset sum problem: Difference between revisions

m
→‎{{header|REXX}}: made the compN subroutine faster. -- ~~~~
m (→‎{{header|REXX}}: optimized the combN subroutine a small bit. -- ~~~~)
m (→‎{{header|REXX}}: made the compN subroutine faster. -- ~~~~)
Line 543:
<br>This is a brute force solution.
<lang rexx>/*REXX pgm finds some non-null subsets of a weighted list whose sum=0. */
arg target stopstopAt . /*get arguments from command line*/
 
arg target stop . /*get arguments from command line*/
if target=='' then target=0 /*No TARGET given? Use default.*/
if stopstopAt=='' then stopstopAt=1 /*No max sols given? Use default.*/
 
pairszzz= 'alliance -624 archbishop -915 balm 397' ,
'bonnet 452 brute 870 centipede -658' ,
'cobol 362 covariate 590 departure 952' ,
'deploy 44 diophantine 645 efferent 54' ,
'elysee -326 eradicate 376 escritoire 856' ,
'exorcism -983 fiat 170 filmy -874' ,
'flatworm 503 gestapo 915 infra -847' ,
'isis -982 lindholm 999 markham 475' ,
'mincemeat -880 moresby 756 mycenae 183' ,
'plugging -266 smokescreen 423 speakeasy -745' ,
'vein 813'
 
@.=0; y=0; do N=1 until zzz=''; parse var zzz do@.N size=1#.N until pairs=''zzz
call tell right('['N']',30) parse var pairs right(@.@.sizeN,11) @right(#.size pairsN,5)
end call tello right(@.size,9) @.@.size/*N*/
solutions=0
end /*size*/; @.0=target
call tell; call tell 'There are' N "entries in the table."
do chunk=1 for size
 
call combN size,chunk
do chunk=1 for sizeN
call combN sizeN,chunk
end /*chunk*/
 
if @.solssolutions==0 then @.solssolutions='no'
call tellotell 'Found' @.solssolutions "subsets whose summed weights =" target
exit
/*─────────────────────────────────────telly subroutine─────────────────*/
/*─────────────────────────────────────tell subroutine──────────────────*/
telly: @.solssolutions=@.solssolutions+1; names=
 
do ig=1 for y; o=!.ig
names=names @.@.o
/* names=names @.@.o '{'@#.o"}" <─── weights in this REXX statement.*/
end /*ig*/
 
call tellotell '['y" names]" space(names)
if @.solssolutions>=stopstopAt &,
stopstopAt\==0 then do
call tellotell 'Stopped after finding' @.solssolutions "subsets."
exit
end
return
 
tellotell: say arg(1); call lineout 'OUTPUTSUBSET.'y,arg(1) /*write to file*/; return
/*─────────────────────────────────────combN subroutine─────────────────*/
combN: procedure expose @. #. solutions stopAt target; parse arg x,y; /*X items taken Y at a time!.*/=0
!.=0; base=x+1; bbase=base-y; ym=y-1 /*!.n are the combination digits*/
 
do in=1 for y; !.in=in; end /*ibuild 1st combination*/
 
do j=1; L=!.d; do d=2 for ym; L=L !.d; end /*d*/
_=!.1; s=@#._
do k=2 for ymy-1; _=!.k; s=s+@#._; end end /*sum the weights.*/
if s==@.0target then call telly /*element @.0 is the target sum.*/
!.y=!.y+1; if !.y==base then if .combUp(ym) then leave
end
 
Line 603 ⟶ 605:
 
.combUp: procedure expose !. y bbase; parse arg d; if d==0 then return 1
p=!.d; do u=d to y; !.u=p+1
if !.u>=bbase+u then return .combUp(u-1)
p=!.u
Cookies help us deliver our services. By using our services, you agree to our use of cookies.