Hi Devon : It sounds a bit like you're writing a hand evaluator for Omaha.
You might find this interesting: https://github.com/tangentforks/TwoPlusTwoHandEvaluator It's a program that generates a giant binary encoding of a state machine that tells you the best hand value for any string of 5 to 7 cards. It was a collaborative effort from a bunch of different people on the 2+2 (poker book publisher) forums. At least when I was looking at this a few years ago, this approach was pretty much the fastest hand evaluator out there. It was designed for Holdem, so it doesn't account for the Omaha rule that you need exactly two of your hole cards to be in the resulting hand, but you might be able to adapt the idea for Omaha. (Generate the file and then open it as a big mapped array in J) On Wed, Aug 11, 2021 at 6:13 AM R.E. Boss <[email protected]> wrote: > 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 > ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
