三角数组中随机数偏置的数学方法
这个问题是Java- Math.random(): Selecting an element of a 13 by 13 triangular array的延伸。我随机选择了两个数字(包括0-12),我希望这些值相等
但现在,由于这是一个乘法游戏,我想找到一种方法来偏向结果,以便某些组合出现得更频繁(比如如果玩家在12x8上表现更差,我希望它出现得更频繁)。最后,我想偏向91种组合中的任何一种,但一旦我把这一点记下来,那就不难了
我的想法是:在三角形数字上加上一些int n
,然后Random.nextInt(91 + n)
使结果偏向于一个组合
private int[] triLessThan(int x, int[] bias) { // I'm thinking a 91 element array, 0 for no bias, positive for bias towards
int i = 0;
int last = 0;
while (true) {
int sum = 0;
for (int a = 0; a < i * (i + 2)/2; a++){
sum += bias[a]
}
int triangle = i * (i + 1) / 2;
if (triangle + sum > x){
int[] toReturn = {last,i};
return toReturn;
}
last = triangle;
i++;
}
}
在随机数字滚动时:
int sum = sumOfArray(bias); // bias is the array;
int roll = random.nextInt(91 + sum);
int[] triNum = triLessThan(roll);
int num1 = triNum[1];
int num2 = roll - triNum[0]; //now split into parts and make bias[] add chances to one number.
sumOfArray只找到和(这个公式很简单)。这样行吗
编辑:使用Floris的想法:
随机数字滚动:
int[] bias = {1,1,1,...,1,1,1} // 91 elements
int roll = random.nextInt(sumOfBias());
int num1 = roll;
int num2 = 0;
while (roll > 0){
roll -= bias[num2];
num2++;
}
num1 = (int) (Math.sqrt(8 * num2 + 1) - 1)/2;
num2 -= num1 * (num1 + 1) / 2;
# 1 楼答案
你已经知道如何将一个介于0和91之间的数字转换成一个滚动(从上一个问题的答案开始)。我建议您创建一个由N个元素组成的数组,其中N>>;91.用0填充前91个元素。。。90,并将计数器
A
设置为91。现在选择一个介于0和a之间的数字,从数组中选择相应的元素,并转换为乘法问题。如果答案是错误的,则将问题的编号附加到数组的末尾,并将A
增加1这将创建一个数组,其中采样频率将表示错误解决问题的次数,但如果下次问题得到正确解决,则不会再次降低频率
另一种更好的解决方案是,与您的解决方案更接近一点(但不同),它创建了一个91个频率的数组,每个频率最初设置为1,并跟踪总和(最初为91)。但是现在,当你选择一个随机数(介于0和和之间)时,你会遍历数组,直到累积和大于你的随机数——箱子的数量就是你选择的滚动,你可以用前面推导的公式来转换它。如果答案是错误的,则增加bin并更新总和;如果它是正确的,您可以减少总和,但决不能减少到小于1的值,并更新总和。重复一遍
这应该给出你想要的东西:给定一个91个数字的数组(“箱子”),随机选择一个箱子,这样箱子的概率与里面的值成正比。返回bin的索引(可以使用之前的方法将其转换为数字的组合)。调用此函数时,bin(frequency)数组作为第一个参数,累积和作为第二个参数。查找前n个元素的累积和首先超过由频率之和缩放的随机数的位置:
我确认它给了我一个直方图(蓝色条),看起来和我输入的概率分布完全一样(红线):
(注意:这是用matlab绘制的,因此X从1到91,而不是从0到90)
下面是另一个想法(这并不能真正回答这个问题,但可能更有趣):
你可以通过抽样而不是均匀分布来改变你选择某个特定问题的概率。例如,均匀抽样随机变量的平方将有利于较小的数字。这给了我们一个有趣的可能性:
首先,将91个数字随机排列
接下来,从非均匀分布中选择一个数字(倾向于较小的数字)。由于这些数字是随机排列的,事实上,它们被选中的可能性是相同的。但现在有一个诀窍:如果问题(由选择的数字表示)得到了正确解决,则将问题编号“移动到堆栈顶部”,在该位置再次选择的可能性最小。如果玩家搞错了,它会被移动到堆栈的底部,在那里很可能再次被选中。随着时间的推移,困难的问题会转移到最底层
可以使用以下变量创建具有不同倾斜度的随机分布:
当
a
接近1时,函数倾向于支持较低的数字,而较高数字的概率几乎为零:我相信以下代码部分符合我的描述: