精華區beta java 關於我們 聯絡資訊
※ 引述《oniki.bbs@ptt.cc (宇治金時月見雪)》之銘言: > 有10%的機率出現18~20 > 有30%的機率出現11~17 > 剩下的60%機率出現0~10 > 請問該怎麼做呢 謝謝各位 需X個數字 其中10%的Outcome A={18,19,20} 其中30%的Outcome B={11,12,13..17} 其中60%的Outcome C={0,1,2,.10} 由A中, 抽 X*0.1 次 由B中, 抽 X*0.3 次 由C中, 抽 X*0.6 次 再亂序放入martix ps. 不滿一次的自己補上XD -- ※ Origin: SayYA 資訊站 <bbs.sayya.org> ◆ From: 163.26.34.214 ◆ Modify: 06/03/09 11:27:09 <163.26.34.214> > -------------------------------------------------------------------------- < 作者: ogamenewbie (觸摸著銀河的新手) 看板: java 標題: Re: [問題] 亂數產生一個矩陣 時間: Thu Mar 9 12:54:28 2006 我現在在用的是... 先設好一個檔案, 裡面格式是 name min max freq [freq ...] 例如說我今天說 aaa 1 3 9 5 1 這在程式裡面代表的意思就是 aaa 這個東西如果出現 15 次(9+5+1, freq總和) 其中有 9 次(第1個freq)會是 1 (min, 迴圈起始條件), 5 次(第2個freq)會是 2, 1 次(第3個freq)會是 3 (max, 迴圈終止條件) 去檔案抓值出來放... 開一個陣列, 長度是freq總和 照每一個元素的出現次數放進陣列裡面... 然後照機率跟名字依序放進陣列 例如 A[0] = 1; A[1] = 1; A[2] = 1; ... A[8] = 1; A[9] = 2; A[10] = 2; ... A[13] = 2; A[14] = 3; 依此類推 (實際程式碼當然是用迴圈去放, 這邊是為了解說...) 然後再去那個陣列隨機從中抓值就好了... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 163.25.148.49 > -------------------------------------------------------------------------- < 作者: PsMonkey (痞子軍團團長) 看板: java 標題: Re: [問題] 亂數產生一個矩陣 時間: Thu Mar 9 13:55:10 2006 當然是包物件阿... 寫 Java 怎麼可以不包物件... \囧/ (路人:這... 不相關吧? ==.==) 我的做法跟上面幾位大大不一樣... 首先,要有幾個 Utility,裡頭有一些 method 長得像這樣 public static double[] aDistributeMethod(int amount){ double[] result = new double[amount]; for(int i=0; i<amount; i++){ result[i]=aProbProduct(); } return result; } /* * 假設 distribution 為 {1, 2, 1} * 則 value 傳入 0~1 時候回傳 0,傳入 1.x~3 時回傳 1,3.x~ 回傳 2 */ public static int valueLocationAt(double[] distribution, double value){ double sum = 0; for(int i=0; i<distribution.length; i++){ sum+=distribution[i]; if(value<=sum){ return i; } } return distribution.length; } aProbProduct() 就看你要怎麼弄 要 poisson 還是什麼鬼的,請隨意 寫一個我喜歡用 Seed 作結尾的物件,這裡就叫做 FooSeed 吧 public class FooSeed { private final String pool[]; private double distribution[]; private double totalProbability; public FooSeed(int totalAmount){ pool = new String[totalAmount]; distribution = Distribution.poisson(totalAmount); for(int i=0; i<pool.length; i++){ pool[i] = "\\囧/"; } totalProbability = Calculate.sumOfArray(distribution); } public double getTotalProbability(){ return totalProbability; } public String pickFoo(){ double value = Distribution.random(0.0, totalProbability); int index = Distribution.valueLocationAt(distribution, value); return pool[index]; } } 那麼,只要 new FooSeed 然後對 FooSeed 一直 pickFoo 就好 這是我的做法,還請各方高手多多指點 [擺茶點] ===== 最近在寫的案子... T__T ==== ㄟ對,qrttOne,再來篇比較的文章吧 我好想 m 阿.... \囧/ -- 侃侃長論鮮窒礙 網站:http://www.psmonkey.idv.tw 眾目睽睽無心顫 個人版:telnet://legend.twbbs.org 煢居少聊常人事 殺頭容易告白難 歡迎參觀 Java 版(@ptt.cc)精華區 \囧/ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 203.204.16.17 > -------------------------------------------------------------------------- < 作者: TonyQ (骨頭) 看板: java 標題: Re: [問題] 亂數產生一個矩陣 時間: Thu Mar 9 15:34:40 2006 ※ 引述《oniki (宇治金時月見雪)》之銘言: : 這是我的程式碼 : Random ra = new Random(); : int[][] M = new int[10][10]; : for (int i=0;i<10;i++){ : for(int j=0;j<10;j++){ : M[i][j]=ra.nextInt(21); : } : } : 這樣是在會產生一個10x10的矩陣 : 裡面的element都是0~20的亂數 : 我想問的是 : 要怎樣才能夠讓每個element的值有機率性的落在0~20中的某些特定範圍 : 舉例說 : 我想要讓這個element : 有10%的機率出現18~20 : 有30%的機率出現11~17 : 剩下的60%機率出現0~10 : 請問該怎麼做呢 謝謝各位 好久沒看到這麼好玩的問題了!! 讓人忍不住手癢實作了一個XD (程式碼很醜 請諸位大德鞭小力一點 orz) 我的作法是把機率量化 比方說10 30 60 (如果有小數點就四捨五入) 然後亂數產生0~100的數字 看它落在哪個區間 就去產生那個區間的亂數 比方說落在 0~10好了 就產生18~20之間的亂數 不過我習慣用Math.random() 跟原po不一樣就是了XD 底下有實作的程式碼 node是我用來代表區間的參數 constructer 第一個放start 第二個是end 第三個是機率 比方說 有10%的機率出現18~20 就是 (18,20,10) <---> % -- 這裡順便附上我測試用的程式碼 RandomNum rn=new RandomNum(); rn.addMoreNode(18,20,10); rn.addMoreNode(11,17,30); rn.addMoreNode(0,10,60); int[] ary=new int[21]; for(int i=0;i<10000;i++) ary[rn.getRandomNum()]++; int sum1=0; for(int i=0;i<=10;i++) sum1+=ary[i]; int sum2=0; for(int i=11;i<=17;i++) sum2+=ary[i]; int sum3=0; for(int i=18;i<=20;i++) sum3+=ary[i]; System.out.println("區間1:"+sum1/10000.0); System.out.println("區間2:"+sum2/10000.0); System.out.println("區間3:"+sum3/10000.0); -- class RandomNum{ int count; LinkedList<node> nodeList; RandomNum(){ nodeList=new LinkedList<node>(); count=0; } boolean addMoreNode(node in){ count+= (int)(in.chance +0.5); return nodeList.add(in); } boolean addMoreNode(int start ,int end,double chance){ node in=new node(start,end,chance); count+= (int)(in.chance +0.5); return nodeList.add(in); } int getRandomNum(){ int k=(int)(Math.random()*count)+1; int index=0; while(index<size()&&k>0){ node temp= nodeList.get(index); k-= (int)(temp.chance +0.5); index++; } index--; return nodeList.get(index).getNum(); } int size(){ return nodeList.size(); } } class node{ //用來代表所需要的節點 double chance; int start; int end; int size; node(int start1 ,int end1,double chance1){ start = start1; end = end1; chance = chance1; size = end-start+1; } int getNum(){ return (int)(Math.random()*(end-start+1)) + start; } } -- String temp="relax"; | Life just like programing while(buringlife) String.forgot(temp); | to be right or wrong while(sleeping) brain.setMemoryOut(); | need not to say stack.push(life.running); | the complier will stack.push(scouting.buck()); | answer your life stack.push(bowling.pratice()); | Bone everything -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.138.240.58 ※ 編輯: TonyQ 來自: 140.138.240.58 (03/09 15:36) > -------------------------------------------------------------------------- < 作者: zanyking (遙遠的旅人) 看板: java 標題: Re: [問題] 亂數產生一個矩陣 時間: Sun Mar 12 04:38:56 2006 之前好像有看過類似的問題...可以參考一下。 文章網址如下: http://www.javaworld.com.tw/jute/post/view?bid=29&id=141413&sty=1 如果眼睛不嫌累的話,就看以下的程式碼吧。 _________________________________________________________________ package test; public class DiscreteProcessor { protected int X1; protected int X2; protected int[] arr; /** * 設定曲線方程式跟區間(x1,x2) * @param fomula * @param X1 * @param X2 */ public void init(CurveFomula fomula,int X1,int X2) { this.X1 = X1; this.X2 = X2; arr = new int[X2-X1]; for (int i = 0, j = arr.length; i < j; i++) { int X = X1 + i;// 現在的X值 arr[i] = fomula.excute(X); // System.out.println("arr[" +i+ "]" + arr[i]); } } /** * 從X1開始,到X2結束,求算曲線積分值, * @return */ public long sigmaDiscrete() { long SUM = 0; for (int i = 0, j = arr.length; i < j; i++) SUM += arr[i]; return SUM; } /** * 取得符合該Fomula的整數離散數列,從X1開始,到X2結束 * @return */ public int[] getDiscreteSamples() { return arr; } /** * @param args */ public static void main(String[] args) { int x1 = 1; int x2 = 1001; int length = x2-x1; Ah_taiCurveFomula fomula1 = new Ah_taiCurveFomula(); DiscreteProcessor processor = new DiscreteProcessor(); processor.init(fomula1,x1,x2); int[] testData = new int[length];//測試統計結果 for (int i = 0, j = 1000000; i < j; i++) { int pickData = diceValue(processor.sigmaDiscrete(), processor.getDiscreteSamples());//多骰幾次,統計一下 testData[pickData]++; } for (int i = 0, j = length; i < j; i++) {// 試看看列印出來答案跟權陣的比例一不一樣? // System.out.println("ans[" + i + "]" + testData[i]); System.out.println(testData[i]); } } /** * Random出來一個參數,然後看他落在哪個權陣區間...燈燈燈,答案出來瞭 * * @param q * @param weightArr * @return */ public static int diceValue(long SUM, int[] weightArr) { double total = Math.random() * SUM; int temp = 0; for (int i = 0, j = weightArr.length; i < j; i++) { temp += weightArr[i]; if (total <= temp) { return i; } } return -1;// an fatal Error!!! } } interface CurveFomula { /** * Y = f(x),輸入X,求Y,直接叫f of x太難聽. * @param X * @return f(X) */ int excute(int X); } /** * @author Ian *一個CurveFomula的實作,你也可以實作自己的 */ class MyCurveFomula implements CurveFomula { public int excute(int X) { return (int) Math.floor(700000 / X); } } /** * * @author Ian *一個CurveFomula的實作,用你給的方程式 */ class Ah_taiCurveFomula implements CurveFomula { /** * y=1/400 * e ^ ((-1/400)*x) * */ public int excute(int X) { return (int) Math.floor(Math.pow(Math.E,((-1d/400d)*X))*100000d/400d) ; } } ___________________________________________________________________________ 原理是這樣的: 你先開一個地址存放陣列addressArr: int[] addressArr = new int[]{1,2,3}; 然後開一個權重存放矩陣weightArr: int[] weightArr = new int[]{9,5,1}; 再來,亂數產生器產生從 [min ~ SUM(min~max)] 中的任一亂數X。 int address = -1; int sum = 0; for(int i=0;i<weightArr.length;i++) { sum += weightArr[i]; if(X<sum) { address = i; break; } } 這時候,addressArr[X]就是你要的答案。 雖然JAVA沒有指標,你還是可以開陣列去模擬這樣的概念。 隨機產生出來的大量亂數在統計上就會服從你給的曲線分佈。 不曉得能不能解決問題? PS:to 版主,kkcity跟這裏好像已經Async了... -- -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 210.85.116.116 > -------------------------------------------------------------------------- < 作者: AI3767 (AI3767) 看板: java 標題: Re: [問題] 亂數產生一個矩陣 時間: Tue Mar 14 22:17:55 2006 不好意思, 這個主題已經很久了 想說試著寫一個一般型的來試看看 下面有主要程式的程式碼, 寫的不好請見諒 作法很直觀, 就是看機率落在那個範圍 再從那個範圍內取亂數 主要由Factory method取得一個物件 然後這個物件就可以用getRand()來取值了 package tw.edu.ccu.cs.ailab; import java.util.Arrays; import java.util.Random; public class RangeRandom { private Random genRandom; private int[] accumulateArray; private int offset; private float[] probabilityArray; private RangeRandom(int[] rangeArr, int off, float[] probArr) { offset = off; probabilityArray = probArr; setAccumulateArray(rangeArr); setProbArray(probArr); genRandom = new Random(); } //{END constructor} /** 利用 <code>range</code> 陣列所設定的各個範圍大小, 相對同個索引位置的 * <code>probs</code> 陣列是該位置範圍的機率. <p> * 舉例當呼叫 <code>createRangeRandom(new int[]{1,3,2}, 2, * new float[]{0.2f,0.7f,0.1f})</code>,<br> * 則亂數產生 2 的機率有 20%; 3, 4, 或5 的機率有 70%; 6 或 7 的機率有 10%. * <p> * <code>probs<code> 機率陣列的機率和, 必須為 1.0f, 否則會丟出一個 * <code>RuntimeException</code> * @param range 存放各範圍大小的陣列 * @param offset 表示要產生亂數的起始值 * @param probs 存放各範圍機率的陣列 */ public static RangeRandom createRangeRandom(int[] range, int offset, float[] probs) { return new RangeRandom(range, offset, probs); } //{END factory} public static RangeRandom createRangeRandom() private int getCase() { int c = Arrays.binarySearch(probabilityArray, genRandom.nextFloat()); if( c<0 ) return -(++c); else return c; } //{END} private int getCase() public int getRand() { int caseRange = getCase(); if( caseRange==0 ) return offset+genRandom.nextInt(accumulateArray[0]-offset); else return accumulateArray[caseRange-1]+genRandom.nextInt( accumulateArray[caseRange]-accumulateArray[caseRange-1]); } //{END} public int getRand() protected void setProbArray(float[] probArr) { if( probArr.length!= accumulateArray.length ) throw new RuntimeException("Array size doesn't match."); float test = 0f; probabilityArray = new float[probArr.length]; for(int i=0; i<probArr.length; i++) { test += probArr[i]; probabilityArray[i] = test; } if( test!= 1.0f ) throw new RuntimeException("Probability doesn't equal to 1.0."); } //{END} protected void setProbArray() protected void setAccumulateArray(int[] rangeArr) { if( rangeArr.length!= probabilityArray.length ) throw new RuntimeException("Array size doesn't match."); int total = offset; accumulateArray = new int[rangeArr.length]; for(int i=0; i<rangeArr.length; i++) { total += rangeArr[i]; accumulateArray[i] = total; } } //{END} protected void setRangeArray() } //{END class} class RangeRandom -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.123.105.166 ※ 編輯: AI3767 來自: 140.123.105.166 (03/14 22:21) > -------------------------------------------------------------------------- < 作者: zanyking (遙遠的旅人) 看板: java 標題: Re: [問題] 亂數產生一個矩陣 時間: Tue Mar 14 23:57:53 2006 ※ 引述《AI3767 (AI3767)》之銘言: : 不好意思, 這個主題已經很久了 : 想說試著寫一個一般型的來試看看 : 下面有主要程式的程式碼, 寫的不好請見諒 : 作法很直觀, 就是看機率落在那個範圍 : 再從那個範圍內取亂數 : 主要由Factory method取得一個物件 : 然後這個物件就可以用getRand()來取值了 : package tw.edu.ccu.cs.ailab; : import java.util.Arrays; : import java.util.Random; : public class RangeRandom { : private Random genRandom; : private int[] accumulateArray; : private int offset; : private float[] probabilityArray; : private RangeRandom(int[] rangeArr, int off, float[] probArr) { : offset = off; : probabilityArray = probArr; : setAccumulateArray(rangeArr); : setProbArray(probArr); 這裡的寫法很可怕,難懂,又容易錯。 兩個set方法互相要求對方的成員跟自己的長度要一樣,而且你是先讓: probabilityArray = probArr;來方便你取得正確的長度 可是在setProbArray(probArr);卻又一定會把probArr指向另外一個值。 這樣寫很危險。 : genRandom = new Random(); : } //{END constructor} : /** 利用 <code>range</code> 陣列所設定的各個範圍大小, 相對同個索引位置的 : * <code>probs</code> 陣列是該位置範圍的機率. <p> : * 舉例當呼叫 <code>createRangeRandom(new int[]{1,3,2}, 2, : * new float[]{0.2f,0.7f,0.1f})</code>,<br> : * 則亂數產生 2 的機率有 20%; 3, 4, 或5 的機率有 70%; 6 或 7 的機率有 10%. 這裡非常的難懂、也非常的不好用。那個new int[]{1,3,2} 指的是從2開始1個數、3個數、2個數吧? 也就是說如果我想要2,3,4,5,6,7分別有不同的機率我就要宣告: rangs = new int[]{1,1,1,1,1,1}; probs = new float[]{0.1f,0.1f,0.1f,0.1f,0.2f,0.3f}; 這樣的使用者介面超難用。 因為事實上,我並不需要知道個別值佔總體的比例,我只需要知道一個純量的權重就好。 也就是說像這樣: new int[]{12,123,34,1,6,77} 至於個別比例是多少,是寫程式的人要負責算的。 : * <p> : * <code>probs<code> 機率陣列的機率和, 必須為 1.0f, 否則會丟出一個 : * <code>RuntimeException</code> : * @param range 存放各範圍大小的陣列 : * @param offset 表示要產生亂數的起始值 : * @param probs 存放各範圍機率的陣列 : */ : public static RangeRandom createRangeRandom(int[] range, int offset, : float[] probs) { : return new RangeRandom(range, offset, probs); : } //{END factory} public static RangeRandom createRangeRandom() : private int getCase() { : int c = Arrays.binarySearch(probabilityArray, genRandom.nextFloat()); : if( c<0 ) return -(++c); : else return c; : } //{END} private int getCase() 如果是要練習Arrays.binarySearch...那不錯。 不過事實上:return genRandom.nextInt(probabilityArray.length); 就好了。 寫程式,好懂的一行文才是王道。^^ : public int getRand() { : int caseRange = getCase(); : if( caseRange==0 ) : return offset+genRandom.nextInt(accumulateArray[0]-offset); : else : return accumulateArray[caseRange-1]+genRandom.nextInt( : accumulateArray[caseRange]-accumulateArray[caseRange-1]); : } //{END} public int getRand() : protected void setProbArray(float[] probArr) { : if( probArr.length!= accumulateArray.length ) : throw new RuntimeException("Array size doesn't match."); : float test = 0f; : probabilityArray = new float[probArr.length]; : for(int i=0; i<probArr.length; i++) { : test += probArr[i]; : probabilityArray[i] = test; : } : if( test!= 1.0f ) : throw new RuntimeException("Probability doesn't equal to 1.0."); : } //{END} protected void setProbArray() : protected void setAccumulateArray(int[] rangeArr) { : if( rangeArr.length!= probabilityArray.length ) : throw new RuntimeException("Array size doesn't match."); : int total = offset; : accumulateArray = new int[rangeArr.length]; : for(int i=0; i<rangeArr.length; i++) { : total += rangeArr[i]; : accumulateArray[i] = total; : } : } //{END} protected void setRangeArray() public static void main(String[] args) { RangeRandom rand = new RangeRandom(new int[]{1,3,2},2,new float[]{0.2f,0.7f,0.1f}); TreeMap<Integer,Integer> ansMap = new TreeMap<Integer,Integer>() ; for(int i=0;i<100000;i++) { int test = rand.getRand(); if(ansMap.containsKey(test)) ansMap.put(test,ansMap.get(test)+1); else ansMap.put(test,1); } for(Map.Entry<Integer,Integer> ent : ansMap.entrySet()) { System.out.println("ans["+ent.getKey()+"]="+ent.getValue()); } } //給你一個main()不然不能測。 : } //{END class} class RangeRandom 其實這個問題,大家原理應該都是大同小異的。 我是給分佈方程式class,產生機率亂數。 也可以給離散數列,設成權陣Array輸入,產生機率亂數。 道理都相同的。 -- -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 210.85.116.116 > -------------------------------------------------------------------------- < 作者: AI3767 (AI3767) 看板: java 標題: Re: [問題] 亂數產生一個矩陣 時間: Wed Mar 15 01:52:20 2006 ※ 引述《zanyking (遙遠的旅人)》之銘言: : : private RangeRandom(int[] rangeArr, int off, float[] probArr) { : : offset = off; : : probabilityArray = probArr; : : setAccumulateArray(rangeArr); : : setProbArray(probArr); : 這裡的寫法很可怕,難懂,又容易錯。 : 兩個set方法互相要求對方的成員跟自己的長度要一樣,而且你是先讓: : probabilityArray = probArr;來方便你取得正確的長度 : 可是在setProbArray(probArr);卻又一定會把probArr指向另外一個值。 : 這樣寫很危險。 嗯...這裡其實, 在setProbArray的方法裡, 並不會將probArr指向另一個值 因為實作上, 是將probArr做了累積計算放到probabilityArray裡 為的是在取亂數時較為簡易快速 雖然在建構時做了assign的動作, 但在setProbArray裡, 會重新assign新的陣列, 這樣不會改動到原 probArr 而且在物件建出後, 還可以重新設定新的機率, 但是得和原範圍數量相等 例如 probArr為{0.2f,0.7f,0.1f}則在setProbArray裡 會將probabilityArray={0.2f, 0.9f, 1.0f} 本來是想將 set 的方法都private掉, 避免誤用 但想說至少 protected 的話, 還有機會被override掉, 如果不滿意的話 ^^ : : genRandom = new Random(); : : } //{END constructor} : : /** 利用 <code>range</code> 陣列所設定的各個範圍大小, 相對同個索引位置的 : : * <code>probs</code> 陣列是該位置範圍的機率. <p> : : * 舉例當呼叫 <code>createRangeRandom(new int[]{1,3,2}, 2, : : * new float[]{0.2f,0.7f,0.1f})</code>,<br> : : * 則亂數產生 2 的機率有 20%; 3, 4, 或5 的機率有 70%; 6 或 7 的機率有 10%. : 這裡非常的難懂、也非常的不好用。那個new int[]{1,3,2} : 指的是從2開始1個數、3個數、2個數吧? : 也就是說如果我想要2,3,4,5,6,7分別有不同的機率我就要宣告: : rangs = new int[]{1,1,1,1,1,1}; : probs = new float[]{0.1f,0.1f,0.1f,0.1f,0.2f,0.3f}; 若是直接給定的話, 的確是難用的, 我的設想是在 使用者應該會去維護一個範圍array,如rArr,以及對映的機率array,如pArr 然後在要用時, 才去createRangeRandom(rArr,0,pArr) 而上面您給的例子, 可以是 int[] rangs = {4, 1, 1}; float probs = {0.4f, 0.2f, 0.3}; //其實會exception, 因為總和不為1.0f createRangeRandom(rangs, 2, probs); 真正的缺點是在於如果要用的範圍中間是有大量小範圍gap時, 例如: 要 1~20, 22~25, 27~30, 31~35, 37~38 40~42 : 這樣的使用者介面超難用。 : 因為事實上,我並不需要知道個別值佔總體的比例,我只需要知道一個純量的權重就好。 : 也就是說像這樣: : new int[]{12,123,34,1,6,77} : 至於個別比例是多少,是寫程式的人要負責算的。 : : * <p> : : * <code>probs<code> 機率陣列的機率和, 必須為 1.0f, 否則會丟出一個 : : * <code>RuntimeException</code> ... : : private int getCase() { : : int c = Arrays.binarySearch(probabilityArray, genRandom.nextFloat()); : : if( c<0 ) return -(++c); : : else return c; : : } //{END} private int getCase() : 如果是要練習Arrays.binarySearch...那不錯。 : 不過事實上:return genRandom.nextInt(probabilityArray.length); 就好了。 : 寫程式,好懂的一行文才是王道。^^ 這邊是不能用這樣的作法, 原因就在於我用的probabilityArray 實際是原機率array的累計值, 而每個範圍的機率不同, 所以取亂數時, 會依照random出來的float值, 來找出所對映的所在範圍 以上面的例子, 機率為 0.2f 0.7f 0.1f 所以probabilityArray為 0.2f 0.9f 1.0f 當取float時, 若是 0.0~0.2 , 則會再從第1個範圍去取亂數, 這才是真正會回傳的亂數 若 float值>0.2 且<=0.9f, 則在第2個範圍取亂數 同樣當值>0.9f且 <=1.0f, 則在第3個範圍取亂數 而使用Arrays.binaraySearch在於當找不到時, 回傳的值是 -(insertion point)-1, 這個在Documentation內有解釋 : : public int getRand() { : : int caseRange = getCase(); : : if( caseRange==0 ) : : return offset+genRandom.nextInt(accumulateArray[0]-offset); : : else : : return accumulateArray[caseRange-1]+genRandom.nextInt( : : accumulateArray[caseRange]-accumulateArray[caseRange-1]); : : } //{END} public int getRand() : : protected void setProbArray(float[] probArr) { : : if( probArr.length!= accumulateArray.length ) : : throw new RuntimeException("Array size doesn't match."); : : float test = 0f; : : probabilityArray = new float[probArr.length]; : : for(int i=0; i<probArr.length; i++) { : : test += probArr[i]; : : probabilityArray[i] = test; : : } : : if( test!= 1.0f ) : : throw new RuntimeException("Probability doesn't equal to 1.0."); : : } //{END} protected void setProbArray() ... : public static void main(String[] args) : { : RangeRandom rand = new RangeRandom(new int[]{1,3,2},2,new : float[]{0.2f,0.7f,0.1f}); : TreeMap<Integer,Integer> ansMap = new TreeMap<Integer,Integer>() ; : for(int i=0;i<100000;i++) : { : int test = rand.getRand(); : if(ansMap.containsKey(test)) ansMap.put(test,ansMap.get(test)+1); : else ansMap.put(test,1); : } : for(Map.Entry<Integer,Integer> ent : ansMap.entrySet()) : { : System.out.println("ans["+ent.getKey()+"]="+ent.getValue()); : } : } : //給你一個main()不然不能測。 : : } //{END class} class RangeRandom : 其實這個問題,大家原理應該都是大同小異的。 : 我是給分佈方程式class,產生機率亂數。 : 也可以給離散數列,設成權陣Array輸入,產生機率亂數。 : 道理都相同的。 感謝 <(_ _)> -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.123.219.115 ※ 編輯: AI3767 來自: 140.123.219.115 (03/15 01:54) ※ 編輯: AI3767 來自: 140.123.219.115 (03/15 01:59) ※ 編輯: AI3767 來自: 140.123.219.115 (03/15 02:01)