抽奖问题分析
普通抽奖问题问题描述用户随机抽奖,数据如下: // map中,key代表用户名,value代表成用户下单数 var users map[string]int64 = map[string]int64{ "a": 10,"b": 6,"c": 3,"d": 12,"f": 1,} 思路随机问题,一般就是通过随机函数从某个范围内随机取出某个数值,则该数值对应的就是中奖用户 在这里,如果我们能给map中每个元素设置对应的索引,即转化为数组,是不是就可以解决问题了呢? 代码实现func GetAwardUserName(users map[string]int64) (name string) { size := len(users) awardIndex := rand.Intn(size) i := 0 for userName,_ := range users { if i == awardIndex { name = userName return } i++ } return } 单元测试func Test_GetAwardUserName(t *testing.T) { var users map[string]int64 = map[string]int64{ "a": 10,} rand.Seed(time.Now().Unix()) awardCount := make(map[string]int) for i := 0; i <= 1000000; i++ { awardName := GetAwardUserName(users) if count,ok := awardCount[awardName]; ok { awardCount[awardName] = count + 1 } else { awardCount[awardName] = 0 } } for n,c := range awardCount { fmt.Printf("%v:%vn",n,c) } } 测试结果:为了验证获奖概率的正确性,循环执行100万次,每个用户获奖的次数基本在20万左右,每个用户的获奖概率相等 c:200102 f:199853 b:198942 a:200395 d:200704 权重抽奖问题描述:数据结构和上面抽奖问题一致,只是这里,要求中奖概率和用户的订单数成正比 思路本质还是随机函数获得一个数值,数值对应的用户即获奖用户;这里要实现订单数对获奖概率的影响问题,即订单数对应随机数的某个范围,订单数越大,范围越大,随机数落在范围内的概率越大 代码实现func getAwardUser_weight(users map[string]int64) (name string) { userArr := make([]string,len(users),len(users)) var sumCount int64 = 0 index := 0 for n,c := range users { //整理所有用户的count数据为数轴 userArr[index] = n index++ sumCount += c } awardIndex := rand.Int63n(sumCount) var offset int64 for _,n := range userArr { //判断获奖index落在那个用户区间内 offset += users[n] if offset > awardIndex { name = n return } } return } 单元测试func Test_getAwardUser_weight(t *testing.T) { var users map[string]int64 = map[string]int64{ "a": 10,} rand.Seed(time.Now().Unix()) awardCount := make(map[string]int) for i := 0; i <= 100000; i++ { awardName := getAwardUser_weight(users) if count,c := range awardCount { fmt.Printf("%v:%v n",c) } } 测试结果:循环遍历了100万次,获奖的次数,与用户的订单数成正比 c:93479 f:31206 d:375614 b:186933 a:312764 总结解决实际问题,往往都有数学模型去对应,比如抽奖问题,就可以转化为初中所学习的数轴知识,画个草图,简单易理解,也不需要多高深的数学知识 问题本身并不难,重要的是转换思路,将抽象问题简化为具体的数学问题,然后去解决 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |