抽奖算法

网上找的抽奖代码都不满意,自己动手丰衣足食,有需要的可以直接拿去用,不收版权费的。

/// <summary>
/// 抽奖
/// </summary>
public class Prize
{
    /// <summary>
    /// 奖品关键字
    /// </summary>
    public string Key { get; set; }

    /// <summary>
    /// 权重/数量
    /// </summary>
    public int Poll { get; set; }

    /// <summary>
    /// 中奖区间
    /// </summary>
    class Area
    {
        /// <summary>
        /// 奖品关键字
        /// </summary>
        public string Key { get; set; }

        /// <summary>
        /// 开始索引位置
        /// </summary>
        public int Start { get; set; }

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

    /// <summary>
    /// 随机种子
    /// </summary>
    static Random Rand = new Random((int)DateTime.Now.Ticks);

    /// <summary>
    /// 轮盘抽奖,权重值(在轮盘中占的面积大小)为中奖几率
    /// </summary>
    /// <param name="prizeList">礼品列表(如果不是百分百中奖则轮空需要加入到列表里面)</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权重值不能小于1");
        if (prizeList.Count == 1) return prizeList[0].Key; //只有一种礼品

        Int32 total = prizeList.Sum(x => x.Poll); //权重和
        if (total > 1000) throw new ArgumentOutOfRangeException("poll权重和不能大于1000"); //数组存储空间的限制。最多一千种奖品(及每种奖品的权重值都是1)

        List<int> speed = new List<int>(); //随机种子
        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++) //权重越大所占的面积份数就越多
            {
                pos = Prize.Rand.Next(speed.Count); //取随机种子坐标
                box[speed[pos]] = p.Key; //乱序 礼品放入索引是speed[pos]的箱子里面
                speed.RemoveAt(pos); //移除已抽取的箱子索引号
            }
        }
        return box[Prize.Rand.Next(total)];
    }

    /// <summary>
    /// 奖盒抽奖,每个参与者对应一个奖盒,多少人参与就有多少奖盒
    /// </summary>
    /// <param name="prizeList">礼品列表</param>
    /// <param name="peopleCount">参与人数</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礼品数量不能小于1个");
        if (peopleCount < 1) throw new ArgumentOutOfRangeException("参数人数不能小于1人");
        if (prizeList.Count == 1 && peopleCount <= prizeList[0].Poll) return prizeList[0].Key; //只有一种礼品且礼品数量大于等于参与人数

        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 }); //把礼品放入奖盒区间
            pos = pos + p.Poll;
        }

        int total = prizeList.Sum(x => x.Poll); //礼品总数
        int speed = Math.Max(total, peopleCount); //取礼品总数和参数总人数中的最大值

        pos = Prize.Rand.Next(speed);
        Area a = box.FirstOrDefault(x => pos >= x.Start && pos < x.Over); //查找索引在奖盒中对应礼品的位置

        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 = "机柜", Poll = 2 });
prizes.Add(new Prize() { Key = "鼠标", 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);
*/
时间: 2024-11-06 03:50:55

抽奖算法的相关文章

中奖概率算法(php 可用于刮刮卡,大转盘等抽奖算法)

php中奖概率算法,可用于刮刮卡,大转盘等抽奖算法.用法很简单,代码里有详细注释说明,一看就懂 <?php /* * 经典的概率算法, * $proArr是一个预先设置的数组, * 假设数组为:array(100,200,300,400), * 开始是从1,1000 这个概率范围内筛选第一个数是否在他的出现概率范围之内, * 如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间, * 在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的. * 这样 筛选到最终,总

php中奖概率算法,可用于刮刮卡,大转盘等抽奖算法

php中奖概率算法,可用于刮刮卡,大转盘等抽奖算法.用法很简单,代码里有详细注释说明,一看就懂 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 <!--?

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

      抽奖算法       参考 Return random `list` item by its `weight`

java版根据权重抽奖算法

根据权重进行抽取的算法应用比较广泛,其中抽奖便是主要用途之一.正好这几天也正在进行抽奖模块的开发,整个抽奖模块涉及到的地方大概有三处,分别是后台进行奖品的添加(同时设置权重和数量),前台根据后台配置生成抽奖队列并根据指令开始抽奖活动,最后一部分是后台统计中奖情况并设置物流状态.本文主要针对前台抽奖算法进行介绍如何根据权重设置每个奖品被抽到的概率. 抽奖算法的核心是根据权重设置随机数出现的概率,在此我将它封装成一个生成随机数的随机类,代码如下: /** * JAVA 返回随机数,并根据概率.比率

Java 抽奖算法

1. 算法分析 根据概率将奖品划分区间,每个区间代表一个奖品,然后抽取随机数,反查落在那个区间上,即为所抽取的奖品. 2. 代码 核心算法 public class Arithmetic { // 放大倍数 private static final int mulriple = 1000000; public int pay(List<Prize> prizes) { int lastScope = 0; // 洗牌,打乱奖品次序 Collections.shuffle(prizes); Ma

PHP抽奖算法

写抽奖无非就是从概率入手,每个层次的奖的概率是该权重总权重的百分比 $arr = array( array('prize'=>'first', 'weight'=>10), array('prize'=>'second','weight'=>10), array('prize'=>'third', 'weight'=>80) //权重依次排下来,权重保证为整型 ); 分析上列数据. 权重加起来=100 所以只能取1到100的随机值 由于1到100的区间内值的概率都是相等

C#抽奖算法

摘自网络 static void Main(string[] args) { //各物品的概率保存在数组里 float[] area = new float[4]{ 0.5f, 0.5f, 0, 0 }; //单次测试 //Console.WriteLine(Get(area)); //批量测试 int[] result = new int[4]{ 0, 0, 0, 0 }; for (int i = 0; i < 1770000; i++) //为了比对结果方便,这里循环的次数是总概率的100

微信平台抽奖算法总结-再也不用怕奖品被提前抢光

前言 但凡商户搞点营销活动,为了能触达更多的顾客,来点儿抽奖的把戏,应该是极好的,什么“刮刮乐”.“砸金蛋”.“大转盘”等等,换汤不换药,屡试不爽.从微客多营销平台各种活动的使用情况也能看出,抽奖活动一直是商户用得最多的线上活动,正所谓无利不起早,给点“花蜜”犒劳下“蜜蜂”也是应该的. 需求分析 那么问题来了,发奖机制怎么玩?作为一个服务商户的营销平台,怎样将商户配置的奖品发出去才能起到比较好的效果呢? 先来看目标,什么是比较好的效果,也就是用户(商户)的需求是什么: 抽奖活动期间奖品数量是固定

JAVA 两个简单的抽奖算法

不多说了,代码不多,算法也简单 方法一: /** * 获取中奖号的算法,方法会在每次抽到一个中奖号后,将最后一个号码填充到此位置,实现不重复抽取. * <p> * 经过多次测试,此方法在大数据时速度略优于{@link #booleans()},小数据时差距可忽略 * * @return */ public int[] deleteLast(){ if(prize <= 0) return new int[0]; int[] nums = new int[max]; for(int i=0