这个问题是Java-Math.random()的扩展:选择13×13三角形数组的元素。我随机选择两个数字(包括 0-12),我希望这些值相等。
但现在,由于这是一个乘法游戏,我希望有一种方法来偏置结果,以便某些组合出现得更频繁(比如,如果玩家在12x8时表现得更差,我希望它出现得更频密)。最终,我想偏向于91种组合中的任何一种,但一旦我把这一点写下来,那就不难了。
我的想法:添加一些int n
到三角形数和Random.nextInt(91n)
以将结果偏向组合。
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只是找到总和(这个公式很简单)。这行得通吗?
编辑:使用弗洛里斯的想法:
在随机数字滚动中:
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;
你已经知道如何将一个0到91之间的数字转换成一个卷(从上一个问题的答案)。我建议您创建一个由N个元素组成的数组,其中N
这将创建一个数组,其中采样频率将表示问题被错误解决的次数,但如果问题在下一次被问及时被正确解决,则不会再次降低采样频率。
另一种更好的解决方案,一个更接近您的(但不同的)的解决方案,创建一个包含 91 个频率的数组 - 每个频率最初设置为 1 - 并跟踪总和(最初为 91)。但是现在,当您选择一个随机数(介于 0 和总和之间)时,您将遍历数组,直到累积总和大于您的随机数 - bin 的数字是您选择的滚动,并使用之前派生的公式进行转换。如果答案是错误的,则增加箱并更新总和;如果正确,则递减总和,但从不递减到小于 1 的值,然后更新总和。重复。
这应该能准确地告诉你你在问什么:给定一个91个数字(“bin”)的数组,随机选择一个bin,使该bin的概率与其中的值成比例。返回bin的索引(可以使用以前的方法将其转换为数字的组合)。调用此函数时,bin(频率)数组作为第一个参数,累积和作为第二个参数。您可以查找前n个元素的累积和首先超过按频率之和缩放的随机数的位置:
private int chooseBin(float[] freq, float fsum) {
// given an array of frequencies (probabilities) freq
// and the sum of this array, fsum
// choose a random number between 0 and 90
// such that if this function is called many times
// the frequency with which each value is observed converges
// on the frequencies in freq
float x, cs=0; // x stores random value, cs is cumulative sum
int ii=-1; // variable that increments until random value is found
x = Math.rand();
while(cs < x*fsum && ii<90) {
// increment cumulative sum until it's bigger than fraction x of sum
ii++;
cs += freq[ii];
}
return ii;
}
(注意——这是用matlab绘制的,所以X从1到91,而不是从0到90)。
这是另一个想法(这并没有真正回答这个问题,但它可能更有趣):
你可以通过抽样而不是均匀分布来歪曲你选择一个特定问题的概率。例如,均匀抽样随机变量的平方将有利于较小的数字。这给了我们一个有趣的可能性:
首先,把你的91个数字随机排列
接下来,从非均匀分布中挑选一个数字(倾向于较小的数字)。由于这些数字是随机打乱的,事实上它们被选中的可能性是相等的。但现在这里有一个窍门:如果问题(由挑选的数字表示)被正确解决,你将问题数字移动到“堆栈的顶部”,在那里它最不可能被再次选择。如果玩家选错了,它会被移到堆栈的底部,在那里它最有可能被再次选中。随着时间的推移,困难的问题转移到堆栈的底部。
您可以使用
roll = (int)(91*(asin(Math.rand()*a)/asin(a)))
当您使a
更接近1时,该函数倾向于支持较低的数字,而较高数字的概率几乎为零:
我相信以下代码部分可以实现我所描述的功能:
private int[] chooseProblem(float bias, int[] currentShuffle) {
// if bias == 0, we choose from uniform distribution
// for 0 < bias <= 1, we choose from increasingly biased distribution
// for bias > 1, we choose from uniform distribution
// array currentShuffle contains the numbers 0..90, initially in shuffled order
// when a problem is solved correctly it is moved to the top of the pile
// when it is wrong, it is moved to the bottom.
// return value contains number1, number2, and the current position of the problem in the list
int problem, problemIndex;
if(bias < 0 || bias > 1) bias = 0;
if(bias == 0) {
problem = random.nextInt(91);
problemIndex = problem;
}
else {
float x = asin(Math.random()*bias)/asin(bias);
problemIndex = Math.floor(91*x);
problem = currentShuffle[problemIndex];
}
// now convert "problem number" into two numbers:
int first, last;
first = (int)((Math.sqrt(8*problem + 1)-1)/2);
last = problem - first * (first+1) / 2;
// and return the result:
return {first, last, problemIndex};
}
private void shuffleProblems(int[] currentShuffle, int upDown) {
// when upDown==0, return a randomly shuffled array
// when upDown < 0, (wrong answer) move element[-upDown] to zero
// when upDown > 0, (correct answer) move element[upDown] to last position
// note - if problem 0 is answered incorrectly, don't call this routine!
int ii, temp, swap;
if(upDown == 0) {
// first an ordered list:
for(ii=0;ii<91;ii++) {
currentShuffle[ii]=ii;
}
// now shuffle it:
for(ii=0;ii<91;ii++) {
temp = currentShuffle[ii];
swap = ii + random.nextInt(91-ii);
currentShuffle[ii]=currentShuffle[swap];
currentShuffle[swap]=temp;
}
return;
}
if(upDown < 0) {
temp = currentShuffle[-upDown];
for(ii = -upDown; ii>0; ii--) {
currentShuffle[ii]=currentShuffle[ii-1];
}
currentShuffle[0] = temp;
}
else {
temp = currentShuffle[upDown];
for(ii = upDown; ii<90; ii++) {
currentShuffle[ii]=currentShuffle[ii+1];
}
currentShuffle[90] = temp;
}
return;
}
// main problem posing loop:
int[] currentShuffle = new int[91];
int[] newProblem;
int keepGoing = 1;
// initial shuffle:
shuffleProblems( currentShuffle, 0); // initial shuffle
while(keepGoing) {
newProblem = chooseProblem(bias, currentShuffle);
// pose the problem, get the answer
if(wrong) {
if(newProblem > 0) shuffleProblems( currentShuffle, -newProblem[2]);
}
else shuffleProblems( currentShuffle, newProblem[2]);
// decide if you keep going...
}
问题内容: 我正在创建一个测验,每当我开始测验时,我都希望将问题打乱,以免每次出现时都不会以相同的顺序出现。 我在我的html代码中有这个: 这在我的控制器中 不幸的是,这根本没有用。希望有人可以帮助我吗? 问题答案: 谢谢 http://bost.ocks.org/mike/shuffle/ 使用此改组功能: 它的特殊之处在于,输入数组保持可绑定性,因为改组不会创建新的数组,而是 对同一引用 执
嗨,伙计们,我有这个阵列,可以打印5x5 1 我想做的是随机地将这些1中的三(3)个设为0。实例 我该怎么做?提前感谢您!
编辑:这个问题解决了。如果您想在另一个问题上提供帮助,请访问Java偏置三角形数组中的随机数。 我在做一个乘法游戏,所以我选了两个0到12之间的数字。如果我这样做: 正方形(0x0、1x1、2x2等)的拾取时间为一半(因为1x2与2x1相同)。如何使所有组合以相同的频率拾取?有91种可能的组合(n(n1)/2)。如果有帮助的话,这里有一个13乘13的三角形阵列: 我试着选择第一个数字,然后给第二个
问题内容: 我想尝试一个直角三角形的星号。但是我只得到以下 输出:( 我不能在这里放置星号) 我想要的是这样的: 这是我编写的代码: 任何想法分享,我们将不胜感激。我是Java新手。谢谢。 问题答案: 您的代码从不打印任何空格,这应该是一个问题。 您可以使用以下简单方法: 逻辑很简单:您的字符串带有两个空格和三个at符号。输出的第一行必须是两个空格和一个at符号,因此这是字符串的前三个字符。第二行
问题内容: 在Java中,如何生成随机数,但如何使该随机数偏向特定数字。例如,我想生成一个介于1到100之间的数字,但是我希望该数字偏向75。但是我仍然希望能够获得该范围内的其他数字,但是我希望获得数字的更多变化接近75,而不是仅仅获得整个范围内的随机数。谢谢 问题答案: 尝试http://download.oracle.com/javase/6/docs/api/java/util/Random
问题内容: 当他每次运行程序时都不断获得相同的数字时,我试图向Java解释随机数生成器。我为同一件事创建了自己的简单版本,每次运行该程序时,我也得到了与他得到的确切数字相同的数字。 我究竟做错了什么? 100个数字中的最后五个数字是: 问题答案: 您已经为随机数生成器提供了恒定的值。它是确定性的,因此每次运行都会生成相同的值。 我不确定您为什么选择使用作为种子,但是种子值与生成的值范围无关(这是由