I tried another solution.
Given a 5-tuple I calculate which 4-tuples obey the constraints, that is, I
combine each 2-tuple from the 5-tuple with each 2 tuple from the 47-tuple,
which is the complement of the corresponding 5-tuple.
The advantage is that most of the calculations are done only once.
As an option one can ignore the 4-tuple, but save its index in c4_52, although
this come with a performance price.
c2_5=: 2 comb 5
c2_47=: 2 comb 47
c4_52=: 4 comb 52
c5_52=: 5 comb 52
$cmpl5=: c5_52 ([, -.~)"1"_ 1 i.52 NB. Complement added to each 5-tuple
2598960 52
$frtpl=:,/c2_5 ,"1"(1 _) 5+c2_47 NB. All 4-tuples, 2 from the 5-tuple
and 2 from the rest
10810 4
$ c4_52 i. frtpl {"1"_ 1 (1000) {. cmpl5 NB. Index in c4_52
1000 10810
ts 'frtpl {"1"_ 1 (1000) {. cmpl5' NB. Full 4-tuple
0.4641848 5.373975e8
0.4641848 * 270725%1000 NB. Estimate for the complete
calculation
125.66643
But
ts 'c4_52 i. frtpl {"1"_ 1 (1000) {. cmpl5' NB. Index in c4_52,
quite slower
2.3893563 6.7528483e8
ts 'frtpl {"1"_ 1 (100000) {. cmpl5' NB. It scales rather well, dependent on
the memory
66.299325 6.8720004e10
(7!:2) 'frtpl {"1"_ 1 (200000) {. cmpl5' NB. This is my max
before I ran out of memory
137439480576
(7!:2) 'c4_52 i. frtpl {"1"_ 1 (200000) {. cmpl5' NB. Index in c4_52,
with even more memory
171798694656
R.E. Boss
-----Original Message-----
From: Programming <[email protected]> On Behalf Of Devon
McCormick
Sent: dinsdag 10 augustus 2021 17:19
To: J-programming forum <[email protected]>
Subject: Re: [Jprogramming] All selected hand possibilities (long)
I'm reducing the 103,776 numbers to a single score for each of the 270,725
combinations. I'm still playing around with exactly how to compute the score
but am simply summing the numbers (indexes into *allHands*) for now.
I'll take a look at your solution later today.
Thanks!
Devon
On Tue, Aug 10, 2021 at 10:41 AM R.E. Boss <[email protected]> wrote:
> I don't know if I understand the question well enough, but do you
> really want the 28,094,757,600 = 103,776*270,725 solutions to your question?
> My solution generates 10,377,600 in 0,41 sec, so it would take 1109
> sec for the complete answer.
>
>
> Here are my thoughts, expressed in J.
> c4_4=: (,.|.)2 comb 4
> c3_48=: 3 comb 48
> c4_52=: 4 comb 52
>
> $/:~"1 ,/^:2 (2{."1 t),"1 "3 c3_48{"1"1 _ (t=.c4_4{"(_ 1)
> 100{.c4_52)-.~ "1 i.52
> 10377600 5
> It scales rather well
>
> ts'/:~"1 ,/^:2 (2{."1 t),"1 "3 c3_48{"1"1 _ (t=.c4_4{"(_ 1)
> 100{.c4_52)-.~ "1 i.52'
> 0.4097461 1.0737812e9
>
> 0.4097461 * 28094757600 % 10377600
> 1109.2851
>
> The idea is you make the 6 variants of (some) all 4 comb 52
> possibilities and remove these 4 numbers from i.52.
> Then you construct all 3 comb 48 from the remaining numbers.
> Then you prepend the two first numbers which were omitted and sort
> each row.
>
> I hope my answers are correct and this helps you further.
>
>
> R.E. Boss
>
> It scales rather well:
> ts'/:~"1 ,/^:2 (2{."1 t),"1 "3 c3_48{"1"1 _ (t=.c4_4{"(_ 1)
> 1000{.c4_52)-.~ "1 i.52'
> 4.3197289 8.5905962e9
>
>
>
> -----Original Message-----
> From: Programming <[email protected]> On Behalf
> Of Devon McCormick
> Sent: maandag 9 augustus 2021 22:15
> To: J-programming forum <[email protected]>
> Subject: Re: [Jprogramming] All selected hand possibilities (long)
>
> Thanks for the responses.
>
> Raul, it looks like the expressions you posted are missing the
> exclusions part of the problem which we can see if substitute the
> values from my original example to replace ({.HCs):
> $I.+./HCmask*/ .=+./"1(a.{~15 22 33 44)=/allHands
> 103776
>
> Pascal's version looks like it is giving a result like we would expect:
> $tst1=. allHands selhands (15 22{a.);33 44{a.
> 17296
> ]rcix=. (]{~[:5&?#) tst1
> 1515605 651644 2267264 157894 933164
> a. i. rcix{allHands
> 15 22 29 36 41
> 15 22 26 37 47
> 4 11 15 22 50
> 15 18 22 32 43
> 15 22 26 38 43
>
> I modified "selhands" to return the indexes into "allHands" rather
> than the explicit results as this is more easily turned into a score.
> selhands=: 4 : 0
> 'in ex' =. y
> I. ((# in) = (ex +/@:e."1 ]) -~ in +/@:e."1 ]) x
> )
>
> I like the elegance of the expression; however, the performance does
> not appear to be better:
> ixs=. i.100 NB. Do only 100 cases
> 6!:2 'tst100=. (<allHands) selhands&.><"1 (<"1
> ixs{,/inclIx{"1/HCs),.<"1 ixs{,/exclIx{"1/HCs'
> 49.7256
> #,/inclIx{"1/HCs NB. How many altogether?
> 1624350
> 49.7256*100%~1624350 NB. Scale time up by total #%100 ->
> estimate of total time
> 807718
> 0 60 60 #: 49.7256*100%~1624350 NB. Estimated total time in h m s
> 224 21 57.7836
>
> Thanks again to both of you for looking at this.
>
> The sizes of the arguments make it easy to max out the 64GB RAM I have
> on my desktop machine and I have discovered that I can run no more
> than about three processes in parallel on the version I proposed
> earlier but this may be enough for a one-time invocation.
>
> Cheers,
>
> Devon
>
> On Mon, Aug 9, 2021 at 11:14 AM 'Pascal Jasmin' via Programming <
> [email protected]> wrote:
>
> > is this 10x faster than your original? selhands uses arbitrary
> > length include/exclude list where all of include, and any of exclude
> > condition.
> >
> > c =. 5 comb 52
> >
> > selhands =: 4 : 0
> >
> > 'in ex' =. y
> >
> > (] #~ (# in) = (ex +/@:e."1 ]) -~ in +/@:e."1 ]) x
> >
> > )
> >
> > timex' c selhands 15 22 ; 33 44'
> >
> > 1.17982
> >
> >
> >
> >
> >
> > On Sunday, August 8, 2021, 04:42:30 p.m. EDT, Devon McCormick <
> > [email protected]> wrote:
> >
> >
> >
> >
> >
> > Hi,
> >
> > I'm stuck on getting decent performance for the following problem.
> > Say we have a list of all 5-card hands from a deck of 52 cards:
> > load '~addons/stats/base/combinatorial.ijs'
> > $allHands=. 5 comb 52
> > 2598960 5
> >
> > We also have a list of all 4-card combinations:
> > $HCs=. 4 comb 52
> > 270725 4
> >
> > I want to find all hands possible using any two cards from a given
> > row of *HCs *but excluding those with either of the other two cards
> > from the same row.
> >
> > For example, for this randomly-chosen row of *HCs*, which hands
> > include the first two but exclude the second two?
> > (]{~[:?#) HCs
> > 15 22 33 44
> > (#,+/) include=. 2=+/"1 allHands e."1 ] *15 22*
> > 2598960 19600
> > (#,+/) exclude=. 0=+/"1 allHands e."1 ] *33 44*
> > 2598960 480200
> >
> > So there are 17,296 hands we want:
> > +/include*.exclude
> > 17296
> >
> > Check five at random to verify that these look correct:
> > ]rcix=. (]{~[:5&?#) I. include*.exclude
> > 1002358 1165504 2176134 1960355 56685
> > rcix{allHands
> > 4 15 22 37 39
> > 5 15 22 34 45
> > 15 18 20 22 39
> > 12 15 22 27 39
> > 0 4 6 15 22
> >
> > These look good because all include (15,22) but exclude any of (33,44).
> >
> > However, this is only one possibility for this single row of *HCs*
> > but we have six variations for this row based on choosing all
> > possible pairs of indexes into the row of *HCs* to include,
> > |:inclIx=. 2 comb 4
> > 0 0 0 1 1 2
> > 1 2 3 2 3 3
> >
> > And six corresponding pairs to exclude (indexes into the row of *HCs*):
> > |:exclIx=. (i.4)-."1 ] 2 comb 4
> > 2 1 1 0 0 0
> > 3 3 2 3 2 1
> >
> > In the above example, we did the one of the six corresponding to
> > *inclIx *of
> > (0,1) and *exclIx *of (2,3). Is there a way to do all six sets for
> > each row of *HCs* compared to each row of *allHands*?
> >
> > We might start by reducing the sizes of our arrays by making them
> > character instead of integer:
> > allHands=. allHands{a. [ HCs=. HCs{a.
> >
> > However, we quickly see that we run out of memory for the expression
> > we would like to write:
> > include=. 2=+/"1 allHands e."1 / inclIx{"1 / HCs
> > |out of memory
> > | include=.2=+/"1 allHands e."1/inclIx{"1/HCs
> >
> > A little arithmetic shows us the extent of the problem:
> > (],*/) #&>(,/inclIx{"1/HCs);<allHands
> > 1624350 2598960 4221620676000
> > 10^.1624350*2598960
> > 12.6255
> >
> > So we have a 4-trillion-element intermediate result which is a bit much.
> >
> > Our immediate thought might be to do this in pieces by selecting
> > successive portions of the right-hand part (*HCs*) of this expression.
> > We would like to work on integral pieces for neatness, so we look at
> > the prime factors of the size of *HCs* and select the product of a
> > couple of them to be the "chunk size":
> > q:#HCs
> > 5 5 7 7 13 17
> > ixs=. (ctr*chsz)+i.chsz [ ctr=. 0 [ chsz=. */5 5
> >
> > [The expression for the next chunk would be
> > ixs=. (ctr*chsz)+i.chsz [ ctr=. >:ctr and so on.]
> >
> > Timing how long one piece takes and scoring the results by simply
> > adding up their indexes into *allHands*, we get this:
> > 6!:2 'sel=. (2=+/"1 allHands e."1 / inclIx{"1 / ixs{HCs) *. 0=+/"1
> > allHands e."1 / exclIx{"1 / ixs{HCs'
> > 11.5105
> > scores=. 0$~#HCs NB. Initialize scores vector
> > 6!:2 'theseScores=. +/&>I.&.><"1 |:+./"1 ] 0 2 1|:sel'
> > 0.687056
> > 6!:2 'scores=. (theseScores) ixs}scores'
> > 6.4e_6
> > +/11.5105 0.687056 6.4e_6 NB. Total time per chunk
> > 12.1976
> > 12.1976*(#ixs)%~#HCs NB. Total estimated time
> > 132088
> > 0 60 60#:12.1976*(#ixs)%~#HCs NB. Estimated time: h m s
> > 36 41 27.8104
> >
> > So we should be able to do it this way in about 36 hours. Can
> > someone think of a faster method to accomplish this? The memory
> > requirements seem modest enough that I should be able to run five to
> > ten processes simultaneously on this to reduce the overall time but
> > is there a way to speed up the basic selection?
> >
> > Thanks,
> >
> > Devon
> >
> >
> > --
> >
> > Devon McCormick, CFA
> >
> > Quantitative Consultant
> > --------------------------------------------------------------------
> > -- For information about J forums see
> > http://www.jsoftware.com/forums.htm
> > --------------------------------------------------------------------
> > -- For information about J forums see
> > http://www.jsoftware.com/forums.htm
> >
>
>
> --
>
> Devon McCormick, CFA
>
> Quantitative Consultant
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
--
Devon McCormick, CFA
Quantitative Consultant
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm