V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
nary
V2EX  ›  问与答

如何通过掷六面骰子,产生 1-7 的随机数?

  •  2
     
  •   nary · 2015-03-03 22:42:25 +08:00 · 8288 次点击
    这是一个创建于 3554 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,假设骰子是均匀的,不限掷多少次。

    33 条回复    2015-03-05 01:25:07 +08:00
    wdhwg001
        1
    wdhwg001  
       2015-03-03 23:00:10 +08:00 via iPhone
    掷两次,出现例外结果重掷。
    NeoAtlantis
        2
    NeoAtlantis  
       2015-03-03 23:02:23 +08:00
    七是怎么扔出来的?
    imydou
        3
    imydou  
       2015-03-03 23:02:56 +08:00
    六面骰子
    1-7 的随机数
    总感觉哪里不对。。。
    binux
        4
    binux  
       2015-03-03 23:05:31 +08:00   ❤️ 3
    所有通过 n 获得 m 都是映射问题。
    每次掷骰子都是获得一个 n 进制位,组合起来就是一个 n 进制数。
    将这个 n 进制数,均匀映射到 m 个位上就好了。

    即将 n 进制数转换为 m 进制数的问题。
    xuc
        5
    xuc  
       2015-03-03 23:06:28 +08:00
    丢7次肯定是可以的
    0x1e240
        6
    0x1e240  
       2015-03-03 23:09:22 +08:00 via Android
    扔7次,7次总和除6取整。
    别打我>_<
    NeoAtlantis
        7
    NeoAtlantis  
       2015-03-03 23:10:52 +08:00
    @binux 我以前一般是产生一个足够大的数,比如一个uint8, 然后算它mod 7的余数(再加一)。
    ysmood
        8
    ysmood  
       2015-03-03 23:12:28 +08:00
    这题改下,求最少需要扔多少次,能达到均匀随机。
    wy315700
        9
    wy315700  
       2015-03-03 23:14:10 +08:00
    @0x1e240 掷骰子的总和不是一个均匀分布,
    geeklian
        10
    geeklian  
       2015-03-03 23:15:38 +08:00
    无解吧=.=

    扔的次数多点,可以均匀分布,但(6^n)/7不能得到整数吧。
    efi
        11
    efi  
       2015-03-03 23:17:50 +08:00
    1 1 1 1 1 ...
    这也是一个1-7随机数生成器
    0x1e240
        12
    0x1e240  
       2015-03-03 23:20:34 +08:00 via Android
    @wy315700 说的在理。1楼的思想很好,先扔一次,确定一个数a(1~6),然后在扔一次得b(1~6),如果b和a相同,则随机数取7,否则随机数取a(1~6)。
    0x1e240
        13
    0x1e240  
       2015-03-03 23:22:21 +08:00 via Android
    @0x1e240 还是不对,算了
    Daniel65536
        14
    Daniel65536  
       2015-03-03 23:25:58 +08:00 via iPhone
    两次
    第一次奇数则取第二次结果
    第一次偶数则取第二次结果加6

    则得到1-12均匀分布
    最后,超过7则从头开始。
    Vinty
        15
    Vinty  
       2015-03-03 23:30:25 +08:00
    @0x1e240 一楼的意思是两次有36中等概率可能,取35种对7个数字映射,出现剩余的那一种就重来
    wy315700
        16
    wy315700  
       2015-03-03 23:30:27 +08:00
    @0x1e240 四楼的方法是正解
    arathos
        17
    arathos  
       2015-03-03 23:35:25 +08:00
    这应该是有答案的。。。
    ysmood
        18
    ysmood  
       2015-03-03 23:41:14 +08:00
    我给个可能不是最优,但易于理解的解吧:

    1、记 N 初始值为 0
    2、扔骰子,如果是奇数 N++
    3、重复步骤 2,7 次

    总共操作 7 次,得到的 N 值就是 [1, 7] 均匀分布的。
    0x1e240
        19
    0x1e240  
       2015-03-03 23:41:54 +08:00 via Android
    @Vinty 理解了
    @Daniel65536 这个方法也很不错,不过要丢弃5/12,1楼的要丢弃1/36,这么说来1楼的效率要高吗了? @Vinty
    Daniel65536
        20
    Daniel65536  
       2015-03-03 23:46:19 +08:00 via iPhone
    @ysmood 错了
    抛硬币7次,出现3个正面的概率远大于出现1个。
    0x1e240
        21
    0x1e240  
       2015-03-03 23:50:05 +08:00 via Android
    @ysmood 也是,7次总共128可能,要得到7就是7次都是1,只有一种,得7概率1/128
    Daniel65536
        22
    Daniel65536  
       2015-03-03 23:53:21 +08:00 via iPhone
    @0x1e240 对的
    我说的比较直白,一楼是经过充分优化的版本。

    这类题目的解法:先获得一个均匀分布的大骰子,再抛弃越界的结果即可。

    至于优化总骰子次数,就是后续考虑的问题了。
    binux
        23
    binux  
       2015-03-04 00:00:51 +08:00   ❤️ 1
    为了看不懂 n 进制 转 m 进制的,以 6 转 7 为例子。

    首先掷骰子 2 次,得 a b 两个 6 进制数,将它转换为 7 进制,即 s = a * 6 + b = a' * 7 + b'
    当 s < 6^2 - 7 时,b' 的 7 进制各位是等概率的。
    (因为 6 进制转 7 进制是单射,当 s < 6^2 - 7 时,7 的 整数倍范围上是满射)
    当 s >= 6^2 - 7 时,再抛一次,得 a b c,即 s = a * 6^2 + b * 6 + c = a' * 7^2 + b' * 7 + c'
    当 s < 6^3 - 7 时,c' 是等概率的。
    以此类推

    而抛的次数越多,s >= 6^n - 7 的概率越低,6^n - 7 就是所谓的越界。
    ysmood
        24
    ysmood  
       2015-03-04 00:02:49 +08:00
    @Daniel65536 嗯,确实,没仔细想,感觉高中天天犯这种错误。
    binux
        25
    binux  
       2015-03-04 00:06:03 +08:00
    @binux 不对。。边界应该是 6 ** n // 7 * 7
    binux
        26
    binux  
       2015-03-04 00:13:29 +08:00
    @binux 唉,解释还是太复杂了,就是抛 n 次,当成 6 进制取 7 余数就行了。。没法完整凑够 7 的那个就重抛一次。
    batman2010
        27
    batman2010  
       2015-03-04 00:16:01 +08:00
    最简单的,1-3视做0,4-6视做1,扔3次,得到000~111(0~7)八个数,如果是000则舍去,重扔。
    ysmood
        28
    ysmood  
       2015-03-04 00:17:25 +08:00
    其实我好奇的是能否在既定的次数内完成这个需求,按现在的解法,运气不好可能要重投无数次。
    crab
        29
    crab  
       2015-03-04 00:53:24 +08:00
    0x1e240
        30
    0x1e240  
       2015-03-04 01:01:31 +08:00 via Android
    0:任意指定一个数a(1~6),这个不是随机数
    1:扔骰子得数b(1~6),如果b不等于a,则随机数为b。若b等于a,则随机数为b和7,此时本次产生两个随机数
    2:再扔得数c(1~6),如果c不等于a,则随机数为c。若c等于a,则随机数为c和7
    ………如此循环……
    line
        31
    line  
       2015-03-04 10:06:34 +08:00
    就是个进制转换问题
    6进制序列转成7进制序列
    zhttty
        32
    zhttty  
       2015-03-04 12:49:51 +08:00 via Android
    最小公倍数问题。用7个骰子,一起扔结果和除以7取余数~
    yangzh
        33
    yangzh  
       2015-03-05 01:25:07 +08:00 via iPhone
    骰子抛连续两次,有36种组合,记为A1到A36;如果结果是A1到A5,记为生成数字1,如果结果是A6到A10,记为生成数字2,…如果结果是A31到A35,记为生成数字7,如果结果是A36,则此次不生成数字,重新抛两次骰子尝试生成数字。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3263 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:01 · PVG 21:01 · LAX 05:01 · JFK 08:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.