zoukankan      html  css  js  c++  java
  • C#抽奖算法,附调用实例

    前提:设置了奖项内容,中奖概率,奖项个数

    算法结构:

    算法的具体实现:

    1、AliasItemModel

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Maticsoft.Web.Mobile.LuckDraw.AliasMethod
    {
        class AliasItemModel
        {
            private AliasModel basic;
            private AliasModel extension;
    
            public AliasItemModel(AliasModel basic)
            {
                this.basic = basic;
            }
    
            public AliasItemModel(object key, decimal probability) : this(new AliasModel(key, probability)) { }
    
            public AliasModel Basic { set { this.basic = value; } get { return this.basic; } }
            public AliasModel Extension { get { return this.extension; } }
            public bool isDecomposable()
            {
                if (this.basic.Probability > 1)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
    
            public bool Extensible()
            {
                if (this.extension == null && this.basic.Probability < 1)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
    
            public bool Extensible(AliasModel extension)
            {
                if (extension != null && this.Extensible() && extension.Probability + this.basic.Probability > 1)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
    
            public bool Extensible(AliasItemModel aim)
            {
                if (aim != null && aim.isDecomposable() && this.Extensible(aim.Basic))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            public AliasModel Extend(AliasModel extension)
            {
                if (this.Extensible(extension))
                {
                    decimal d = 1 - this.basic.Probability;
                    this.extension = extension.Split(d);
                    return extension;
                }
                else
                {
                    return null;
                }
            }
    
            public decimal Probability { get { return this.basic.Probability; } }
        }
    }
    View Code

    2、AliasMethod

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Maticsoft.Web.Mobile.LuckDraw.AliasMethod
    {
        public class AliasMethod
        {
            private List<AliasItemModel> list = new List<AliasItemModel>();
            public AliasMethod(Dictionary<object, decimal> prizes)
            {
                List<AliasModel> models = new List<AliasModel>();
                decimal otherProbability = 1;
                foreach (KeyValuePair<object, decimal> pair in prizes)
                {
                    models.Add(new AliasModel(pair.Key, pair.Value));
                    otherProbability = otherProbability - pair.Value;
                }
                if (otherProbability > 0)
                {
                    models.Add(new AliasModel(null, otherProbability));
                }
                foreach (AliasModel model in models)
                {
                    list.Add(new AliasItemModel(model.Key, model.Probability * models.Count));
                }
                foreach (AliasItemModel item in list)
                {
                    if (item.isDecomposable())
                    {
                        foreach (AliasItemModel item2 in list)
                        {
                            if (item.isDecomposable() && item2.Extensible(item))
                            {
                                item.Basic = item2.Extend(item.Basic);
                            }
                        }
                    }
                }
            }
    
            public object Raffle()
            {
                Random ran = new Random();
                int listIndex = ran.Next(this.list.Count - 1);
                AliasItemModel item = list[listIndex];
                decimal probabilityIndex = decimal.Parse(ran.NextDouble().ToString());
                if (probabilityIndex >= item.Probability)
                {
                    return item.Extension.Key;
                }
                else
                {
                    return item.Basic.Key;
                }
            }
        }
    }
    View Code

    3、AliasModel

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Maticsoft.Web.Mobile.LuckDraw.AliasMethod
    {
        class AliasModel
        {
            private object key;
            private decimal probability;
    
            public AliasModel(object key, decimal probability)
            {
                this.key = key;
                this.probability = probability;
            }
            public object Key { set { this.key = value; } get { return this.key; } }
            public decimal Probability { set { this.probability = value; } get { return this.probability; } }
    
            public AliasModel Split(decimal d)
            {
                if (d < this.probability)
                {
                    this.probability = this.probability - d;
                    return new AliasModel(this.key, d);
                }
                else
                {
                    return null;
                }
            }
        }
    }
    View Code

    4、RaffleResult(具体场景应用时,可以修改属性)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Maticsoft.Web.Mobile.LuckDraw.AliasMethod
    {
        public class RaffleResult
        {
            public bool Success { set; get; }
            public string Message { set; get; }
            public int PrizeLevel { get; set; }  //奖品级别,1等奖,2等奖……
            public int PrizeID { get; set; }
            public int PrizeType { get; set; }  //奖品类型,实物,红包,优惠券……
            public string PrizeName { get; set; }  //奖项内容,10元红包,5元红包,手机……
            public string CardJson { get; set; }
            public int ActivityPrizeUserID { get; set; }
            public int PrizeState { get; set; }  //中奖状态
            public bool isFirst { get; set; }
    
        }
    }
    View Code

    抽奖事件:                  

    DataSet ds = bll.GetList(" PrizeStatus = 1 AND ActivitysSettingID=" + actId);//获取活动的所有奖品信息
                            if (ds != null && ds.Tables[0].Rows.Count > 0)
                            {
                                int prizeId;
                                int prizeCount;
                                Dictionary<object, decimal> dic = new Dictionary<object, decimal>();
                                foreach (DataRow dr in ds.Tables[0].Rows)
                                {
                                    prizeId = Convert.ToInt32(dr["PrizeID"]);
                                    prizeCount = userBll.GetModelList(" PrizeID=" + prizeId).Count;  //该奖项已经抽中的个数
                                    if (Convert.ToInt32(dr["PrizeNum"]) > prizeCount)
                                    {
                                        dic.Add(prizeId, decimal.Parse(dr["PrizeCount"].ToString()) / 100);
                                    }
                                }
                                AliasMethod.AliasMethod act = new AliasMethod.AliasMethod(dic);
                                object key = act.Raffle();  //执行抽奖
                             
                                if (key != null)
                                {
    //中奖了,
    //处理中奖之后的逻辑操作
    } 
    else{
    //没中奖
     result.PrizeID = 0;
                                    result.PrizeState = 0;
                                    result.Message = "很遗憾,没有中奖!";  //没有抽中
                                    result.Success = true;
                                    result.isFirst = true;
                                    //插入中奖记录表
                                    ActivityPrizeUserID = InserPrizeUserInfo(actId, openId, username, phone, code, null, drawArea);
                                    if (ActivityPrizeUserID > 0)
                                        result.Success = true;
                                    else
                                        result.Success = false;
    
    }
    }
    else
                            {
                                result.Success = false;
                                result.PrizeID = -1;
                                result.Message = "尚未设置奖品信息";
                            }
    View Code

    以上就是抽奖的整个流程,可以确保每次抽奖的概率都是跟设定的概率一样,并且所中的奖项不会大于后台设置的奖项个数

  • 相关阅读:
    安装MSSQL2008出现的问题记录
    制作安装包遇到的问题
    算法设计方法动态规划
    基础果然要牢记(一次失败的电面)
    搜狗垂搜笔试
    几种堆的时间复杂度分析
    正则表达式转NFA
    组合数学(1)
    算法设计方法贪心算法
    最短路径问题
  • 原文地址:https://www.cnblogs.com/SmilePastaLi/p/7229103.html
Copyright © 2011-2022 走看看