C#實現(xiàn)基于權(quán)重的隨機算法

一运杭、線性掃描

最簡單常用的算法夫啊,獲取隨機值,直接遍歷辆憔。

public static int GetRandomIndexLinear(int[] list, int totalWeight)
{
    var value = random.Next(0, totalWeight);
    for (int i = 0; i < list.Length; i++)
    {
        value -= list[i];
        if (value <= 0)
        {
            return i;
        }
    }
    return -1;
}

二涮母、預(yù)處理

首先對權(quán)重進行處理,填充PrepareAdRewardWeight躁愿。

public static (float, int)[] PrepareAdRewardWeight;

設(shè)置n個空桶,空桶容量為平均權(quán)重沪蓬,按平均權(quán)重區(qū)分大權(quán)重與小權(quán)重彤钟,依次將小權(quán)重填入桶中,剩余部分由大權(quán)重的一部分填滿跷叉,大權(quán)重減去填充部分后逸雹,如果小于平均值,則后續(xù)當做小權(quán)重處理云挟。
一輪遍歷后梆砸,填充好的數(shù)據(jù)為小權(quán)重的占比和大權(quán)重的索引。

public static void InitAdRewardWeight(int[] weightList)
{
    var total = weightList.Sum();
    int length = weightList.Length;
    var avg = 1f * total / length;
    List<(float, int)> smallAvg = new List<(float, int)>();
    List<(float, int)> bigAvg = new List<(float, int)>();
    for (int i = 0; i < weightList.Length; i++)
    {
        (weightList[i] > avg ? bigAvg : smallAvg).Add((weightList[i], i));
    }
    PrepareAdRewardWeight = new (float, int)[weightList.Length];
    for (int i = 0; i < weightList.Length; i++)
    {
        if (smallAvg.Count > 0)
        {
            if (bigAvg.Count > 0)
            {
                PrepareAdRewardWeight[smallAvg[0].Item2] = (smallAvg[0].Item1 / avg, bigAvg[0].Item2);
                bigAvg[0] = (bigAvg[0].Item1 - avg + smallAvg[0].Item1, bigAvg[0].Item2);
                if (avg - bigAvg[0].Item1 > 0.0000001f)
                {
                    smallAvg.Add(bigAvg[0]);
                    bigAvg.RemoveAt(0);
                }
            }
            else
            {
                PrepareAdRewardWeight[smallAvg[0].Item2] = (smallAvg[0].Item1 / avg, smallAvg[0].Item2);
            }
            smallAvg.RemoveAt(0);
        }
        else
        {
            PrepareAdRewardWeight[bigAvg[0].Item2] = (bigAvg[0].Item1 / avg, bigAvg[0].Item2);
            bigAvg.RemoveAt(0);
        }
    }
}

預(yù)處理結(jié)束后园欣,獲取隨機值的復(fù)雜度為O(1)帖世。

public static int GetRandomIndex()
{
    var randomNum = random.NextDouble() * PrepareAdRewardWeight.Length;
    int intRan = (int)Math.Floor(randomNum);
    var p = PrepareAdRewardWeight[intRan];
    if (p.Item1 > randomNum - intRan)
    {
        return intRan;
    }
    else
    {
        return p.Item2;
    }
}

三、總結(jié)

隨機目標的數(shù)量越大沸枯,第二種方法越高效日矫。

參考

https://zhuanlan.zhihu.com/p/146216606

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市绑榴,隨后出現(xiàn)的幾起案子哪轿,更是在濱河造成了極大的恐慌,老刑警劉巖翔怎,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窃诉,死亡現(xiàn)場離奇詭異,居然都是意外死亡赤套,警方通過查閱死者的電腦和手機飘痛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來于毙,“玉大人敦冬,你說我怎么就攤上這事∥ň冢” “怎么了脖旱?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵堪遂,是天一觀的道長。 經(jīng)常有香客問我萌庆,道長溶褪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任践险,我火速辦了婚禮猿妈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘巍虫。我一直安慰自己彭则,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布占遥。 她就那樣靜靜地躺著俯抖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓦胎。 梳的紋絲不亂的頭發(fā)上芬萍,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音搔啊,去河邊找鬼柬祠。 笑死,一個胖子當著我的面吹牛负芋,可吹牛的內(nèi)容都是我干的漫蛔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼旧蛾,長吁一口氣:“原來是場噩夢啊……” “哼惩猫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蚜点,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤轧房,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绍绘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奶镶,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年陪拘,在試婚紗的時候發(fā)現(xiàn)自己被綠了厂镇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡左刽,死狀恐怖捺信,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤迄靠,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布秒咨,位于F島的核電站,受9級特大地震影響掌挚,放射性物質(zhì)發(fā)生泄漏雨席。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一吠式、第九天 我趴在偏房一處隱蔽的房頂上張望陡厘。 院中可真熱鬧,春花似錦特占、人聲如沸糙置。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽罢低。三九已至,卻和暖如春胖笛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宜岛。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工长踊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萍倡。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓身弊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親列敲。 傳聞我的和親對象是個殘疾皇子阱佛,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容