确定甲板洗牌的程度

Sig*_*dur 4 c# random entropy

我正在做一个小型扑克计划,我想确定一个牌组的洗牌程度.我有一张带有52张牌的List然后我运行我的洗牌算法,我希望能够确定牌组在某种程度上的洗牌程度.有人知道怎么做吗?谢谢

编辑:哇.很多回复.一切都很好但不完全是我想要的.这是我没有进一步指出我的问题的错.但我认为Saran最接近我真正想要的.我来说明一下.

我不想马上进行"完美"的洗牌.我已经读完了,我实施了Fisher-Yates.那个人很擅长"完美"的洗牌.我想要做的是模拟一个真实世界的情况,朋友们正在玩德州扑克,经销商拿着套牌并使用混合其他洗牌的浅滩洗牌来洗牌.最后,我想要的是一种衡量现实世界洗牌之间差异的方法.

一个例子.假设牌组总是新鲜的(对于所有四件套装来说,王牌适合王牌,然后是王牌王牌.)乔拿着甲板,做了2次浅口洗牌,其中一次切入.彼得做了5次剥离洗牌.我想找到一种方法,看看哪一个改组"更好".

我越想它越多,我认为它很难确定.

再次感谢.

编辑23.10.2013

这是我想出的方法,将Sarans的想法与我的想法结合起来:

 public int checkShuffle(List<Card> cardDeckToCheck,int[] previousOrder)
    {
        // Higher is worse? Sure.
        int score = 0;

        for (int i = 0; i < cardDeckToCheck.Count; i++)
        {
            Card cardToCheck = cardDeckToCheck[i];
            Card cardToLeft = null;
            Card cardToRight = null;

            // Should cost more since the card has not moved at all.
            // For this I need an array that shows me the arangement of the deck before shuffling.
            if(cardToCheck.index == previousOrder[i])
            {
                score += 3;
            }

            if (i == 0)
            {
                Console.WriteLine("i == 1");
                cardToRight = cardDeckToCheck[i+1];
                // if the card we are checking is one lower or one higher than the card to the right
                if(Math.Abs(cardToCheck.index - cardToRight.index) == 1)
                {
                    score++;
                }
                continue;
            }

            else if (i == cardDeckToCheck.Count-1)
            {
                Console.WriteLine("i == carddecktocheck.count-1");
                cardToLeft = cardDeckToCheck[i - 1];
                // if the card we are checking is one lower or one higher than 
                if (Math.Abs(cardToCheck.index - cardToLeft.index) == 1)
                {
                    score++;
                }
                continue;
            }

            else
            {
                cardToLeft = cardDeckToCheck[i - 1];
                cardToRight = cardDeckToCheck[i + 1];
                // if the card we are checking is one lower or one higher than 
                if (Math.Abs(cardToCheck.index - cardToLeft.index) == 1)
                {
                    score++;
                }
                if (Math.Abs(cardToCheck.index - cardToRight.index) == 1)
                {
                    score++;
                }
                continue;
            }

        }
        return score;
    }
Run Code Online (Sandbox Code Playgroud)

我首先记录甲板看起来像是一个int数组然后我洗牌,然后我用洗牌的甲板和甲板的先前顺序运行这个方法.像这样:

int[] previousOrder = getCurrentOrder(deck.getDeck());
deck.setDeck(riffleShuffle2(3));
textBoxShuffleness.Text = "" + checkShuffle(deck.getDeck(), previousOrder);
displayDeck(deck);
Run Code Online (Sandbox Code Playgroud)

当我从一个未洗过的甲板开始并且运行riffle shuffle方法5次时我得到70,33,28,5,10.当我从一个未洗过的甲板开始并且运行Durstenfeld shuffle方法5次时我得到5,0,7,11,7.

这些结果非常符合我的预期.

如果有人发现这种方法有问题,那么如果你愿意,我将不胜感激:)谢谢

abe*_*nky 7

为了有任何希望,你需要一遍又一遍地运行你的洗牌程序,总是从同一个初始套牌开始,并比较结果.

如果它是完全公平的,那么你预计任何给定的牌在洗牌之后有一个五分之一的机会在任何一个位置结束.

如果有偏见,你会发现它在某些地方比其他地方更频繁地结束.

当然,预计会有一些与理想的5-in-52不同的变化.
可接受的变化量可通过统计数据和各种置信区间来预测.(95%?97%?)

即使你有一个完美的发行版,这并不意味着你的改组是随机的.
(想象一下一个洗牌算法,只需在每次连续洗牌时用一张牌旋转牌组......它会有完美的五分之一结果,但不会随意)

要寻找的另一个方面是卡之间的相关性.
例如,黑桃王牌和黑桃王的最终位置应完全不相关.
一个糟糕的改组算法可以将这两张卡一起移动,从而产生高度相关性.检查每张卡与每张其他卡的相关性在计算上是昂贵的,但应该是一种简单的算法.

我认为最终的结果是你无法证明你的算法是公平/良好的洗牌.您只能设置各种测试以查找"不良"混洗(非均匀分布或卡位置的高相关性).如果您通过了所有测试以进行糟糕的改组,那么这并不意味着您的算法没有以测试未覆盖的其他方式存在缺陷.
但它确实会让你增强信心.

可能有更好的方法来测试随机性,但在计算上是不可能的.

正如编码恐怖博客文章指出的那样,更好的方法可能是针对非常小的卡片组运行算法(文章使用3张牌),并仔细评估这些结果.只有3张卡,跟踪所有路径应该更容易,并查看所有结果是否同样可能.