我正在尝试编写此程序,该程序随机选择3个名称 选择名称后,每次弹出该名称时,该名称再次出现的可能性都会降低10%。
问题是,当我将for循环中的所有名称更改为一个名称时,我将所有内容更改为90%的名称,而将另外2个名称之一更改为10%。
String [] arr = new String[30];
int i; int b; int g;
for (i = 0; i < 11; i++)
{
arr[i] = "moshe";
}
for (b = 9; b < 20; b++)
{
arr[b] = "Nir";
}
for (g = 22; g < 29; g++)
{
arr[g] = "Yoad";
}
double letsdomath = Math.random()*arr.length; // Exp: return the no. 10 / 30 letsdomath = 10
if (letsdomath < 11) // if i get moshe
{
for (i = 0; i <= letsdomath - 1; i++)
{
arr[i] = "Nir"; // Originally it would be Moshe here
arr[i + 1] = "Nir";
}
}
if (letsdomath > 11 && letsdomath < 21) // if i get nir
{
for (b = 0; b <= letsdomath -1; b++)
{
arr[b] = "Nir";
arr[b + 1] = "Nir"; // Originally it would be Yoad here
}
}
if (letsdomath > 21 && letsdomath < 30) // if i get yoad
{
for (g = 0; g <= letsdomath -1; g++)
{
arr[g] = "Nir"; // Originally it would be Yoad here
arr[29] = "Nir"; // Originally it would be Moshe here
}
}
System.out.println(arr[(int) letsdomath]);
预期结果:
要使名字Nir每次弹出
实际结果:
Nir的名称会弹出90%〜,Yoad的名称会弹出10%〜。
答案 0 :(得分:1)
让我们重新回顾一下您想做的事情:为什么不将您所说的每件事实现为“我们可以做的事”,然后运行“尽可能多的迭代”,这些迭代只是按顺序进行?
例如,让我们从基础开始:
import java.util.*;
import java.lang.Math;
public class Test {
String[] names;
int len;
double[] probabilities, thresholds;
public static void main(String[] args) {
new Test();
}
public Test() {
init();
int steps = 5;
for (int i=0; i<steps; i++) {
// do the thing!
}
}
public void init() {
// set up a probability distribution
names = new String[]{"name1", "name2", "name3"};
len = names.length;
thresholds = new double[len];
probabilities = new double[len];
for (int i=0; i<len; i++) {
probabilities[i] = 1./len;
}
}
}
然后,我们确保有一种方法来查找概率阈值:如果概率为[0.4,0.3,0.3],则我们需要阈值[0,0.4,0.7],以便我们可以轻松地处理以下事实:随机数> = 0但<0.4应该解析为索引0,数字> = 0.4但<0.7应该解析为索引1,依此类推:
// turns [0.3, 0.4, 0.3] into [0, 0.3, 0.7]
public void setThresholds() {
double tally = 0;
for (int i=0; i<len; i++){
thresholds[i] = tally;
tally += probabilities[i];
}
}
然后,让我们根据选择的名称索引定义重新平衡概率的函数:
// turns [0.4, 0.3, 0.3] with pos=0 into [0.36, 0.32, 0.32]
public void updateProbabilities(int namePos) {
double sprinkle = (probabilities[namePos] * 0.1) / (len - 1.);
probabilities[namePos] *= 0.9;
for (int i=0; i<len; i++) {
if (i == namePos) continue;
probabilities[i] += sprinkle;
}
}
正确,完成所有设置后,我们现在就可以依靠这些功能按预期运行(当然应该验证),以更新public Test()
以运行一百万次更新并通过一次: / p>
public Test() {
init();
int steps = 5;
for (int i=0; i<steps; i++) {
setThresholds();
double randomValue = Math.random();
// find the associated name by finding the index of
// the threshold that is higher than our random value.
int namePos = findIndex(randomValue);
if (namePos == -1) {
namePos = names.length;
}
namePos--;
updateProbabilities(namePos);
// String name = names[namePos];
// System.out.println("step " + i + ": picked " + name + " (index " + namePos + ") based on " + randomValue);
// System.out.println("new probabilities: " + Arrays.toString(probabilities));
}
System.out.println("Final probabilities: " + Arrays.toString(probabilities));
}
public int findIndex(double randomValue) {
for (int i=0; i<len; i++) {
if (thresholds[i] > randomValue) return i;
}
return -1;
}
注释掉那些中间控制台日志,因为您当然不想看到一千个中介...除非您这样做。