青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

WisKeyのLullaby

huangwei.pro 『我失去了一只臂膀』「就睜開了一只眼睛」

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  12 Posts :: 0 Stories :: 23 Comments :: 0 Trackbacks

公告

“我該走哪條路?”
“這取決于你要去哪里。”
“我只想能到某個地方。”
“只要你走的夠遠,你始終能到達那個地方。”

Home: huangwei.pro
E-Mail: sir.huangwei [at] gmail.com
09.6 畢業(yè)于杭州電子科技大學
進入網(wǎng)易杭州研究院工作至今

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

積分與排名

  • 積分 - 51846
  • 排名 - 450

最新評論

閱讀排行榜

評論排行榜

http://huangwei.pro/2015-07/game-random/


這段時間公司開發(fā)的游戲上線測試,許多玩家在抽卡時抱怨臉黑,很難抽到所需要的卡牌,而又有一部分玩家反應(yīng)運氣好能連著抽到紫卡,檢查了下隨機相關(guān)邏輯代碼,并沒有找出問題所在,玩家運氣好與壞只是覺得真有可能是概率原因。


測試開服了幾天之后,需要開放某個限時抽卡活動,在內(nèi)部測試時,我們發(fā)現(xiàn)玩家反應(yīng)的問題在限時抽卡中格外明顯,尤其是其中最主要的一張稀有卡牌,猜測因為限時抽卡庫配置的種類較少,然后就拿該活動來檢查了下我們游戲隨機機制問題。

5%概率?20次出現(xiàn)一次?

大部分游戲策劃使用權(quán)值來配置隨機概率,因為權(quán)值有個好處就是可以在增加隨機物品時,可以不對之前的配置進行更改,比如:白卡 30,藍卡 10,紫卡 10,轉(zhuǎn)為概率即是:白卡 60%,藍卡 20%,紫卡 20%。

而上述限時抽卡的例子中,我們的權(quán)值配置是5和95,模擬50000次隨機(使用系統(tǒng)隨機函數(shù),如C的rand函數(shù),Python的random庫)得到如下結(jié)果:

按權(quán)值隨機50000次

上圖繪制的是權(quán)值為5的卡牌的隨機狀態(tài),紅色的圖是分布圖,X軸是出現(xiàn)的次數(shù),Y軸是相同卡牌再次出現(xiàn)的間隔。綠色的圖是分布概率圖,X軸是間隔數(shù),Y軸是概率。按策劃的想法,5%概率應(yīng)該等同于20次出現(xiàn)一次,那上圖很明顯并不滿足20次出現(xiàn)一次出現(xiàn)規(guī)則,實際間隔從近到遠呈下坡形狀分布,就是說相鄰的概率最大,間隔最大超過160,這與玩家所吐槽的抽卡體驗是一致的。但50000次隨機總共出現(xiàn)了2508次,從統(tǒng)計的意義上來說又是符合5%概率的。所以這個問題,究其原因就是所謂的概率是統(tǒng)計意義上的還是分布意義上的問題。

最原始的實現(xiàn)

我用列表里取元素的方式來模擬20次出現(xiàn)一次,為了方便比較異同,直接隨機的方式我也貼上相關(guān)代碼。

pool = [0]*5 + [1]*95 result = [random.choice(a) for i in xrange(N)] 

上面是直接隨機的方式,只保證5%概率

pool = [] result = [] for i in xrange(N): if not pool: pool = [0]*1 + [1]*19 random.shuffle(pool) result.append(pool[-1]) del pool[-1] 

上面是打亂列表,然后依次取元素的方式,保證20次出現(xiàn)一次,而5%概率則是隱含在內(nèi)的,生成效果如下圖。

使用第二種實現(xiàn)的隨機分布

該圖明顯跟第一個實現(xiàn)的圖不一樣,上圖表明了間隔基本上是落在[0, 40]的區(qū)間內(nèi),并且均勻分布在20那條藍色對稱線附近。這個才是最終想要的隨機的效果。紅色的線是正態(tài)分布曲線,是不是很相似?后面我會講到。

眼尖的會發(fā)現(xiàn)在第一個實現(xiàn)中我用的pool是[0]*5 + [1]*95,而第二個實現(xiàn)中我用的是[0]*1 + [1]*19

這里20次出現(xiàn)一次并不等同于100次出現(xiàn)五次,也是從分布的意義上來說的,100次出現(xiàn)五次是存在5次連續(xù)出現(xiàn)的可能。

針對策劃的配置,我們需要進行預(yù)處理,怎么處理?GCD啊~,5和95的最大公約數(shù)是5,所以在第二個實現(xiàn)的代碼中我直接使用了1和19。

但這里有個問題,一般策劃配置的隨機庫中肯定有多個物品。權(quán)值如果配置的比較隨意的話,很可能就導(dǎo)致GCD為1,這樣想要實現(xiàn)XX次出現(xiàn)一次就不可行了。比如剛才的權(quán)值配置5和95,再加一個權(quán)值為11的話,就只能實現(xiàn)111次出現(xiàn)5次

所以這兩種依賴列表的隨機方式并不適用,一是需要維護的列表內(nèi)存會比較大,二是對策劃配置方式有過多約束。

更通用更優(yōu)美的實現(xiàn)

20次出現(xiàn)一次是以20為標準周期,當然不能每次都是間隔20出現(xiàn),這樣就太假了,根本沒有隨機感受可言,為了模擬隨機并可以控制一定的出現(xiàn)頻率,我選擇正態(tài)分布來進行偽隨機分布生成,原因是分布會更自然一些。

正態(tài)分布

關(guān)于正態(tài)分布這里就不詳細描述了,只需關(guān)心分布的兩個參數(shù)即可,位置參數(shù)為μ、尺度參數(shù)為σ。根據(jù)正態(tài)分布,兩個標準差之內(nèi)的比率合起來為95%;三個標準差之內(nèi)的比率合起來為99%。

根據(jù)正態(tài)分布,兩個標準差之內(nèi)的比率合起來為95%;三個標準差之內(nèi)的比率合起來為99%

用上面的例子來定下參數(shù),μ=20,σ=20/3,這樣每次按正態(tài)分布隨機,就能得到一個理想的隨機分布和概率區(qū)間。

C語言標準函數(shù)庫中只有rand,如何生成符合正態(tài)分布的隨機數(shù)可以參見WiKi上的介紹。這里我直接使用Python中random庫中的normalvariate函數(shù),當然gauss函數(shù)也是一樣的,官方文檔上說gauss函數(shù)會快些,StackOverFlow上說gauss是非線程安全函數(shù),所以會快。我自己簡單測試了下,在單線程情況下,gauss是會快些,但只是快了一點點而已。

首先,我直接生成權(quán)值為5的卡牌的間隔,檢驗下正態(tài)分布的隨機效果。

NN = int(N*0.05) mu, sigma = 20, 20/3. delta = [int(random.normalvariate(mu, sigma)) for i in xrange(NN)] 

模擬正態(tài)分布的偽隨機

這圖是不是比第二個實現(xiàn)的圖更好看一些,分布也更平滑一些呢。OK,接下來就是替換舊的隨機算法了。

細節(jié)和優(yōu)化

剛才說了隨機庫中會有很多物品,都需要按照各自的權(quán)值隨機,并各自出現(xiàn)頻率符合正態(tài)分布。下面我們來說說細節(jié)。

wtp = [1.*x/sum(wt) for x in wt] result = [] p = [random.normalvariate(1./x, 1./x/3.) for x in wtp] for i in xrange(N): minp = 1.e9 minj = -1 for j, pp in enumerate(p): if pp < minp: minp = pp minj = j result.append(minj) for j, pp in enumerate(p): p[j] -= minp p[minj] = random.normalvariate(1./wtp[minj], 1./wtp[minj]/3.) 

這里我使用了統(tǒng)一的隨機種子,隨機測試了500萬次后,所得的結(jié)果與多個隨機種子差別不大。

簡單解釋下代碼:初始化對所有物品按權(quán)值進行正態(tài)分布隨機,每次取位置最小值的物品(也就是最先出現(xiàn)的),然后其它物品均減去該值,被取出的物品再單獨進行一次正態(tài)分布隨機,再次循環(huán)判斷位置最小值。

這里,每次都需要對所有物品進行求最小值和減法,都是需要遍歷的運算,我們可以有如下優(yōu)化。

例如:(1,3,4) -> 取1減1, (0,2,3) -> 隨機1, (1,2,3),其實我們只是為了保持各物品之間位置的相對順序即可,將對其它物品的減法變成對自己的加法,操作量級立馬從O(N)縮為O(1) 。

如上面的例子:(1,3,4) -> 取1, (0,3,4) -> 隨機1加1, (2,3,4),這樣的操作不會改變物品序列的正確性。

熟悉最小堆的朋友,將查找最小值優(yōu)化到O(1)應(yīng)該也沒啥問題吧。

wtp = [1.*x/sum(wt) for x in wt] result = [] p = [(random[i].normalvariate(1./x, 1./x/3.), i) for x in wtp] heapq.heapify(p) for i in xrange(N): minp, minj = heapq.heappop(p) result.append(minj) heapq.heappush(p, (random[minj].normalvariate(1./wtp[minj], 1./wtp[minj]/3.)+minp, minj)) 

測試結(jié)果

問題分析和算法實現(xiàn)就到這了,替換進我的游戲里看看什么效果,我已經(jīng)迫不及待了。

物品測試權(quán)值序列[10, 30, 50, 110, 150, 200, 250, 500],隨機測試500萬次。

第一個隨機實現(xiàn) 
第一個隨機實現(xiàn)

第一個實現(xiàn)是只符合統(tǒng)計要求,不符合分布要求。

第二個隨機實現(xiàn) 
第二個隨機實現(xiàn)

第二個實現(xiàn)中對權(quán)值序列進行了GCD,可以看到只有綠色是符合分布要求的,而藍色和青色退化成第一種實現(xiàn)。

基于正態(tài)分布的隨機實現(xiàn) 
基于正態(tài)分布的隨機實現(xiàn)

完美!

玩家體驗

最好每個玩家有各自的隨機種子,否則會造成體驗上的誤差。服從正態(tài)分布的全局隨機序列,不同玩家任意的取走序列中一段或者一些值,就可能導(dǎo)致對于每個玩家而言,各自取出的隨機序列不再服從正態(tài)分布。

結(jié)束

我只能感嘆Python的庫太強大了,matplotlib繪制出來的圖形也挺漂亮的,感興趣的童鞋可以查閱用Python做科學計算

更多內(nèi)容請移步huangwei.pro

posted on 2015-07-27 01:20 威士忌 閱讀(3458) 評論(4)  編輯 收藏 引用

Feedback

# re: 游戲中的隨機概率 2015-07-27 16:54 GameBoy
C++ 有normal_distribution實現(xiàn)正態(tài)分布  回復(fù)  更多評論
  

# re: 游戲中的隨機概率 2015-07-28 11:55 KaleoVon
在游戲中做強化之類概率的時候,也遇到了這種問題,好文章  回復(fù)  更多評論
  

# re: 游戲中的隨機概率 2015-08-31 14:18 freeeyes
非常不錯,主要是以誰為1的問題。好文章,記錄了。  回復(fù)  更多評論
  

# re: 游戲中的隨機概率 2015-12-01 17:16 mmocake
Python的庫確實強大 MARK下  回復(fù)  更多評論
  


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产午夜精品视频免费不卡69堂| 久久亚洲不卡| 久久国产手机看片| 中文久久乱码一区二区| 欧美在线视频观看| 亚洲欧美日韩另类| 欧美金8天国| 欧美激情视频一区二区三区免费| 国产午夜亚洲精品羞羞网站| 一区二区三区四区五区精品视频| 最新成人av网站| 久久久久九九视频| 久久久福利视频| 国产日韩精品一区二区三区在线| 在线一区二区三区四区| 一区二区三区久久网| 欧美夫妇交换俱乐部在线观看| 久久裸体艺术| 国产在线不卡| 欧美一区二区三区日韩视频| 先锋资源久久| 国产精品理论片| 亚洲一区久久| 午夜精品久久久久久99热| 欧美性开放视频| 宅男精品视频| 先锋亚洲精品| 国产一区二区三区久久| 欧美一区二区精品| 久久激情视频久久| 国产真实精品久久二三区| 午夜日韩在线观看| 久久久久久久久综合| 狠狠狠色丁香婷婷综合久久五月| 欧美中文字幕不卡| 久久琪琪电影院| 亚洲国产精品v| 蜜臀av在线播放一区二区三区| 欧美激情在线免费观看| 亚洲日本欧美日韩高观看| 欧美成人按摩| 一本久道久久综合婷婷鲸鱼| 亚洲免费在线视频一区 二区| 国产精品美女久久| 欧美一区二区三区免费视| 美女被久久久| 日韩午夜免费视频| 国产精品免费看久久久香蕉| 午夜一区在线| 欧美xx视频| 亚洲永久免费| 影音先锋中文字幕一区二区| 欧美精品二区三区四区免费看视频| 亚洲精品一二区| 久久成人国产| 亚洲毛片网站| 国产日韩欧美视频| 免费观看日韩av| 亚洲视频导航| 欧美a级一区二区| 亚洲在线一区二区| 好吊色欧美一区二区三区视频| 欧美freesex交免费视频| 亚洲视频二区| 亚洲国产欧美一区| 午夜影院日韩| 99国产精品久久久| 国产一区二区精品| 欧美日韩麻豆| 久久久噜噜噜久久中文字免| 亚洲毛片在线看| 免费av成人在线| 午夜免费久久久久| 日韩午夜在线观看视频| 国产日韩一区| 国产精品大片wwwwww| 久久综合久色欧美综合狠狠 | 99综合电影在线视频| 国产麻豆精品theporn| 欧美国产一区视频在线观看| 欧美一区二区三区免费大片| 日韩亚洲国产精品| 免费在线国产精品| 欧美在线首页| 亚洲欧美成aⅴ人在线观看| 尤物yw午夜国产精品视频| 国产精品欧美日韩一区二区| 欧美精品日韩综合在线| 久久五月天婷婷| 欧美亚洲网站| 亚洲一区国产精品| 一本色道综合亚洲| 亚洲精品老司机| 亚洲国产精品va在线看黑人| 久久免费视频一区| 亚洲欧美中文日韩v在线观看| 99亚洲一区二区| 亚洲日韩中文字幕在线播放| 亚洲国产aⅴ天堂久久| 国产尤物精品| 狠狠色伊人亚洲综合网站色 | 欧美日韩一区二区三区四区在线观看| 老司机免费视频久久| 久久riav二区三区| 久久国产精彩视频| 欧美在线资源| 久久成人免费网| 久久国产主播精品| 久久久久久欧美| 久久亚洲一区二区三区四区| 久久人人超碰| 久久午夜av| 欧美不卡在线视频| 欧美.日韩.国产.一区.二区| 牛人盗摄一区二区三区视频| 欧美成人精品三级在线观看| 欧美成年网站| 欧美日韩情趣电影| 国产精品高清一区二区三区| 国产精品视频一区二区高潮| 国产视频精品xxxx| 韩国视频理论视频久久| 在线免费观看成人网| 亚洲黄色成人| 中日韩午夜理伦电影免费| 亚洲一区二区成人在线观看| 午夜在线视频观看日韩17c| 欧美资源在线| 免费视频一区二区三区在线观看| 另类春色校园亚洲| 亚洲国产日韩欧美| 一区二区福利| 久久精品成人一区二区三区蜜臀 | 欧美精品福利| 国产精品爱啪在线线免费观看 | 国产一区二区三区久久精品| 有坂深雪在线一区| 最新国产成人在线观看| 中文精品99久久国产香蕉| 亚洲免费在线看| 免费欧美高清视频| 99精品欧美一区二区三区综合在线| 亚洲在线观看视频网站| 久久精品日韩一区二区三区| 欧美极品影院| 国产无遮挡一区二区三区毛片日本| 亚洲丰满在线| 亚洲欧美制服中文字幕| 牛牛影视久久网| 一区二区三区波多野结衣在线观看| 欧美在线日韩在线| 欧美精品一区二区三区一线天视频 | 久久国产高清| 欧美久久久久久久久久| 国产伦精品一区二区三区高清版 | 韩国美女久久| 一区二区三区偷拍| 久久久久9999亚洲精品| 亚洲伦理在线| 久久亚洲综合色一区二区三区| 国产精品a级| 亚洲国产精品黑人久久久| 亚洲欧美日韩精品久久亚洲区| 欧美黄在线观看| 性欧美videos另类喷潮| 国产精品99免费看| 亚洲精品国精品久久99热一| 久久久久九九视频| 亚洲午夜av| 欧美日韩精品在线播放| 在线播放中文字幕一区| 欧美一区亚洲二区| 夜夜嗨av一区二区三区网页| 美脚丝袜一区二区三区在线观看 | 亚洲免费成人| 美女日韩在线中文字幕| 国产一在线精品一区在线观看| 亚洲一区免费观看| 亚洲欧洲在线播放| 免费久久精品视频| 亚洲第一天堂无码专区| 久久免费少妇高潮久久精品99| 亚洲天堂av综合网| 欧美视频在线观看一区| 99精品欧美一区二区三区综合在线| 欧美国产先锋| 久久综合色婷婷| 在线观看国产日韩| 老牛嫩草一区二区三区日本| 性8sex亚洲区入口| 国产老肥熟一区二区三区| 亚洲一区二区三区在线视频| 日韩视频免费在线观看| 欧美精品在线极品| 亚洲精品国产精品国产自| 欧美激情bt| 欧美二区在线播放| 日韩一级片网址| 日韩亚洲欧美在线观看| 欧美日韩精选|