前提:设置了奖项内容,中奖概率,奖项个数
算法结构:
算法的具体实现:
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; } } } }
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; } } } }
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; } } } }
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; } } }
抽奖事件:

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 = "尚未设置奖品信息"; }
以上就是抽奖的整个流程,可以确保每次抽奖的概率都是跟设定的概率一样,并且所中的奖项不会大于后台设置的奖项个数