Java實驗--課上提到的隨機數生成原理簡單實現(不利用庫生成隨機數的簡單算法)
阿新 • • 發佈:2018-10-14
9.png 技術分享 當前 span col 分享 args 簡單 返回
對於隨機數的實驗,根據課程上的教程,有如下的公式:
對應的變量參數的說明:
其中對應的Mouduls變量對應的就是公式中a的值,在公式中的含義就是相當於要循環多少個數才重復的一個值。
Multiplier對應的就是公式中m的值,表示的是範圍值,例如圖上的16807表示的就是取種子返回的隨機數的範圍為0-16806。
公式中的c表示的是公式每次返回的隨機數要增長的一個值,如果是常數的話,每次增長的值將會是一個固定的值,就變成了容易重復的狀態,所以,為了不使其是一個重復的狀態,我打算在每次取完隨機數之後將生成的隨機數Xn賦值給c;
Xn表示的隨機數函數中取種子的一個步驟,其中第一次取值,其實就是取種子的過程,也就是對X0取值的過程,當取到第一個種子後,此後的隨機數一般都不用取種子了。
根據上述的簡單分析,那麽以下就是實驗實現隨機數的一個算法,代碼如下:
package suijishu; public class Suijishu { private long xn=0; private long c=0; public int random_num(int a,int b) { return (int) (random()%(b-a+1)+a); } public long random() //生成第n+1個的隨機數過程 { int Multiplier=16807;long Modulus=((1<<31)-1); xn=(Modulus*xn+c)%Multiplier; c=xn; return xn; } public void setseed(long seed) //取種子 { xn=seed; } //主函數 public static void main(String[] args) { // TODO 自動生成的方法存根 Suijishu sjs=new Suijishu();int num[]=new int[6]; //模擬色子的六個面整型變量 int account=0; sjs.setseed(System.currentTimeMillis()); for(int i=0;i<6000;i++) //模擬循環6000次搖色子的過程 { account=sjs.random_num(1,6); //搖色子 ++num[account-1]; //對應的色子面的變量加一 } for(int j=0;j<6;j++) { System.out.println((j+1)+":"+num[j]);//看最終色子對應面被咬的次數 } } }
類中setseed是一個取種子的函數,我在代碼中取的種子是系統的當前時間。(距離1970年1月1日的毫秒數),因為時間是一直在變得,因此取時間作為種子是一個不錯的選擇。
random()是一個取種子之後的返回隨機數的函數
random_num(int a,int b)是一個封裝的函數,返回a-b之間的隨機數的值;
下面是實驗的截圖:
隨機數的分布情況還是挺平均的。
Java實驗--課上提到的隨機數生成原理簡單實現(不利用庫生成隨機數的簡單算法)