博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于网站抽奖活动算法的尝试
阅读量:6758 次
发布时间:2019-06-26

本文共 3279 字,大约阅读时间需要 10 分钟。

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

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);
            }
        }
    }
}

转载地址:http://vxweo.baihongyu.com/

你可能感兴趣的文章
亚马逊宣布与西云数据达成合作,旨在进一步扩大中国业务
查看>>
java nio的基础--缓冲区
查看>>
负载均衡沙龙活动第二期现场问答汇集
查看>>
GBDT原理及利用GBDT构造新的特征-Python实现
查看>>
Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(10)...
查看>>
【Xamarin.Forms】在XAML中传递参数
查看>>
关于数据仓库 — 总体工具介绍
查看>>
最大的错误是不敢犯错
查看>>
跟我学交换机配置(七)
查看>>
makefile 中 $@ $^ % 2015-04-11 18:02:36
查看>>
C#强化系列文章三:实验分析C#中三种计时器使用异同点
查看>>
Linux 进程间通信(一)
查看>>
通用对象池ObjectPool的一种简易设计和实现方案
查看>>
HTTP压缩仍让加密连接处于风险之中
查看>>
乐视阿里达成百亿元销售框架
查看>>
戴尔通过提升大数据分析能力巩固“全数据”战略 帮助企业在现代数据经济中蓬勃发展...
查看>>
⑤Windows Server 8 RemoteFX体验
查看>>
《企业云桌面实施》-小技巧-03-vSAN6.5中SAS和SSD的使用建议
查看>>
cocos2d-x学习笔记番外篇02:获取系统毫秒时间
查看>>
perl学习笔记(1)
查看>>