调试:用Python /随机随机播放卡片组

 奈何为人非_800 发布于 2023-02-09 15:36

我知道标题听起来很无聊,因为很多人已经问过这个话题了.我希望它可以帮助我深入了解随机模块的工作原理.问题是,我写的,我认为应该是相同的两个不同的功能,但我得到的结果是不相同的,我不明白为什么.

我希望最终得到一个"洗得很好的套牌".我只关心卡片是红色还是黑色,所以我的套牌非常简单.我称之为"1"红色和"0"黑色.

我的想法是通过附加1(红色),如果random.random()是> .5,或者除了0(黑色),然后在我达到26(甲板的一半)时自动附加1或0来构建套牌)一种颜色.但是出了点问题.deckmaker()无法正常工作,尽管deckmaker2()可以正常工作.谁能提供洞察力?

import random

def deckmaker():
    deck = []
    for i in range(52):
        if deck.count(0) == 26:
            deck.append(1)
        elif deck.count(1) == 26:
            deck.append(0)
        elif random.random() > .5:
            deck.append(0)
        else:
            deck.append(1)
    return deck

def deckmaker2():
    newdeck = []
    for i in range(26):
        newdeck.append(0)
    for i in range(26):
        newdeck.append(1)
    deck = []
    for i in range(52):
        x = random.randint(0,len(newdeck)-1)
        deck.append(newdeck.pop(x))
    return deck

注意:在写这个问题的时候,我发现了random.shuffle列表操作符,它与我的第二个函数做了同样的事情,所以当然让洗牌后的表变得容易.但我仍然想知道为什么我的原始代码不会做同样的事情.

编辑:抱歉对deckmaker()的确切问题含糊不清.问题是,我并不完全明白什么是错的.它与它产生的甲板上的事实有关,当你逐一"翻转"卡片时,有一些策略可以让你预测"下一张牌"是红色还是黑色不是使用random.shuffle创建的套牌

编辑2: [更多信息]我将解释我如何确定甲板制造商不起作用,以防重要.我在写这个程序模型拼图张贴在这里:http://www.thebigquestions.com/2013/12/17/tuesday-puzzle-4/

我的策略是记住最后几张牌,然后用这些信息决定何时决定拿下一张牌.我想也许在连续获得5张"黑色"牌之后,现在是预测"红色"的好时机.我是这样实现的:

mycards = []

for j in range(1000):
    mydeck = deckmaker(52)
    mem_length = 5
    mem = []
    for c in range(mem_length):
        mem.append(4)
    for i in range(len(mydeck)):
        if mem.count(0) == mem_length:
            mycards.append(mydeck[i])
            break
        elif i == len(mydeck)-1:
            mycards.append(mydeck[i])
            break
        else:
            mem.append(mydeck[i])
            mem.pop(0)


x = float(mycards.count(1))

print x/len(mycards)

结果超过一半的卡我正在(投入列表mycards)为"红",我通过后5张取卡实现结果的红色在一排卡被抽出.这没有任何意义,所以我寻找一种不同的方式来创建甲板并获得更正常的结果.但我仍然不知道我原来的套牌出了什么问题.

1 个回答
  • 一般来说,除非您能够严格证明其正常工作,否则您永远不要相信随机化方法可以正常工作.这通常很难.

    为了深入了解您的问题,让我们概括一下有问题的函数:

    import random
    
    def deckmaker(n):
        half = n // 2
        deck = []
        for i in range(n):
            if deck.count(0) == half:
                deck.append(1)
            elif deck.count(1) == half:
                deck.append(0)
            elif random.random() > .5:
                deck.append(0)
            else:
                deck.append(1)
        return deck
    

    这是一个小司机:

    from collections import Counter
    c = Counter()
    for i in range(1000):
        c[tuple(deckmaker(2))] += 1
    for t in sorted(c):
        print t, c[t]
    

    运行:

    (0, 1) 495
    (1, 0) 505
    

    所以这两种可能性大致相同.好!现在尝试一个4号甲板; 只需更改相关行:

    c[tuple(deckmaker(4))] += 1
    

    运行:

    (0, 0, 1, 1) 236
    (0, 1, 0, 1) 127
    (0, 1, 1, 0) 133
    (1, 0, 0, 1) 135
    (1, 0, 1, 0) 130
    (1, 1, 0, 0) 239
    

    哎呀!如果你愿意的话,你可以进行正式的卡方检验,但通过检查可以看出两个排列(第一个和最后一个)的可能性是其他四个的两倍.所以输出甚至没有接近可以说是随机的.

    这是为什么?考虑一下;-)

    暗示

    对于一个大小的牌组2*M,第一个M条目全部为0 的几率是多少?有两个答案:

      如果所有M0和M1的排列可能相等,则机会为1 in (2*M)-choose-M(选择M零位置的方式的数量).

      在函数构造牌组的方式中,机会为1英寸2**M(0和1在每个第一个M位置中同样可能).

    一般来说,(2*M)-choose-M它比非常大2**M,所以函数构造一个以全部零开始的牌组远比"它应该".对于一副52张牌(M == 26):

    >>> from math import factorial as f
    >>> one = f(52) // f(26)**2
    >>> two = 2**26
    >>> float(one) / two
    7389761.998476148
    

    因此,"以26个零开始"的可能性超过应有的700多万倍.酷:-)

    "一次一个"地做

    那么有可能一次正确地选择0或1吗?对!你只需要使用正确的概率:当nzero剩余的零被挑选时,nremaining剩下的总"卡"将被挑选,选择零概率nzero / nremaining:

    def deckmaker(n=52):
        deck = [None] * n
        nremaining = float(n)
        nzero = nremaining / 2.0
        for i in range(n):
            if random.random() < nzero / nremaining:
                deck[i] = 0
                nzero -= 1.0
            else:
                deck[i] = 1
            nremaining -= 1.0
        return deck
    

    请注意,没有必要计算.当nzero变为0.0时,if测试永远不会成功(random() < 0.0不可能发生); 一旦我们选择了n/2一个,那nzero == nremaining将是真的,if测试将永远成功(random() < 1.0总是如此).它真可爱 ;-)

    2023-02-09 15:38 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有