隨機數算法

軟件實現的算法都是僞隨機算法,隨機種子一般是系統時間
在數論中,線性同餘方程是最基本的同餘方程,“線性”表示方程的未知數次數是一次,即形如:
ax≡b (mod n)的方程。此方程有解當且僅當 b 能夠被 a 與 n 的最大公約數整除(記作 gcd(a,n) | b)。這時,如果 x0 是方程的一個解,那麼所有的解可以表示爲:
{x0+kn/d|(k∈z)}
其中 d 是a 與 n 的最大公約數。在模 n 的完全剩餘系 {0,1,…,n-1} 中,恰有 d 個解。
例子編輯
* 在方程
3x ≡ 2 (mod 6)
中, d = gcd(3,6) = 3 ,3 不整除 2,因此方程無解。
* 在方程
5x ≡ 2 (mod 6)
中, d = gcd(5,6) = 1,1 整除 2,因此方程在{0,1,2,3,4,5} 中恰有一個解: x=4。
* 在方程
4x ≡ 2 (mod 6)
中, d = gcd(4,6) = 2,2 整除 2,因此方程在{0,1,2,3,4,5} 中恰有兩個解: x=2 and x=5。


純線性同餘隨機數生成器
線性同餘隨機數生成器介紹:
古老的LCG(linear congruential generator)代表了最好最樸素的僞隨機數產生器算法。主要原因是容易理解,容易實現,而且速度快。 


LCG 算法數學上基於公式:




X(0)=seed;
X(n+1) = (A * X(n) + C) % M;


其中,各系數爲:
X(0)表示種子seed
模M, M > 0
係數A, 0 < A < M
增量C, 0 <= C < M
原始值(種子) 0 <= X(0) < M
其中參數c, m, a比較敏感,或者說直接影響了僞隨機數產生的質量。


一般來說我們採用M=(2^31)-1 = 2147483647,這個是一個31位的質數,A=48271,這個A能使M得到一個完全週期


,這裏C爲奇數,同時如果數據選擇不好的話,很有可能得到週期很短的隨機數,例如


,如果我們去Seed=179424105的話,那麼隨機數的週期爲1,也就失去了隨機的意義。


(48271*179424105+1)mod(2的31次方-1)=179424105



package test;  
  
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
  
public class Random {  
      
    public final AtomicLong seed=new AtomicLong();  
    public final static long C = 1;  
    public final static long A = 48271;  
    public final static long M = (1L << 31) - 1;  
      
    
    public Random(int seed){
    	this.seed.set(seed);
    }
    
    public Random(){
    	this.seed.set(System.nanoTime());
    }
    
    public long nextLong(){
    	seed.set(System.nanoTime());
    	return  (A *seed.longValue()  + C) % M;
    }
    public int nextInt(int number){
    	return  new Long( (A * System.nanoTime() + C) % number).intValue();
    }
    
      
      
    public static void main(String[] args) {  
    	System.out.println(new Random().nextLong());
    	Map<Integer,Integer> map=new HashMap<Integer,Integer>();
    	for(int i=0;i<100000;i++){
    		int ran=new Random().nextInt(10);
    		if(map.containsKey(ran)){
    			map.put(ran, map.get(ran)+1);
    		}else{
    			map.put(ran, 1);
    		}
    		
    	}
    	System.out.println(map);
    }  
}  

自己寫個簡單例子,隨機10萬次,隨機範圍0到9,看看是否均勻


相對來說還是挺均勻的


發佈了113 篇原創文章 · 獲贊 69 · 訪問量 45萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章