2014-11-04 30 views
4

我在紙牌遊戲中做了一些假設測試。隨機Monad在replicateM迭代之間是否獨立?

要做到這一點,我實現了遊戲和AI,玩遊戲。爲了進行測試,我必須在我的套牌中安排牌的所有可能性進行抽樣(該套牌有24張牌,所以有24張牌不同的初始狀態)。然而,採樣應該是獨立的,因爲(a)在洗牌之後,每次初始排列應該有概率(1/24!)和(b)如果i和i'是兩次洗牌之後的兩次初始排列,概率,該裝置i和然後佈置I」爲初始安排應是(1/24!)×(1/24!)。[注1]

所以,如果d是我的甲板和shuffleDeck是我洗牌的功能。我相信隨機monad的構建方式是Probability((suffleDeck d)== i)= 1/24!

但我的問題是:這個函數獨立時,與函數replicateM交互?換句話說,以下是真的嗎?

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

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 

我看到,在第一次看這個問題似乎是:

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

,我使用的洗牌的代碼下面給出微不足道,但考慮到haskell處理隨機性的方式,我認爲它值得提一個問題。

[1]注意:分佈並不需要像我說的那樣統一。它只是一個已知的分佈,所以我可以掌握測試的力量。但在這種情況下,它應該是統一的。

[2]注意:如註釋中所述,該函數僅使用System.Random而不是Control.Monad.Random。

+1

您的代碼中沒有任何內容使用'Control.Monad.Random'中的內容,但是'System.Random'的重新導出除外。這使得它有點混亂,特別是當你談論'replicateM'時,但實際上會在'IO'而不是'Rand'中使用它。 – Carl 2014-11-04 12:58:24

回答

5

由於您的示例僅在IO中使用replicateM,所以問題實際上稍有不當。 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實例的問題類型已損壞。單子法結合replicateM的定義要求這些表達式具有相同的結果。

+0

對不起,但我看不出類型的問題。由於(:t replicateM)= Monad m => Int - > ma - > m [a]和(:t shuffleDeck)= [Card] - > IO [Card],我們得到(:t replicateM 2(shuffleDeck d ))= IO [[Card]]。我是否使用不同的replicateM? – zeh 2014-11-04 14:00:48

+0

根據您的評論,可以很容易地看到等式成立。 – zeh 2014-11-04 14:07:19

+0

@zeh你是正確的類型簽名是'IO [[Card]]'。但除此之外,這是解決問題核心的堅實答案。 – 2014-11-04 14:22:38

2

首先,很好的問題。並回答你的問題,是的,你的方程確實成立。在你的代碼中,你顯式地生成了生成器,而不是使用MonadRandom。當你使用MonadRandom時,你應該發現你的公式不僅保持不變,而且兩種不同的雙重洗牌方法實際上應該會給你相同的洗牌甲板。 (這是假設你以確定性方式而不是IO來生成發電機)。公平的推理和反映透明度是強大的。讓我知道我是否可以進一步澄清。