golang随机概率的权重抽奖实现
package main
import (
"encoding/json"
"fmt"
"math"
"math/rand"
"sort"
"time"
)
type Prize struct {
PlayerId int64
Weight int
}
func main() {
//设置奖项名称、权重等数组
var prizes = make([]*Prize, 0)
for i := 0; i < 4; i++ {
prize := &Prize{
PlayerId: int64(i) + 10000,
Weight: (5 - i) * 10,
}
prizes = append(prizes, prize)
}
for _, v := range prizes {
fmt.Println(v.PlayerId, v.Weight)
}
RandomDraw(prizes)
}
// 权重随机抽奖
func RandomDraw(prizes []*Prize) int64 {
//权重累加求和
var weightSum int
for _, v := range prizes {
weightSum += v.Weight
html实现用户注册登录代码}
//⽣成⼀个权重随机数,介于0-weightSum之间
rand.Seed(time.Now().UnixNano())
randomNum := rand.Intn(weightSum)
//权重数组重组并排序
randomNumTmp := &Prize{PlayerId: -1, Weight: randomNum}
concatWeightArr := make([]*Prize, 0)
aa, _ := json.Marshal(prizes)
_ = json.Unmarshal(aa, &concatWeightArr)
fmt.Println("concatWeightArr:", concatWeightArr)
concatWeightArr = append(concatWeightArr, randomNumTmp) //将随机数加⼊权重数组
//将包含随机数的新权重数组按从⼩到⼤(升序)排序
sort.Slice(concatWeightArr, func(i, j int) bool {
return concatWeightArr[i].Weight < concatWeightArr[j].Weight
})
sort.Slice(prizes, func(i, j int) bool {
return prizes[i].Weight < prizes[j].Weight
})
for _, v := range prizes {
fmt.Println(*v)
}
//索引权重随机数的数组下标
var randomNumIndex = -1 //索引随机数在新权重数组中的位置
for p, v := range concatWeightArr {
if v.Weight == randomNum {
randomNumIndex = p
}
}
randomNumIndexTmp := math.Min(float64(randomNumIndex), float64(len(prizes)-1)) //权重随机数的下标不得超过奖项数组的长度-1,重新计算随机数在奖项数组中的索引位置 randomNumIndex = int(randomNumIndexTmp)
//取出对应奖项
res := prizes[randomNumIndex] //从奖项数组中取出本次抽奖结果
fmt.Println("本次抽奖结果:", res.PlayerId)
return res.PlayerId
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论