帶權重的隨機演算法

2021-07-23 09:34:54 字數 2873 閱讀 2290

但是,對於這樣的問題,怎樣才能實現這樣的隨機效果呢?直接使用random函式,是不可能做到的。其實相信好多人都已經有實現的思路了,就是產生0-100之間的隨機數,當隨機數在0-70時,就獲得3等獎,70-90是2等獎,90-100是一等獎。一般情況下,這種隨機概率,是通過讀取**或檔案來獲取的,然後儲存在陣列之類的容器中,這裡只使用陣列來模擬這些資料。下面,我們就來用c++實現這個功能:

由於在c/c++中沒有random函式,這裡先自己定義乙個。這裡使用c語言自帶的rand函式,但直接使用rand函式會產生乙個問題,就是每次產生的隨機數都是同乙個隨機數,所以,這裡使用時間來產生隨機種子,這樣,產生的數就是隨機的了。根據時間產生隨機種子要用到time.h,使用rand函式要用到stdlib.h,這裡引入兩個標頭檔案和基本的標頭檔案:

#include #include #include
建立自己的random函式:

int random(int x)
然後在寫主函式:

int main();

int length = sizeof(a)/sizeof(int);

int sum = 0;

for (int i = 0; i < length; i++)

int randval = random(sum);

printf("%d\n",randval);

int grade = 0;

for (int i = 0;i < length; i++)

randval -= a[i];

} printf("%d等獎\n",grade);

system("pause");

return 0;

}

首先設定各個獎勵的權重,這裡的權重之和不必非要是100,我的這段**設定的權重之和位100,是為了方便讀者了解到各個獎勵抽中的概率,所以這樣設定的,理論上說,數值大一點,產生的隨機數更大,也更加隨機。這裡只將權重放大陣列中,一般情況下,需要策劃提供相關的配表,然後從配表中讀取數值,這樣,在應用中,可以通過跟新配表,來事實更新權重資訊。由於通過配表設定了權重,所以,獎勵種類不確定,因此,通過sizeof函式,獲取數所佔空間,然後,除以int所佔記憶體空間,獲得陣列長度。然後,求權重總和,再呼叫自己建立的隨機函式,產生隨機數。下面就是判斷這個隨機數在那種獎勵的權重範圍了。將獲取的隨機送randval和權重陣列中的數進行比較,首先和a[0]作比較,加入獲取的隨機數是41,a[0]=5,41>a[0],那麼,將41 - 5 等於36,繼續和第二個數a[1]也就是10進行比較,36比10大,就減去10,變成26,然後繼續和a[2]也就是15比較,還是大,就減去15變為16,然後和a[3] 也就是25比較,這時,比25小,也就是說,此時隨機到了這個獎勵,由於等級是從1開始,陣列從0開始,所以,將i+1的值賦值給grade作為獎勵等級,然後break,退出迴圈,輸出獎勵型別。這樣就實現了乙個簡單的帶權重的隨機函式。也就是上面**的整體邏輯,後面的system("pause");函式時為了讓輸出的控制台不要迅速關閉,才加上的。

下面,要加深程式難度了。

由於筆者是遊戲開發者,這裡就以遊戲來說事兒吧(貌似只有遊戲會有這麼多的要求

int main(),

, ,

};int length = sizeof(a[0])/sizeof(int);

//設定vip等級

int vip = 3;

int sum = 0;

for (int i = 0; i < length; i++)

int randval = random(sum);

printf("%d\n",randval);

int grade = 0;

for (int i = 0;i < length; i++)

randval -= a[vip][i];

} printf("%d等獎\n",grade);

system("pause");

return 0;

}

首先將各個vip等級的數值獲取出來,放在陣列中,一般也可以在想要**的時候,直接去表中讀取也可以,只讀取對應vip的那一行資料,然後,放在乙個一維陣列中。這裡的二維陣列,其實就是一維陣列的陣列,相信大家都看得懂,通過獲取a[0]的長度,來判斷獎勵有幾種。然後,套用之前的方法,根據vip等級和產生的隨機數,來產生獎勵,相信大家也能看出來,vip等級越高,高階獎勵的概率越大(

這還只是簡單的問題,還有更難的。大家都知道,隨機函式會產生乙個範圍的數,例如,0-100,也就是說會產生邊界值0和100,不僅如此,而且,概率也不小。0-100總共101個數,這兩個數的概率都是1/101,舉個例子,當vip0的時候,如果權重是這樣的:,也就是說,在設計的時候,不是vip的話,抽不到1等獎,但是從上面的方法來說,如果隨機的數randval的值為0,randval<=a[0][0],也就是0,等於條件滿足了,也就是抽到了1等獎,但是,按照策劃的要求,不應該有0,程式設計的結果和策劃要求不匹配,而且,概率還很大,有人會想,如果將權重同時乘以100,產生0-10000的隨機數,這樣概率就小很多了,但實際上,還是不可行,還是有概率,因此,要想方法將為0的值過濾掉,這樣,就不會產生權重為0的獎勵了。所以,這裡要對0進行判斷,當a[vip][i] == 0時,就直接退出當前迴圈,進入下次的迴圈,這樣就避免了這樣的問題。**上,只需要在上面的for迴圈中,先判斷是否為0即可。**如下:

for (int i = 0;i < length; i++)

if (randval <= a[vip][i])

randval -= a[vip][i];

}

這樣基本上就完成了乙個帶權重的隨機數演算法。其實這個功能也不是很難,只不過是可能存在一些特殊情況,這裡將其進行了部分考慮,如果有表達不嚴謹的地方,還請技術大牛們指正。

權重隨機演算法

主要用於計算 ip池設計,實現概率選擇優質 ip,所以簡單寫了個權重隨機演算法。如果量大注意int 超限,預設20次 支援107374182個ip。權重物件類 public class ipweight public void setaddress string address public int...

演算法 權重隨機

權重物件 public class randomobject id public int id 四類寶箱中物品數量的權重 json格式資料 1,101 2,102 31,103 41,104 寶箱中具體物品數量的權重 json格式資料 1202,100 1203,100 1201,100 1210,...

python 獲取帶權重的隨機數

usr bin env python coding utf 8 import random def random weight weight data total sum weight data.values 權重求和 ra random.uniform 0,total 在0與權重和之前獲取乙個隨機...