我正在做一个小型扑克计划,我想确定一个牌组的洗牌程度。 我有一张带有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;
}
我首先记录甲板看起来像是一个int数组,然后我洗牌,然后我用洗牌的甲板和甲板的先前顺序运行这个方法。 像这样:
int[] previousOrder = getCurrentOrder(deck.getDeck());
deck.setDeck(riffleShuffle2(3));
textBoxShuffleness.Text = "" + checkShuffle(deck.getDeck(), previousOrder);
displayDeck(deck);
当我从一个未洗过的甲板开始并且运行riffle shuffle方法5次时我得到70,33,28,5,10。 当我从一个未洗过的甲板开始并运行Durstenfeld shuffle方法5次我得到 5,0,7,11,7。
这些结果非常符合我的期望。
如果有人发现此方法有问题,那么如果你发表评论,我将不胜感激:) 感谢
答案 0 :(得分:7)
为了有任何希望,你需要一遍又一遍地运行你的洗牌程序,总是从同一个初始套牌开始,然后比较结果。
如果完全公平的话,你预计任何给定的牌在洗牌后有机会在任何位置结束。[/ p>
如果有偏见,你会发现它在某些地方比其他地方更频繁地结束。
当然,预计会有一些与理想的5-in-52有所不同 可接受的变化量可通过统计数据和各种置信区间来预测。 (95%?97%?)
即使你有完美的发行,但这并不意味着你的洗牌是随机的 (想象一下,一个随机算法,只需在每次连续的随机播放中将卡片旋转一张卡片......它将具有完美的1-in-52结果,但不会完全随机) < / p>
要寻找的另一个方面是卡之间的相关性
例如,黑桃王牌和黑桃王的最终位置应完全不相关。
一个糟糕的改组算法可以将这两张卡一起移动,从而产生高度相关性。
检查每张卡与每张其他卡的相关性在计算上是昂贵的,但应该是一个简单的算法。
我认为最终的结果是你不能证明你的算法是公平/好的洗牌。
您只能设置各种测试以查找“不良”混洗(非均匀分布或卡位置的高相关性)。如果你通过了所有的糟糕洗牌测试,这并不意味着你的算法没有以测试所覆盖的其他方式存在缺陷。
但它确实会让你增强信心。
可能有更好的方法来测试随机性,但它是computationally impossible。
正如Coding Horror Blog条目所指出的,更好的方法可能是针对非常小的卡片组运行您的算法(文章使用3张牌),并仔细评估这些结果。只有3张牌,跟踪所有路径应该更容易,并且看看所有结果是否同样可能。
答案 1 :(得分:3)
这里有一些信息:Randomness tests。值得注意的是,如果你的洗牌“通过”所有这些测试,那只是表明洗牌可能是真正随机的。但是,如果您使用的是伪随机生成器,则您已经知道它不是。
答案 2 :(得分:1)
你无法衡量单层牌组的洗牌程度,因为每张牌组合都是同样可能的。
但是,您可以衡量您的改组算法的真实程度。杰夫阿特伍德有一些关于这个特殊问题的帖子:
http://www.codinghorror.com/blog/2007/12/shuffling.html
http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html
答案 3 :(得分:1)
这样做的一个想法是获取列表并用整数值填充它(每个卡1个int)。制作另一组带有int值的代码并将其转换为卡片值,这样您就可以保留哪些卡属于哪些卡片。随机化整数列表,然后循环遍历列表中的每一行,并标记一组范围内的数量或前一数字中1-2个整数的一个范围。然后,然后为穷人,好人,好人等设置一组百分比等等......
这可能不是最佳解决方案,但您可以了解列表的分布情况。