基於多執行緒的隨機數生成演算法
阿新 • • 發佈:2019-01-24
(只限於學習交流,未經許可,請勿用於商業用途)
目前的隨機數演算法產生的多是偽隨機數,產生真的隨機數則一般需要獲取外界環境的輸入。本演算法是根據多執行緒中每個執行緒獲得CPU時間的不確定性而產生隨機數,具有無規律性、無法預測、資料分佈均勻的特點,雖然隨機數產生效率較低,但相信在某些場合可以用的到。
演算法模型:計算機的每一位都是0或1,如果每一位對應一個獨立的執行緒,在這個執行緒中不斷改變對應位置的值,多位組合在一起就可以形成不同的二進位制數字,每一刻訪問都會得到隨機組合的數。和搖桿抽獎類似。當然也可以每一位用0~9的數字進行迴圈,但是因為這樣是有次序的迴圈,產生的隨機數不夠均勻。
關於CPU時間分配這一塊不是很瞭解,個人認為這樣產生的隨機數是無法預測的,歡迎大家過來討論。
附java程式碼的例子:
採用8位2進位制,產生25600個隨機數耗時約25~30spublic class Random { private boolean flag = true, isFirst = true; private int[] a = new int[8]; private Thread t0, t1; public boolean isFlag() { return flag; } public void setFlag(boolean flag) {//在結束隨機數的產生之後,應把flag置為false this.flag = flag; } public int getRandom() throws InterruptedException { //如果是第一次,需要啟動多執行緒 if (isFirst) { isFirst = false; for (int i = 0; i < a.length; i++) { getSubThread(i).start(); } } Thread.sleep(0, 1);//也可以用yield(),可提高几十倍效率,但產生的隨機數分佈不夠均勻 int sum = 0; //轉換為十進位制 for (int i = 0; i < a.length; i++) { Thread.yield(); sum = (sum << 1) + a[i]; } return sum; } private Thread getSubThread(int i) { // TODO Auto-generated method stub Thread t = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub while (flag) { a[i] ^= 1; Thread.yield();//讓出執行緒,否則在flag變化後還可能繼續消耗資源 } } }); return t; } }
下圖是系統自帶的隨機數產生方法與本文的演算法產生的隨機數分佈圖,二者方差接近。