Fast ranking/unranking of combinations (64bit)

南笙酒味 提交于 2019-12-06 15:38:51

I think you are already quite well on the way. Are you doing some poker related perhaps? (I just googled unranking algorithms when doing just that). Some considerations:

1) With small amount of items, binomials could be quicker to calculate manually than the memory accesses, but considering long long, this is highly unlikely in your case.

2) However, depending on compiler wits, you might save a memory access with calculating 2D index of the precalc table:

binCoef[(index<<6) + i]; // instead of binCoef[index][i]

3) Not sure how well the binCoef fits in L1 cache during calculations, but you might save half of the lookup space with identity C(n, k) == C(n, n-k) with a cost of one additional conditional. Maybe worth testing?

4) In unrank, I think the internal while-loop is the slowest part. There are two obvious optimizations: Either implement a binary search to locate p, OR...

5) IF you are dealing with small values of card, you might even consider full-blown lookup solution to unrank: there are C(52, 5) = 2.6 million poker hands, which is only a few MB of lookup.

6) Similarly, you might see if map<int, long long> rank could be used to replace the rank algorithm altogether. A binary tree is O(log N) for lookup, and hashmaps might have even better performance. Just precalc it:

map<long long, int> rank5;
for(int i=0; i<N; i++) rank5[unrank(i, 5)] = i; //ranks of 5 card hands

If you will need large values of card, then the lookup methods won't work, and I think you're pretty much stuck with the binary search optimization. Good luck!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!