我想从一个集合中选择一个随机项目,但是选择任何项目的机会应该与相关的权重成比例
示例输入:
item weight
---- ------
sword of misery 10
shield of happy 5
potion of dying 6
triple-edged sword 1
Run Code Online (Sandbox Code Playgroud)
所以,如果我有4个可能的项目,那么获得任何一个没有权重的项目的机会将是1/4.
在这种情况下,用户获得痛苦之剑的可能性应该是三角剑的10倍.
如何在Java中进行加权随机选择?
因此,假设我们有一个代码块,我们希望执行70%的次数,另一次执行30%的代码.
if(Math.random() < 0.7)
70percentmethod();
else
30percentmethod();
Run Code Online (Sandbox Code Playgroud)
很简单.但是如果我们希望它可以很容易地扩展到30%/ 60%/ 10%等怎么办?在这里,它需要添加和更改所有关于变化的if语句,这些语句不是很好用,慢和错误诱导.
到目前为止,我发现大型交换机对于这个用例非常有用,例如:
switch(rand(0, 10)){
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:70percentmethod();break;
case 8:
case 9:
case 10:30percentmethod();break;
}
Run Code Online (Sandbox Code Playgroud)
哪个可以很容易地改为:
switch(rand(0, 10)){
case 0:10percentmethod();break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:60percentmethod();break;
case 8:
case 9:
case 10:30percentmethod();break;
}
Run Code Online (Sandbox Code Playgroud)
但是这些也有它们的缺点,很麻烦并且分成预定量的分区.
理想的东西将基于我想的"频率数"系统,如下所示:
(1,a),(1,b),(2,c) -> 25% a, 25% b, 50% c
Run Code Online (Sandbox Code Playgroud)
然后,如果你添加另一个:
(1,a),(1,b),(2,c),(6,d) -> 10% a, 10% b, 20% …Run Code Online (Sandbox Code Playgroud) 比方说,我得到了号码3.然后我必须选择0到3之间的随机数,但是0的选择概率大于1,1选择的概率大于2,而2选择的概率大于3.
我已经知道,通过执行以下操作可以实现从0到3选择特定数字的百分比机率:
double r = Math.random();
int n = 0;
if (r < 0.5) {
n = 0;
// 50% chance of being 0
} else if (r < 0.8) {
n = 1;
// 30% chance of being 1
} else if (r < 0.95) {
n = 2;
// 15% chance of being 2
} else {
n = 3;
// 5% chance of being 3
}
Run Code Online (Sandbox Code Playgroud)
问题在于它3可以是任何东西.我怎样才能做到这一点?
注意:数字0.5,0.8和0.95由我任意选择.我希望这些数字减少,以便所有数字的总和等于1,并且如果在某种程度上可能的话,它们都不相同.
我想从3-10或4-6等范围中选择一个随机数.应该选择数字,使得数字越低,选择的机会就越多.我下面的代码只选择具有相同概率的每个数字.
private int bonusPoints;
private double randomBonusPoints = Math.Random() * 100;
bonusPoints = (int)randomBonusPoints;
Run Code Online (Sandbox Code Playgroud)
如何从分布中选择P(3,4,5)=85%, P(6,7,8)=10%, P(9,10)=5%?