3

我正在为 android 编写一个单词学习应用程序。

要获得随机单词,我使用:

Random rnd = new Random();
final int rnd.nextInt(WordsNumber);

要获得随机方向(显示单词或显示翻译),我使用:

Random rnd = new Random();
final boolean dir.nextBoolean();

但我看到,一个词不是均匀分布的。我正在用 17 个单词测试应用程序。有些单词显示 10 次,有些单词只显示一次。同样的问题是方向。它经常发生,连续第五次方向是相同的。

也许有人知道,如何使单词的分配更加平等?

UPD:我写了一个测试应用程序。它在按钮单击时生成新数字:

public class About extends Activity
{
  final int N = 10;
  int[] results;
  Random rnd;
  int total;

  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_about);

    results = new int[N];
    for (int i = 0; i < N; i++)
    {
      results[i] = 0;
    }

    rnd = new Random();
    total = 0;
  }

  public void GenerateNumber(View view)
  {
    int number = rnd.nextInt(N);
    results[number]++;
    total++;

    String output = new String();
    TextView txt = (TextView)findViewById(R.id.text1);

    output += "Total numbers: " + String.valueOf(total) + "\n";
    for (int i = 0; i < N; i++)
    {
      output += String.valueOf(i) + ": " + String.valueOf(results[i]) + "\n";
    }
    txt.setText(output);
  }
}

以下是测试结果:在此处输入图像描述

也许,当 N=10000 时,它会是相等的……但对于我的应用程序来说,这是一个糟糕的安慰。

4

3 回答 3

2

你所做的应该会给你非常均匀的伪随机分布。
例如,您可以运行 1000 次采样并计算每个结果最终出现的频率。它应该大致相同。否则,请发布更多导致问题的代码。

更新 要说服自己,请尝试在您的平台上运行下面的简单测试并检查观察到的结果。越大testNum,您得到的结果就越均匀。

        final int testNum = 10000;
        final int max = 9; // will generate integers in range [0 ; 9]
        Random rnd = new Random();
        int[] results = new int[max + 1];

        for (int i = 0; i < testNum; ++i) {
           int nextRandomNumber = rnd.nextInt(max + 1);
           results[nextRandomNumber]++;
        }

        // print statistics
        System.out.println("tests performed = " + testNum);
        for (int i = 0; i <= max; ++i) {
            System.out.println("frequency of " + i + " is " 
                + results[i] * 100 / testNum  + "%");
        }
于 2013-11-01T18:00:02.310 回答
1

不要使用

Random rnd = new Random();

每次你想要一个数字。创建rnd一个范围更广的变量(实例、类等),然后运行一次来​​初始化它。

然后你只需使用

int whatever = rnd.nextInt(WordsNumber);

当你想要一个新号码时。

创建 时new Random(),它会初始化一个新的 PRNG,并将种子设置为当前时间。如果自上次调用以来时间没有改变,您将获得相同的编号序列。

于 2013-11-01T18:17:12.637 回答
0

Geobits 提出的洗牌算法是一个很好的解决方案。

但这是更简单的方法。我决定做一些最近的话。存储 6-8 个遗言就足以解决此问题。

于 2013-11-28T20:56:52.893 回答