作者aiweisen (魯‧排骨宅)
看板java
標題[問題] Random 的範圍到底多大?
時間Wed Sep 9 15:27:16 2015
各位前輩你們好
是這樣子的 目前我要去製作10%~90%的機率出來
原本的方式是這樣
假設是要製作10%的機率 那就是準備一個陣列 陣列裡面裝有1個1、9個0
執行的時候 每次使用Math.random()的方式從陣列內取值 每次都會記錄取幾次才成功
然後只要一成功 就開始執行下一次 總共執行100次
但被老師打槍說這樣的機率根本不是10%
就好比 硬幣有50%的機率都是正面跟反面 我們要求產生50%的正面
那執行10次能保證說 正反面出現的次數一樣嗎? 可能剛好10次都是反面
所以要一直擲骰子 擲到正反面出現的次數一樣才行
最後我們老師提出兩種方式
1.增加執行次數 讓他趨近於10%
也就是原本的方法 不要只執行100次 要執行到1萬 10萬 甚至是100萬次
這個樣本數才夠足以證明10%
2. 增加random範圍
假設java的random範圍是-9999999~9999999
切個10個區域 若random出來的結果剛好就落在指定的區域
那就是算成功的10% 成功後就繼續執行下一筆 然後執行100次
第一個要做比較容易
但第二個我就有問題了
我找到的資料是
Math.random()好像是0~0.9999999(無窮小數)
而Random rnd = new Random()這個方法
一般是直接餵seed 告訴random中從seed隨機取一個值
但是 我找不到說 在沒有餵seed情況下 Random的範圍是多大
請問 有人知道怎麼算說 Random的範圍是多大?
還是說Random跟Math.random()一樣 範圍都是無窮大?
--
作者 MicroGG (La new總冠軍) 看板 Japan_Travel 標題 [問題] 溫泉旅館的兒童人頭算法? → robler:問問題然後自稱拎背這樣好嗎 有點禮貌ok?04/11 16:32
→ penan:骨科大 XD04/11 16:34
→ MicroGG:你不懂,我有苦衷,我不說拎杯會被鄉民罵..04/11 16:36
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.138.150.27
※ 文章網址: https://www.ptt.cc/bbs/java/M.1441783643.A.BD2.html
→ cowbaying: 0.0~1.0 09/09 15:56
→ ssccg: 每次都剛好一樣,就不叫隨機了,先確定你的需求... 09/09 16:09
聽不太懂你的意思 請容許我跳針一下
目前就是client會固定一個時間(例如每5s或30s...等等)去向server做查詢的動作
但是client不一定每次都會上線
所以要做一個假設說 假設10%的機率client會上線做查詢 那麼須要花多久時間?
現在就是卡在說 要怎樣做出那個10%的機率 才是真正符合那所謂"10%"機率的上線可能
※ 編輯: aiweisen (140.138.150.27), 09/09/2015 16:28:13
→ ssccg: 至於random的範圍 09/09 16:19
→ ssccg: docs.oracle.com/javase/8/docs/api/java/util/Random.html 09/09 16:20
→ ssccg: Math.random就是Random.nextDouble,其他的上面都有寫 09/09 16:20
→ ssccg: new Random一般是"不"餵seed,上面也有寫會用一個重複機率 09/09 16:22
→ ssccg: 很低的seed,自己設seed是要產生重複結果時才會用 09/09 16:23
→ ssccg: 範圍跟seed沒關係也不是無窮,數位資料值域都是有限的 09/09 16:25
一般Random好像都是搭配nextInt()來使用
那麼範圍就是依照nextInt()的 2^32 是麻?
※ 編輯: aiweisen (140.138.150.27), 09/09/2015 16:34:27
→ ssccg: 如果你相信java的實作,那nextInt(10)結果就是0~9機率各10% 09/09 16:43
這我就不懂了
那跟我直接在陣列裡面放10個值 然後用Random去跑 去抓裡面其中的特定的值
跟直接nextInt(10)會一樣嘛?
→ ssccg: 如果你說的是 array[new Random().nextInt(10)] 那一樣 09/09 17:04
抱歉 剛打到一半同學被拖走
雖然說nextInt(10)每個出現的機率都是10% 但是這個問題後面就會跟硬幣一樣
硬幣出現正反兩面的機率是50% 但是要擲出多少次的硬幣 使出現"正面" 的機率是50%?
我是要製作後面的50%
話說回到new Random() 請問他的範圍是0~2^32-1嗎?
※ 編輯: aiweisen (140.138.238.19), 09/09/2015 18:20:57
推 LPH66: 你去把你剛才提的投硬幣這個例子丟回去給你們老師 09/09 19:41
→ LPH66: 說起來, 誰規定 10% 一定是每十次要有一次? 09/09 19:42
恩 所以才會說10%的機率下可能會24次才會中一次 5次才會中一次 也有可能一次就中
這些24次 5次 都是有包含前面23次的失敗跟4次的失敗
才會提到說 執行這10%的機率要作很多組
假設做1萬組 總共花了86953次 其中一萬次是成功 其他失敗是76953次
那是不是就可以說成功的機率大概是 10000(成功次數)/85953(總次數)=11.5%
→ LPH66: 回到你的 Random() 問題, 你把隨機數引擎跟取值混在一起了 09/09 19:44
→ LPH66: new Random() 是做出一個隨機數引擎 09/09 19:44
→ LPH66: 你要怎麼取亂數是 nextXxx() 在取的 09/09 19:44
→ LPH66: 你可以 new 一個 Random 物件然後從中取整數/取浮點數/etc. 09/09 19:45
→ LPH66: 所以「Random() 的範圍」這問題根本問錯方向了 09/09 19:46
→ LPH66: 最後我覺得你找個時間跟你們老師好好談談他到底在講什麼 09/09 19:50
→ LPH66: 不然我們這邊給了一堆建議如果又被你們老師打槍不就囧了 09/09 19:50
→ LPH66: 對他提的方法有問題就去問他, 我們不可能懂他在想什麼 09/09 19:51
→ lucky1lk: Random的範圍多大 跟你問的問題根本不相關... 09/09 19:52
→ LPH66: 多嘴一句, 你可以查查「先驗機率」跟「後驗機率」這兩個詞 09/09 19:53
好 明白了
→ lucky1lk: Random的範圍多大 看你的型別 09/09 19:55
所以就是看對象是 int long double 這些的範圍是嗎?
→ ssccg: 出現正面的機率50%的情況下,出現正面的"次數"是50%的機率 09/09 20:02
→ ssccg: 是C(n,n/2)0.5^n,這值不會是100% 09/09 20:06
→ ssccg: 你要"次數"是50%,那根本就不需要隨機,準備好結果就好啊 09/09 20:08
我不曉得有沒有誤會你的意思
以這個為例 你的意思是說 我就一直給他跑數據
跑到剛好出現正面的次數剛好是佔所有次數的一半就可以停止了 是嗎?
例如 1024(出現正面的次數)/2048(所有正反面的次數)
※ 編輯: aiweisen (140.138.238.19), 09/09/2015 21:00:57
推 ooooooo: 看不懂你所謂的"成功"是什麼 不過我猜你要的是shuffle 09/09 21:35
我所謂的成功就好比是指
一直擲硬幣 總共擲了幾次硬幣 才會出現一個正面 然後紀錄次數 再做下一輪
話說 什麼是shuffle?
※ 編輯: aiweisen (140.138.238.19), 09/09/2015 22:54:17
→ ooooooo: 以10%機率來說,我感覺你要的是 10次必定要出現1次 09/10 00:20
→ ooooooo: 那就可以想成拿10張撲克牌洗牌 每次抽獎就是取走一張牌 09/10 00:21
→ ooooooo: 這樣就可以保證 10次中必定中1次 09/10 00:22
所以我不確定我原本的想法是不是正確的
拿原本的例子套用在你這 也就是說
撲克牌有A、2、3...10共10張 每張牌取的機率都一樣
請問要取幾次牌才會使A剛好是佔全部次數的10%?
推 k47100014: 假設你client有1000個,你隨機挑100個不就是10%了嗎 09/10 02:12
推 k47100014: 不是每個client都用10%機率下去抽而是用總數的10%下去 09/10 02:15
→ k47100014: 挑client,不知道這樣有沒有符合你的條件 09/10 02:15
應該說沒以要先擴大 就一個server跟一個client
但這邊也是我問題的其中之一
更原始的要求的是
「client 會固定一個時間向server查詢資料,但是server有10%的機率會上線.如果查詢
的時候server沒上線,這個時候client就會再等待下一個固定時間,再去向servert查詢,
一直重複到server開啟,最後統計總共花多少時間」
所以我的演算法大致上如下
計數=0
10%陣列={1,0,0,0,0,0,0,0,0,0}
for(執行100次){
繼續=true
while(繼續){
亂數值=產生亂數0~9
計數加1
if(10%陣列[亂數值] is 1){
繼續=false
}
else{
skip
}//if else end
}//while end
}//for end
但是最後就老師被打槍 然後舉前面擲硬幣的例子給我聽
所以就會覺得奇怪的是 以上面的「更原始的要求」那邊來看
我不知道是不是看的角度不同 那個10%的機率是指
1.假定好server上線的機率為10%,由這個機率去跑數據 (這是我最原始的作法)
2.server只有上線或不上線兩種可能,client要查詢多少次才發現server上線的機率為10%
但現在老師提供的第一種方式 好像是有點混合我1、2這兩個角度
也就變成
假定好server上線的機率為10%,然後client要查詢多少次才發現server上線的機率為10%
老師講到這 就又開始舉擲骰子的例子了==
但這樣會符合上面的「更原始的要求」的題目嗎?
※ 編輯: aiweisen (140.138.238.19), 09/10/2015 09:58:34
推 cyclone350: 所以你做了一百次的結果是幾%? 09/10 10:00
推 ctrlbreak: 不討論題目, Java的亂數是平均的亂數, random1~10 出現 09/11 18:00
→ ctrlbreak: 1的機率就是10%了.. 09/11 18:01
推 k47100014: 原來是server的上線機率阿...但要怎麼去定義Server機率 09/11 22:48
→ k47100014: ?一天24HR,Server上線2.4小時?因為如果Server沒開,所 09/11 22:49
→ k47100014: 有的Client都無法查詢到資料,還是你要以五分鐘作時間 09/11 22:50
→ k47100014: 區隔,一天就有288次測試,10%的話就是28.8次上線區段 09/11 22:50
→ k47100014: 你上面那段程式碼 是以程式內建的亂數去跑上線機率 09/11 22:52
→ k47100014: 如果A Client在十二點的時候開始測試,他每五分鐘Test 09/11 22:53
→ k47100014: 一次,B Client在十二點半的時候開始測試,一樣五分鐘 09/11 22:53
→ k47100014: Test一次,而Server在十三點整開啟,所以A會測試12次 09/11 22:54
→ k47100014: B會測試六次。機率之所以是機率就是因為我們不知道接下 09/11 22:55
→ k47100014: 來會發生甚麼事情,沒辦法真的去定義玩美的10% 09/11 22:55
→ realmeat: 你可以用 rand%10 .... 09/16 13:51
→ realmeat: 不過你的題目我看不懂 09/16 13:53