日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

抽奖算法-指定概率的随机

發(fā)布時(shí)間:2023/12/19 综合教程 23 生活家
生活随笔 收集整理的這篇文章主要介紹了 抽奖算法-指定概率的随机 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

 

抽獎(jiǎng)模型

普通概率模型

普通概率模型是最常用的一種模型,但是在游戲運(yùn)營(yíng)過(guò)程中的確發(fā)現(xiàn)很多小白玩家不能正確理解——他們認(rèn)為中獎(jiǎng)率 10% 的設(shè)定等同于抽 10 次肯定會(huì)中一次。這顯然是錯(cuò)誤的,普通概率模型的中獎(jiǎng)抽獎(jiǎng)次數(shù)是基于正態(tài)分布的,而且每次抽獎(jiǎng)的事件是獨(dú)立的,并不會(huì)因?yàn)槟闱懊娉榱?9 次沒(méi)中獎(jiǎng),第十次就一定能中獎(jiǎng)。

雖然在大量的統(tǒng)計(jì)中,兩次中獎(jiǎng)的平均間隔是 10 次,但是還有一個(gè)有趣的數(shù)據(jù)是連續(xù) 10 次都沒(méi)中獎(jiǎng)的概率約為 (1-10%)^10 ~= 34.8% 可不小呢。

此外「標(biāo)準(zhǔn)差」是一個(gè)很有意思的數(shù)據(jù),經(jīng)過(guò)模擬統(tǒng)計(jì),10% 中獎(jiǎng)率得到的標(biāo)準(zhǔn)差為 9.62 ——也就是說(shuō)絕大分部人經(jīng)過(guò) 10 ± 9.62 次抽獎(jiǎng)即能中獎(jiǎng),運(yùn)氣再背抽 20 次也差不多能得到獎(jiǎng)勵(lì)了。

這種概率模型能非常準(zhǔn)確地實(shí)現(xiàn)策劃的需求,但是會(huì)惹來(lái)一些小白玩家的差評(píng)——為什么你說(shuō)中獎(jiǎng)率是 10% 但是我抽了 20 次還沒(méi)有中獎(jiǎng)!然后給你打個(gè)一星。所以很多游戲運(yùn)營(yíng)商為了顧及玩家的體驗(yàn),會(huì)對(duì)普通概率模型進(jìn)行修訂,增設(shè)一些保底抽獎(jiǎng)次數(shù),例如每第 10 次固定中獎(jiǎng)(10,20,30...)

對(duì)于這種做法,我暫不于評(píng)價(jià)。但是讓我們看看如果硬生生地加入固定中獎(jiǎng)的設(shè)定,會(huì)給數(shù)值帶來(lái)什么變化吧。

固定中獎(jiǎng)模型

每次抽獎(jiǎng)中獎(jiǎng)率依舊為 10% ,但每第十次抽獎(jiǎng)必中。

這時(shí)候玩家得到的抽獎(jiǎng)體驗(yàn)是:10 次抽獎(jiǎng)肯定能中獎(jiǎng),而且不止中一次,爽暴了是不是。實(shí)際期望高達(dá) 19% 這遠(yuǎn)遠(yuǎn)超出策劃 10% 的預(yù)期。所以策劃琢磨著不能便宜了玩家,只能把中獎(jiǎng)率調(diào)低。但是這會(huì)導(dǎo)致中獎(jiǎng)集中在每 10 次附近,抽獎(jiǎng)的樂(lè)趣幾近喪失。

這樣看來(lái),固定中獎(jiǎng)模型是否真的無(wú)藥可救?其實(shí)還是有可以優(yōu)化的地方。

計(jì)數(shù)器模型

每次抽獎(jiǎng)中獎(jiǎng)率依舊為 10% ,若連續(xù) 9 次未中獎(jiǎng),下一次抽獎(jiǎng)必中獎(jiǎng)。

這個(gè)需求看起來(lái)和上面好像沒(méi)什么不同,但是保底的條件不再是每第 10 次,而是發(fā)生在每連續(xù) 9 次未中獎(jiǎng)后。也就是說(shuō)計(jì)數(shù)器會(huì)在每次中獎(jiǎng)后清 0 重計(jì)。

 

隨機(jī)步長(zhǎng)累加模型

也是一種保底中獎(jiǎng)模型,只不過(guò)去掉了獨(dú)立隨機(jī)事件,并把計(jì)數(shù)增長(zhǎng)改為隨機(jī)量,最終在累計(jì)超過(guò)閾值時(shí)得獎(jiǎng)。這種模型如果有個(gè)較大的閾值和較小的步長(zhǎng)下限,還可以起到讓玩家在頭幾次抽獎(jiǎng)必然不中(大)獎(jiǎng)的效果。另外在這種模型下,計(jì)數(shù)器甚至可以對(duì)玩家可見(jiàn),讓看玩家看到進(jìn)度和目標(biāo),感受到獎(jiǎng)勵(lì)是可達(dá)的、近在眼前的。

 

 

 

 

抽獎(jiǎng)算法

/// <summary>
/// 抽獎(jiǎng)
/// </summary>
public class Prize
{
    /// <summary>
    /// 獎(jiǎng)品關(guān)鍵字
    /// </summary>
    public string Key { get; set; }

    /// <summary>
    /// 權(quán)重/數(shù)量
    /// </summary>
    public int Poll { get; set; }


    /// <summary>
    /// 中獎(jiǎng)區(qū)間
    /// </summary>
    class Area
    {
        /// <summary>
        /// 獎(jiǎng)品關(guān)鍵字
        /// </summary>
        public string Key { get; set; }

        /// <summary>
        /// 開(kāi)始索引位置
        /// </summary>
        public int Start { get; set; }

        /// <summary>
        /// 截止索引位置
        /// </summary>
        public int Over { get; set; }
    }

    /// <summary>
    /// 隨機(jī)種子
    /// </summary>
    static Random Rand = new Random((int)DateTime.Now.Ticks);


    /// <summary>
    /// 輪盤(pán)抽獎(jiǎng),權(quán)重值(在輪盤(pán)中占的面積大小)為中獎(jiǎng)幾率
    /// </summary>
    /// <param name="prizeList">禮品列表(如果不是百分百中獎(jiǎng)則輪空需要加入到列表里面)</param>
    /// <returns></returns>
    public static string Roulette(List<Prize> prizeList)
    {
        if (prizeList == null || prizeList.Count == 0) return string.Empty;
        if (prizeList.Any(x => x.Poll < 1)) throw new ArgumentOutOfRangeException("poll權(quán)重值不能小于1");
        if (prizeList.Count == 1) return prizeList[0].Key; //只有一種禮品

        Int32 total = prizeList.Sum(x => x.Poll); //權(quán)重和               
        if (total > 1000) throw new ArgumentOutOfRangeException("poll權(quán)重和不能大于1000"); //數(shù)組存儲(chǔ)空間的限制。最多一千種獎(jiǎng)品(及每種獎(jiǎng)品的權(quán)重值都是1)

        List<int> speed = new List<int>(); //隨機(jī)種子
        for (int i = 0; i < total; i++) speed.Add(i);

        int pos = 0;
        Dictionary<int, string> box = new Dictionary<int, string>();
        foreach (Prize p in prizeList)
        {
            for (int c = 0; c < p.Poll; c++) //權(quán)重越大所占的面積份數(shù)就越多
            {
                pos = Prize.Rand.Next(speed.Count); //取隨機(jī)種子坐標(biāo)
                box[speed[pos]] = p.Key; //亂序 禮品放入索引是speed[pos]的箱子里面
                speed.RemoveAt(pos); //移除已抽取的箱子索引號(hào)
            }
        }
        return box[Prize.Rand.Next(total)];
    }

    /// <summary>
    /// 獎(jiǎng)盒抽獎(jiǎng),每個(gè)參與者對(duì)應(yīng)一個(gè)獎(jiǎng)盒,多少人參與就有多少獎(jiǎng)盒
    /// </summary>
    /// <param name="prizeList">禮品列表</param>
    /// <param name="peopleCount">參與人數(shù)</param>
    /// <returns></returns>
    public static string LunkyBox(List<Prize> prizeList, int peopleCount)
    {
        if (prizeList == null || prizeList.Count == 0) return string.Empty;
        if (prizeList.Any(x => x.Poll < 1)) throw new ArgumentOutOfRangeException("poll禮品數(shù)量不能小于1個(gè)");
        if (peopleCount < 1) throw new ArgumentOutOfRangeException("參數(shù)人數(shù)不能小于1人");
        if (prizeList.Count == 1 && peopleCount <= prizeList[0].Poll) return prizeList[0].Key; //只有一種禮品且禮品數(shù)量大于等于參與人數(shù)

        int pos = 0;
        List<Area> box = new List<Area>();
        foreach (Prize p in prizeList)
        {
            box.Add(new Area() { Key = p.Key, Start = pos, Over = pos + p.Poll }); //把禮品放入獎(jiǎng)盒區(qū)間
            pos = pos + p.Poll;
        }

        int total = prizeList.Sum(x => x.Poll); //禮品總數(shù)
        int speed = Math.Max(total, peopleCount); //取禮品總數(shù)和參數(shù)總?cè)藬?shù)中的最大值

        pos = Prize.Rand.Next(speed);
        Area a = box.FirstOrDefault(x => pos >= x.Start && pos < x.Over); //查找索引在獎(jiǎng)盒中對(duì)應(yīng)禮品的位置

        return a == null ? string.Empty : a.Key;
    }

}


/*
List<Prize> prizes = new List<Prize>();
prizes.Add(new Prize() { Key = "電腦", Poll = 1 });
prizes.Add(new Prize() { Key = "機(jī)柜", Poll = 2 });
prizes.Add(new Prize() { Key = "鼠標(biāo)", Poll = 3 });
                        

string lp1 = Prize.LunkyBox(prizes, 6);
Console.WriteLine(lp1);


prizes.Add(new Prize() { Key = "謝謝惠顧", Poll = 5 });
string lp2 = Prize.Roulette(prizes);      
Console.WriteLine(lp2);
*/

 

 

參考

Return random `list` item by its `weight`

不同概率模型的抽獎(jiǎng)體驗(yàn)

抽獎(jiǎng)算法

一個(gè)簡(jiǎn)單抽獎(jiǎng)算法的實(shí)現(xiàn)以及如何預(yù)防超中

總結(jié)

以上是生活随笔為你收集整理的抽奖算法-指定概率的随机的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。