Here's the reasonably constructive approach.

Much better than my earlier effort at a constructive approach, 
but it still generates too much redundancy as x approaches y 
for larger y.  Limited time to do email,  so in a bit of a rush...

NB. Generate non-zero partitions of y size x
   3 mpart 5  NB. eg 
2 2 1
3 1 1

mpart =: 3 : 0
:
m =. x [ n =. y
NB. smoutput m;n
if. m = 1 do. ,: n  return. end.
max =. n + 1 - m
min =. >.n%m
l   =. ,.min ([+i.@>:@-~ ) max
for_j. >:}:}. i.m do.
  rem =. n - +/"1 l
  min =. >. rem%(m + 1 - j) 
  max =. min >. ({:"1 l) <. rem - m - j
  nl  =. 0-.~, min ([+i.@>:@-~ )"0 max
  l   =. nl,.~ l#~1 + max - min
end.
l,. n - +/"1 l
)

NB. CONSTruct boxed outputs for a given arrangement of partition sizes
NB. eg const 2 4 3 as a contribution to 3 par 9

require'stats'    NB. for comb

const =: 3 : 0
p     =. y     NB. eg 2 4 3
n     =. +/p
r     =. comb/({.,+/)p   NB. initialise with first group-size
last  =. done  =. {.p
in    =. i.n
s     =. 0
for_pi. }:}.p do.        NB. add on intermediate groups - last is 
implicit
  ri    =. comb/ pi,n - done
  ini   =. r -. "1~ in   NB. commute is silly,  no time to change it! 
  r     =. r#~#ri
  add   =. ,/ ri&{"1 ini
  if. last = pi do.   NB. only need to check for redundancy 
                      NB. when repeating partial group size
     ok =. (s{"1 r) < {."1 add
     r  =. ok#r
     add=. ok#add
  end.
  r     =. r,. add
  done  =. done + pi
  s     =. s    + last
  last  =. pi
end.
NB. append last group-size sub-array
if. last = {:p do.    NB. check redundancy if same group-size as 
previous
  ok =. (s{"1 r) < {."1 add =. r -."1 ~ in
  r  =. (ok#r),. ok#add
else.
  r =. r,.  r -."1 ~ in
end.
(p#i.#p) </."1 r
)

NB. constructive verb for (eg) 3 par 9
NB. Fairly efficient cf Raul's,  but still suffers from 
NB. big-O problems

mdconst =: 3 : 0
mdconst/y
:
NB. special cases, pace Erland!
if. x >: y    do. r =. <"0 i.(x=y){0 0,:1,x
elseif. x = 1 do. r =. 1 1$<i.y 
elseif. 1     do.   
   p =. x mpart y
   r =. const {.p
   for_pi. }.p  do.
      r =. r, const pi
   end.
end. 
)

   |: mdconst 3 4
+---+---+---+---+---+---+
|0 1|0 2|0 3|1 2|1 3|2 3|
+---+---+---+---+---+---+
|2  |1  |1  |0  |0  |0  |
+---+---+---+---+---+---+
|3  |3  |2  |3  |2  |1  |
+---+---+---+---+---+---+

   ts'mdconst 3 9'
0.0177876 1.37434e6
   ts'parRDM/ 3 9'
0.0179469 995968

   ts'mdconst 5 9'
0.0728827 5.22534e6
   ts'parRDM/ 5 9'
0.0815166 4.38822e6

   ts'mdconst 8 9'
0.00567922 543360
   ts'parRDM/ 8 9'
0.00107666 61952

Must go now! 

Mike


>----Original Message----
>From: [email protected]
>Date: 30/10/2017 14:17 
>To: <[email protected]>
>Subj: Re: [Jprogramming] Partitions
>
>Yes - even with your improvement,  it works by filtering an ever 
larger array.  I’ll post separately a reasonably “constructive” 
approach,  which is closer to Raul’s method in performance,  I think.
>Mike
>
>Please reply to [email protected].      
>Sent from my iPad
>
>> On 29 Oct 2017, at 19:37, Erling Hellenäs <[email protected]> 
wrote:
>> 
>> Hi all!
>> 
>> I took a sample. We must remember that when we have 10 buckets and 
10 elements, we get only one combination.
>> However, it seems Rauls algorithm is better for high y. parELMDE 
still generates too many unused combinations.
>> 
>>    x=:5
>>    y=:10
>>    ts'x parR y'
>> 0.211737 2.7077e7
>>    ts'x parELMDE y'
>> 0.417241 1.1325e8
>>    ts'x parMD y'
>> 2.30795 1.71128e9
>> 
>> Cheers,
>> 
>> Erling Hellenäs
>> 
>>> On 2017-10-29 17:53, Raul Miller wrote:
>>> Ah, excellent.
>>> 
>>> require'stats'
>>> 
>>> parRDM=:4 :0
>>>   x (1+y-x) P y
>>> )
>>> 
>>> combine=:1 :0
>>> :
>>>   q=.(#;{.x)=#@>y
>>>   if.1 e.,q do.
>>>     b=. ,(<./@>x)<:/ q <./@;@#"1 y
>>>     b # ,/  x ([,] ({L:0 ,) (i.m)-.S:0 [)"0 1/  y
>>>   else.
>>>     ,/ x ([,] ({L:0 ,) (i.m)-.S:0 [)"0 1/  y
>>>   end.
>>> )
>>> 
>>> 
>>> P=:1 :0
>>> :
>>>   NB. x: number of partitions
>>>   NB. m: maximum allowed partition size
>>>   NB. y: number of items to distribute across partitions
>>>   if. y>x*m do.return. end.
>>>   if. (0=m)+.y<x do.return.end.
>>>   if.1=x do. ,.<"1 m comb y return.end.
>>>   r=.i.0 0
>>>   for_n. 1+i.m do.
>>>     t=.(x-1) (m<.(y-n)<.n) P y-n
>>>     if. 0=#t do. continue. end.
>>>     c=.<"1 n comb y
>>>     r=.r, c y combine t
>>>   end.r
>>> )
>>> 
>>> parELMDE=: 4 : 0
>>>   a =. ~. i.~"1 iy #: i. */ iy =. (1+i.x),(y-x)$x
>>>   a =. a#~ x = #@~."1 a
>>>   sort a </."1 i. y
>>> )
>>> 
>>> timerat=:4 :0"0
>>>   try.
>>>     elmde=.6!:2 'vE=. x parELMDE y'
>>>     rdm=.6!:2 'vR=. x par y'
>>>     r=. rdm%elmde
>>>   catch.
>>>     vR=.vE=.0
>>>     r=. _
>>>   end.
>>>   assert. vR -:&(/:~)&:(/:~"1)&:(/:~&.>) vE
>>>   r
>>> )
>>> 
>>> For the simple (and fast) cases, parELMDE tends to be significantly
>>> faster than my parRDM. Low complexity pays off:
>>> 
>>>    3 timerat 4
>>> 2.59375
>>> 
>>> However, for other cases, it tends to be significantly slower. 
Here,
>>> low complexity does not pay off enough to amortize big-O issues:
>>> 
>>>    6 timerat 8
>>> 0.067733
>>> 
>>> Or, a slightly better overview (better viewed with fixed width font 
or
>>> run it yourself):
>>> 
>>>    9!:11]3 NB. reduce display precision, for email line widths
>>> 
>>>    (1+i.10) timerat table 1+i.10
>>> 
┌───────┬─────────────────────────────────────────────────────────────┐
>>> │timerat│   1    2    3    4    5     6      7      8       9       
10│
>>> 
├───────┼─────────────────────────────────────────────────────────────┤
>>> │ 1     │1.03 1.38 1.67 1.82  2.3   2.5    2.9    3.1     3.4      
3.7│
>>> │ 2     │   _ 5.43 3.28 5.13  3.6  3.95   2.36   2.37    1.52     
1.58│
>>> │ 3     │   _    _ 5.46 3.24 3.24  2.27   1.46   1.43    0.83    
0.763│
>>> │ 4     │   _    _    _ 2.94 1.74  1.44  0.961  0.668   0.599    
0.621│
>>> │ 5     │   _    _    _    _ 2.08 0.514  0.374  0.325   0.315    
0.311│
>>> │ 6     │   _    _    _    _    _ 0.566 0.0929 0.0876  0.0951    
0.124│
>>> │ 7     │   _    _    _    _    _     _ 0.0936 0.0156  0.0177   
0.0323│
>>> │ 8     │   _    _    _    _    _     _      _ 0.0117 0.00192  
0.00209│
>>> │ 9     │   _    _    _    _    _     _      _      _ 0.00256 
0.000176│
>>> │10     │   _    _    _    _    _     _      _      _       _  
0.00019│
>>> 
└───────┴─────────────────────────────────────────────────────────────┘
>>> 
>>> Thanks,
>>> 
>> 
>> 
----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm

>
>----------------------------------------------------------------------
>For information about J forums see http://www.jsoftware.com/forums.htm



----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to