haskell - Random Monad 在replicatM 迭代之间是独立的吗?

标签 haskell random random-sample

我正在纸牌游戏中进行一些假设检验。

为此,我实现了游戏和玩游戏的 AI。对于测试,我必须对我的牌组中所有可能的牌排列空间进行抽样(牌组有 24 张牌,所以有 24 种!牌组的不同初始状态)。然而,采样应该是独立的,因为(a)在洗牌后,每个初始排列应该有概率(1/24!)和(b)如果 i 和 i' 是两次洗牌后的两个初始排列,则排列 i 和排列 i' 是初始排列的概率应该是 (1/24!)x(1/24!)。[注 1]

所以,如果 d 是我的牌组,而 shuffleDeck 是我洗牌的功能。我相信随机单子(monad)是以概率((suffleDeck d)== i)= 1/24的方式构建的!

但我的问题是:这个函数在与函数 replicateM 交互时是独立的吗?换句话说,以下是真的吗?

P((replicateM 2 (shuffleDeck d) )== [i,i']) = P((suffleDeck d) == i ) * P((suffleDeck d) == i' )

其中 P(x = X) 是 x 为 X 的概率。

我用于洗牌的代码如下:

import System.Random

shuffleDeck d = do
         seed <- newStdGen 
         return $ shuffle seed d

shuffle :: StdGen -> [Card] -> [Card]
shuffle g [] = [] 
shuffle g d  = c : shuffle g' d'
        where (c, g') = oneRandomCard g d 
              d' = d\\[c]

oneRandomCard :: StdGen -> [Card] -> (Card, StdGen)
oneRandomCard g d =((last $ take n d), g1 )
              where (n,g1) = randomR (1, length d) g

我看到乍一看这个问题似乎微不足道,但考虑到 haskell 处理随机性的方式,我认为值得提出一个问题。

[1]注意:分布不需要像我说的那样均匀。它必须是一个已知的分布,这样我才能掌握测试的力量。但在这种情况下,它应该是统一的。

[2]注意:如评论中所述,该函数仅使用 System.Random 而不是 Control.Monad.Random 起作用。

最佳答案

由于您的示例仅使用 replicateMIO ,这个问题实际上有点不正确。 replicateM 2 (shuffleDeck d)有类型 IO [[Card]] .它永远不会等于 [[Card]] 类型的东西.但是,虽然在使用 Haskell 时该技术问题非常重要,但我将忽略它来回答我认为是您的潜在问题。

据我所知,您的基本问题是以下两个代码片段之间是否存在差异:

decks d = replicateM 2 (shuffleDeck d)


decks d = do
    d1 <- shuffleDeck d
    d2 <- shuffleDeck d
    return [d1, d2]

如果这两者之间存在差异,Monad有问题的类型的实例已损坏。单子(monad)定律与 replicateM 的定义相结合要求这些表达式具有相同的结果。

关于haskell - Random Monad 在replicatM 迭代之间是独立的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26735523/

相关文章:

haskell - 优雅前奏曲(头.头)

caching - Haskell 缓存函数结果

unix - 正确终止生成的 runghc 进程

-13 和 13 之间的 javascript/jquery 随机数,不包括 -3 和 3 之间的数字

随机抽样 - 矩阵

haskell - 在用户定义类型和现有类型之间定义已经存在(例如在 Prelude 中)运算符的正确方法是什么?

java - HashMap:以随机顺序迭代键值对

swift - 0 和文本框文本之间的随机数

r - R中runif和sample的区别?

google-bigquery - 在 Big Query 中从每个组中随机抽取样本