Saber 酱的抱枕

Fly me to the moon

04/16
2019
学习

JavaScript 按概率选择项目

今天看到的一个算法,挺有意思。

假设有五个选项,在 100 个人里,有 8 个人选择第一项,22 个人选择第二项,26 个人选择第三项,26 个人选择第四项,18 个人选择第五项。如何用程序模拟?

先按照顺序把每个选项的概率保存到数组:[8, 22, 26, 26, 18],然后生成一个 100 以内的随机数,依次减去每个数字,当结果小于 0 时,就选择当前这个选项。

var a = [8, 22, 26, 26, 18]	// 5 个选项,每个的概率
var r = [0, 0, 0, 0, 0]	// 统计结果
for (let i = 0; i < 10000; i++) {	// 测试 10000 次
	let random = Math.random() * 100	// 生成随机数。如果概率之和不是 100,那么这里的 100 要换成概率之和
	for (let j = 0; j < 5; j++) {
		random -= a[j]	// 随机数依次减去概率
		if (random < 0) {	// 当随机数小于 0 时,选择当前选项
			r[j]++
			break
		}
	}
}
console.log(r)

经过上面的 demo 验证,结果符合预期。

JavaScript 按概率选择项目

JavaScript 按概率选择项目

  1. locationiskey
    Microsoft EdgeMicrosoft EdgeWindowsWindows

    噢,原来是“依次减去每个数字”……我说呢

    其实就是把100人分成8, 22, 26, 26, 18这么5组,给所有人编个号,号码<8的(从0开始#滑稽)是一个,去掉后号码<8+22的是一个,下同(在高中概率题解里这叫隔板法)

    随机性从哪来?这100人的编号是随机的

    随机算法其实挺好玩的(指看别人做自己猜想法

    回复
      1. 火狐狸先生
        Firefox 66Firefox 66WindowsWindows

        啊不是这个意思(`・ω・´)
        我想的是一种比较像数组随机重排的随机,或者说100个人一定要分成20x5共五组,求每个人分别到哪。如果单纯的随机数/人数的话一个人可能会同时在两个地方,或者每组人数不是恰好20。
        老实讲我遇到数组随机重排问题都是疯狂遍历到O(N^2)的(′・_・`)
        另外单就这篇文章提到的随机数模拟(姑且这么叫),给定分布的连续随机数也有很多精彩的生成方法,不过感觉除了物理化学什么的之外很少有地方会用就是了……

        回复