最近在写一个自动答题软件,在答题的时候,每个选项的选择的概率需要可控,想了一会儿没有想通!
于是在网上搜索解决思路,其中有一条思路描述得比较好:
把random出来的随机数当成概率,看这个概率落在选项的哪个区间就行了!
于是,我这里就简单的实现了一版typescript版本的指定概率选择其中一项,见代码
实现代码
/**
* 根据设置的比例,随机返回其中一项
* @param {{ratio:number,label:string}[]} itemsN n个选项
* @returns {typeof itemsN[number]} 返回itemsN其中的一项
*/
const random_select:(itemsN:{ratio:number,label:string}[]) => typeof itemsN[number] = (itemsN)=>{
// 1.判断下各选项的概率之和是否为1
if(itemsN.reduce((pre,curr)=> ({ratio:((pre.ratio||0)+(curr.ratio||0)),label:''})).ratio!==1) return {
ratio:0,
label:'错误!概率相加必须等于1'
}
// 2.核心实现
const ratio = Math.random()
let start = 0;
for (let index = 0; index < itemsN.length; index++) {
const element = itemsN[index];
if(ratio>=start && ratio<start+element.ratio){
return element
}
start = start+element.ratio
}
// 3.未生成时,此处报错
return {
ratio:0,
label:'错误!未选择到元素'
}
}
验证一下
验证思路很简单:
- 指定N个选项,这里指定了6个选项,以及各个选项的概率
- 定义一个变量,存储各选项出现的次数
- 将random_select执行10万次,并统计次数
- 打印最终各选项的统计次数
下面是验证的代码:
// 1.指定N个选项,这里指定了6个选项,以及各个选项的概率
const itemsN = [
{ratio:0.2,label:'A'},
{ratio:0.2,label:'B'},
{ratio:0.25,label:'C'},
{ratio:0.1,label:'D'},
{ratio:0.05,label:'E'},
{ratio:0.2,label:'F'},
];
// 2. 定义一个变量,存储各选项出现的次数
const counts = {
A:0,
B:0,
C:0,
D:0,
E:0,
F:0
}
// 3. 将random_select执行10万次,并统计次数
for (let index = 0; index < 100000; index++) {
const select = random_select(itemsN)
if(typeof counts[select.label as keyof typeof counts]!==undefined) counts[select.label as keyof typeof counts]+=1
}
// 4. 打印最终的统计次数
console.log(counts)
最终得到的结果如下:
通过结果,我们可以看出:
- A、B、F选项,与我们设置的0.2非常接近;
- C选项,与0.25很接近;
- D选项,与0.1很接近;
- E选项,与0.05很接近;
与我们指定的概率,完全稳合,并且10万次执行之后没有抛异常!
验证通过,需要代码的朋友,自己复制吧!
觉得有用,还请点赞收藏!
励志前端,CSDN唯一账号!关注我,带你了解更多前端知识!