关于网站抽奖活动算法的尝试

    技术2024-12-17  7

    遇到一个需求,某网站为了吸引人气,要开展抽奖活动,需求主要有以下几点:

    1.共分一、二、三等奖,要控制一等奖尽量不要一开始就抽掉;

    2.活动长期开展,持续时间一周左右,要使每天的各奖项概率趋于一致;

    3.为保证每天活动参与人数,要确保在限定人数附近抽出所有奖项;

     

    基于以上几点,做出如下设计:

    1.首先要输入天预估总人数,并将奖品平均分到每天,得到各奖项的日均奖品数(可能为小数);

    2.计算各奖项的抽奖概率,日均奖品数/日抽奖总人数;

    3.产生一个随机双精度数,若小于等于概率则视为抽中;

    4.一次抽奖开始时,先抽取三等奖,若中奖则提示,若不中奖则继续抽取二等奖,若再不中奖则抽取一等奖;

    5.每次抽奖过后,若抽中奖品则预估总人数-1,并且所有概率重新计算,并应用于下一轮抽奖;

    6.若总人数小于一个限定阀值,则停止概率变化,用此概率完成全部抽奖;

    7.当天奖品总数小于1时,抽奖结束,小数部分流入后一天继续抽奖。

     

    大概思路如上,设计较为简单,没有技术含量,会有的问题就是理论上后一天一开始抽奖的概率会偏高一些,也曾想用某些数学公式定理来解决,但因为对概率论不了解,不了了之。

    顺手贴上第一天所有抽奖的代码,希望感兴趣的朋友多给些宝贵意见!

     

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.Threading; namespace Lottery {     class Program     {         private static string InputString;//输入字符串         private static int LevelCount;//         private static int DayNum;//         private static int DayUserNum;//         private static int[] arrPrizeNum;//         private static double[] AvgPrizeNum;         private static double TotalPrizeNum;         private static double[] ArProbability;         public static Random rand = new Random((int)DateTime.Now.Ticks);         static void Main(string[] args)         {             ShowInfo();             GetInputNum("请输入奖项总数:", ref LevelCount);             arrPrizeNum = new int[LevelCount];             InputPrizeNum();             GetInputNum("请输入预计抽奖天数:", ref DayNum);             GetInputNum("请输入第一天预估总人数:", ref DayUserNum);             BeginLottery();         }         private static void ShowInfo()         {             Console.WriteLine("欢迎使用随机抽奖系统!");         }         private static void InputPrizeNum()         {             for (int i = 0; i < LevelCount; i++)             {                 GetInputNum("请输入 " + (i + 1) + " 等奖奖品数目:", ref arrPrizeNum[i]);             }         }         private static void GetInputNum(string words, ref int target)         {             while (true)             {                 Console.WriteLine(words);                 InputString = Console.ReadLine();                 int temp = SafeParse(InputString);                 if (temp != -1)                 {                     target = temp;                     break;                 }                 else                 {                     Console.WriteLine("您的输入有误,请输入整型数字!");                     continue;                 }             }         }         private static int SafeParse(object obj)         {             int temp;             if (!int.TryParse(obj.ToString(), out temp))             {                 temp = -1;             }             return temp;         }         private static void BeginLottery()         {             AvgPrizeNum = new double[LevelCount];             ArProbability = new double[LevelCount];             TotalPrizeNum = 0;             for (int i = 0; i < LevelCount; i++)             {                 TotalPrizeNum += arrPrizeNum[i];             }             for (int i = 0; i < LevelCount; i++)             {                 AvgPrizeNum[i] = (double)arrPrizeNum[i] / (double)DayNum;             }             for (int i = 0; i < LevelCount; i++)             {                 ArProbability[i] = (double)AvgPrizeNum[i] / (double)DayUserNum;             }             for (int j = 0; j < 10000; j++)             {                 double x = rand.NextDouble();                 for (int i = LevelCount - 1; i >= 0; i--)                 {                     if (x < ArProbability[i])                     {                         if (AvgPrizeNum[i] > 1)                         {                             AvgPrizeNum[i]--;                             Console.WriteLine("恭喜您,抽到了" + (i + 1) + "等奖!");                             LotteryOnit();                             //Console.ReadLine();                             break;                         }                         else                         {                             continue;                         }                     }                     else                     {                         Console.WriteLine("很遗憾,欢迎下次再来!" + DayUserNum);                         x = rand.NextDouble();                         LotteryOnit();                         continue;                     }                 }                 if (DayUserNum > TotalPrizeNum / DayNum)                 {                     DayUserNum--;                 }                 for (int i = 0; i < AvgPrizeNum.Length; i++)                 {                     if (AvgPrizeNum[i] >1)                     {                         break;                     }                     if (i == AvgPrizeNum.Length - 1)                     {                         Console.WriteLine("共" + j + "位用户参与," + "奖已抽完!");                         Console.ReadLine();                     }                 }                 Console.WriteLine();             }             Console.ReadLine();         }         private static void LotteryOnit()         {             for (int i = 0; i < LevelCount; i++)             {                 ArProbability[i] = (double)AvgPrizeNum[i] / (double)DayUserNum;                 Console.WriteLine("第"+(i+1)+"等奖的概率变为:"+ArProbability[i].ToString());                 Console.WriteLine(AvgPrizeNum[i] + "    " + DayUserNum);             }         }     } }

     

    最新回复(0)