package rands import ( "math/rand/v2" "time" ) var ( rad = rand.New(rand.NewPCG(uint64(time.Now().Unix()), uint64(time.Now().UnixNano()))) ) // Choice 一个选项包含一个泛型项以及一个权重,该权重用于控制其被选中的频率 type Choice[W int | int32 | int64, T any] struct { Weight W Item T } // WeightedChoice 加权随机选择, 从所提供的选项中返回一个选项, 权重值为 0 的选项永远不会被选中 // Based on this algorithm: http://eli.thegreenplace.net/2010/01/22/weighted-random-generation-in-python/ func WeightedChoice[W int | int32 | int64, T any](choices []Choice[W, T], rd ...*rand.Rand) (ret Choice[W, T], ok bool) { sum := int64(0) for _, c := range choices { sum += int64(c.Weight) } crd := rad if len(rd) > 0 && rd[0] != nil { crd = rd[0] } r := crd.Int64N(sum) for _, c := range choices { r -= int64(c.Weight) if r < 0 { return c, true } } return }