抽奖-随机加权算法

package lottery

import (
	"fmt"
	"math/rand"
	"sort"
	"time"
)

type Lottery struct {
}

func NewLottery() *Lottery {
	return &Lottery{}
}

type Prize struct {
	Name   string
	Stock  int
	Weight int //权重
}

// SortPrizes 按权重生序
func (l *Lottery) SortPrizes(prizes []Prize) {
	sort.Slice(prizes, func(i, j int) bool {
		return prizes[i].Weight < prizes[j].Weight
	})
}

// CreateWeightRanges 创建权重区间
func (l *Lottery) CreateWeightRanges(prizeList []Prize) []int {
	var weightRanges []int
	totalWeight := 0
	for _, item := range prizeList {
		totalWeight = item.Weight + totalWeight
		weightRanges = append(weightRanges, totalWeight)
	}
	return weightRanges
}

func (l *Lottery) DrawPrize(prizeList []Prize, weightRanges []int) string {

	//生成一个随机数
	//播种
	rand.Seed(time.Now().UnixNano())
	randNum := rand.Intn(weightRanges[len(weightRanges)-1])
	fmt.Println("随机数=", randNum)
	fmt.Println("权重slice=", weightRanges)
	for i, rangeNum := range weightRanges {
		if randNum < rangeNum {
			return prizeList[i].Name
		}
	}
	return ""
}

func TestDraw() {
	// 定义奖品信息及库存
	prizes := []Prize{
		{"一等奖 iPhone 16 Max", 1, 1},
		{"二等奖 iPad", 1, 1},
		{"三等奖 苹果耳机", 1, 1},
		{"四等奖 红米手机", 5, 4},
		{"五等奖 苹果手机充电器", 10, 5},
		{"六等奖 红牛", 20, 8},
		{"七等奖 矿泉水", 20, 10},
		{"八等奖 微信10元立减金", 30, 12},
		{"九等奖 微信3元立减金", 30, 14},
	}
	p := NewLottery()
	p.SortPrizes(prizes)
	weightRanges := p.CreateWeightRanges(prizes)
	for i := 0; i < 1; i++ {
		result := p.DrawPrize(prizes, weightRanges)
		fmt.Printf("抽中奖品:%s\n", result)
	}
}

  权重值约大,中奖概率越大。逻辑是控制随机数落到每个奖品的范围概率。

posted @ 2024-11-15 15:44  今天滴天气不错  阅读(15)  评论(0编辑  收藏  举报