在开发中,经常遇到一个需求,给一些事件,并指定这些事件出现的概率。例如:A:10%,B:20%, C:30%,D:40%
按照事件的概率随机选择一个其中一个事件。
实现思路:
根据大学概率论所学的知识(啥,概率论课你睡觉了,我也睡觉了。那就我吹你听吧),这是一个典型的均匀分布问题。不扯那些复杂的公式了,我的概率论知识也差不多都还给老师了,直接画图来解释一下。
图中,A,B,C,D四种颜色画出了四个事件出现的概率,也就是在[0,100]数轴上所占的长度。只要我们在[0-100]中取一个随机数,看这个随机数落在A,B,C,D哪个区间中,就取哪个事件。
用代码实现一下,现在主要写golang,先用golang实现一下:
package main
import (
"fmt"
"math/rand"
)
func main() {
b := make(map[uint32]int32)
b[0] = 10
b[1] = 20
b[2] = 30
b[3] = 40
h2 := make([]int, 4)
for x := 0; x < 200000000; x++ {
r := rand.Int31n(99)
i, j := int32(0), int32(0)
for k, v := range b {
j = i + v - 1
if r >= i && r <= j {
h2[k]++
break
}
i += v
}
}
for _, b := range h2 {
fmt.Print(float32(b)/2000000, " ")
}
}
顺便统计了一下事件的概率,为了结果更真实一些,循环了2亿次,这个数据量基本可以比较真实的显示随机性了。
运行结果:
结果已经非常接近我们期待的概率了
java版:
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Map<Integer, Integer> m = new HashMap<>();
m.put(0, 10);
m.put(1, 20);
m.put(2, 30);
m.put(3, 40);
int[] h2 = new int[4];
for (int i = 0; i < h2.length; i++) {
h2[i] = 1;
}
Random random = new Random();
for (int x = 0; x < 200000000; x++) {
int i = 0;
int j = 0;
int r = random.nextInt(99);
for (Map.Entry<Integer, Integer> entry : m.entrySet()) {
j = i + entry.getValue() - 1;
if (r >= i && r <= j) {
h2[entry.getKey()]++;
break;
}
i += entry.getValue();
}
}
for (int i : h2) {
System.out.printf("%f ", i / 2000000.0);
}
}
}
运行结果也比较接近期待值
网友评论