你已經知道如何將數字轉換0和91之間,並把它變成一個卷(從答案到你以前的問題)。我建議你創建一個N元素數組,其中N >> 91。用0 ... 90填充前91個元素,並將計數器A
設置爲91.現在選擇一個介於0和A之間的數字,選擇相應的元素,並轉換爲乘法問題。如果答案不正確,請將問題編號追加到數組末尾,並將A
加1。
這將創建一個數組,其中採樣頻率將表示錯誤解決問題的次數 - 但如果問題在下次詢問時正確解決,它不會再次降低頻率。
另一種更好的解決方案,以及更接近你的一個(但不同)創建一個包含91個頻率的陣列 - 每個頻率初始設置爲1,並跟蹤總和(最初爲91)。但是現在,當你選擇一個隨機數(在0和總和之間)時,你遍歷數組,直到累積和大於你的隨機數 - 倉的數量就是你選擇的倉位,然後用前面推導的公式。如果答案錯誤,則增加容器並更新總和;如果它是正確的,你減少總和,但從不小於一個值,並更新總和。重複。
這應該給你準確的問題:給定91個數字(「bin」)的數組,隨機選擇一個bin,以便該bin的概率與其中的值成比例。返回bin的索引(可以使用之前的方法將它轉換爲數字的組合)。使用bin(頻率)數組作爲第一個參數調用此函數,第二個作爲累積和。你查找其中第n個元素的累計總和首次超過通過頻率的總和邁上了一個隨機數:看起來酷似概率
private int chooseBin(float[] freq, float fsum) {
// given an array of frequencies (probabilities) freq
// and the sum of this array, fsum
// choose a random number between 0 and 90
// such that if this function is called many times
// the frequency with which each value is observed converges
// on the frequencies in freq
float x, cs=0; // x stores random value, cs is cumulative sum
int ii=-1; // variable that increments until random value is found
x = Math.rand();
while(cs < x*fsum && ii<90) {
// increment cumulative sum until it's bigger than fraction x of sum
ii++;
cs += freq[ii];
}
return ii;
}
我證實,它給了我一個直方圖(藍色條)分佈,我餵它(紅線):
(注 - 這是繪製與matlab所以X從1到91,而不是從0到90)。
這裏是另一個想法(這是不是真的回答這個問題,但它可能更有趣):
您可以扭曲你通過採樣比均勻分佈的其他一些選擇特定問題的概率。例如,均勻採樣隨機變量的平方將有利於較小的數字。這給了我們一個有趣的可能性:
首先,洗你的91號變成一個隨機順序
下一步,選擇從非均勻分佈的數量(一個有利於更小的數字)。由於數字隨機洗牌,實際上他們可能被選中。但現在這裏有一個訣竅:如果問題(由所選數字表示)得到正確解決,則將問題編號移動到「堆棧的頂部」,最不可能再次選擇問題編號。如果玩家錯了,它會移動到堆棧的最底部,最有可能再次被選中。隨着時間的推移,困難問題會轉移到堆棧底部。
可以使用的
roll = (int)(91*(asin(Math.rand()*a)/asin(a)))
變化創建具有不同程度的歪斜的隨機分佈,當你做出a
越接近1,功能趨於幾乎爲零的概率較高的數字的偏愛較低的數字:
我相信下面的代碼段做什麼,我描述:
private int[] chooseProblem(float bias, int[] currentShuffle) {
// if bias == 0, we choose from uniform distribution
// for 0 < bias <= 1, we choose from increasingly biased distribution
// for bias > 1, we choose from uniform distribution
// array currentShuffle contains the numbers 0..90, initially in shuffled order
// when a problem is solved correctly it is moved to the top of the pile
// when it is wrong, it is moved to the bottom.
// return value contains number1, number2, and the current position of the problem in the list
int problem, problemIndex;
if(bias < 0 || bias > 1) bias = 0;
if(bias == 0) {
problem = random.nextInt(91);
problemIndex = problem;
}
else {
float x = asin(Math.random()*bias)/asin(bias);
problemIndex = Math.floor(91*x);
problem = currentShuffle[problemIndex];
}
// now convert "problem number" into two numbers:
int first, last;
first = (int)((Math.sqrt(8*problem + 1)-1)/2);
last = problem - first * (first+1)/2;
// and return the result:
return {first, last, problemIndex};
}
private void shuffleProblems(int[] currentShuffle, int upDown) {
// when upDown==0, return a randomly shuffled array
// when upDown < 0, (wrong answer) move element[-upDown] to zero
// when upDown > 0, (correct answer) move element[upDown] to last position
// note - if problem 0 is answered incorrectly, don't call this routine!
int ii, temp, swap;
if(upDown == 0) {
// first an ordered list:
for(ii=0;ii<91;ii++) {
currentShuffle[ii]=ii;
}
// now shuffle it:
for(ii=0;ii<91;ii++) {
temp = currentShuffle[ii];
swap = ii + random.nextInt(91-ii);
currentShuffle[ii]=currentShuffle[swap];
currentShuffle[swap]=temp;
}
return;
}
if(upDown < 0) {
temp = currentShuffle[-upDown];
for(ii = -upDown; ii>0; ii--) {
currentShuffle[ii]=currentShuffle[ii-1];
}
currentShuffle[0] = temp;
}
else {
temp = currentShuffle[upDown];
for(ii = upDown; ii<90; ii++) {
currentShuffle[ii]=currentShuffle[ii+1];
}
currentShuffle[90] = temp;
}
return;
}
// main problem posing loop:
int[] currentShuffle = new int[91];
int[] newProblem;
int keepGoing = 1;
// initial shuffle:
shuffleProblems(currentShuffle, 0); // initial shuffle
while(keepGoing) {
newProblem = chooseProblem(bias, currentShuffle);
// pose the problem, get the answer
if(wrong) {
if(newProblem > 0) shuffleProblems(currentShuffle, -newProblem[2]);
}
else shuffleProblems(currentShuffle, newProblem[2]);
// decide if you keep going...
}
爲什麼**你不**嘗試自己並驗證它是否有效? (O_o) – SudoRahul
@ R.J嗯,我提出了一個問題並提出了一個可能的解決方案。如果它有效,那麼你只需將它作爲答案發布,你就會被接受。 – Justin