You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
37 lines
943 B
37 lines
943 B
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 |
|
}
|
|
|