zeh*_*zeh 4 random haskell 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的概率.
我用于shuffle的代码如下:
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
Run Code Online (Sandbox Code Playgroud)
我看到第一眼看起来这个问题似乎微不足道,但考虑到haskell对待随机性的方式,我认为值得提问.
[1]注意:分配不需要像我说的那样统一.它必须是一个已知的分布,所以我可以掌握测试的力量.但在这种情况下它应该是统一的.
[2]注意:如注释中所述,该函数仅使用System.Random而不是Control.Monad.Random.
由于您的示例仅使用replicateMin IO,因此问题实际上有点不正确.replicateM 2 (shuffleDeck d)有类型IO [[Card]].它永远不会等于某种类型[[Card]].虽然在使用Haskell时这个技术问题非常重要,但我会忽略它来回答我认为你的基本问题.
据我所知,您的基本问题是以下两段代码之间是否存在差异:
decks d = replicateM 2 (shuffleDeck d)
Run Code Online (Sandbox Code Playgroud)
和
decks d = do
d1 <- shuffleDeck d
d2 <- shuffleDeck d
return [d1, d2]
Run Code Online (Sandbox Code Playgroud)
如果这两者之间存在差异,则Monad该类型的实例将被破坏.monad法则与定义相结合,replicateM要求这些表达式具有相同的结果.