gpt4 book ai didi

java - 名称结果与概率不匹配

转载 作者:行者123 更新时间:2023-12-02 09:41:38 25 4
gpt4 key购买 nike

我正在尝试编写这个程序,随机选择 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% 的时间出现。

最佳答案

让我们重新审视您对想要做的事情的描述:为什么不将您所说的每件事都实现为“我们可以做的事情”,然后运行“我们喜欢的尽可能多的迭代”,只需按顺序运行这些迭代?

例如,让我们从基础知识开始:

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() 来运行一百万次更新传递,依靠这些函数按我们的预期工作(您应该这样做,当然,请验证):

  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;
}

将这些中间控制台日志注释掉,因为您不想看到一千个中介......当然,除非您这样做。

关于java - 名称结果与概率不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57022267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com