Android:随机数不是很随机

时间:2013-11-01 17:54:24

标签: java android random

我正在为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);
  }
}

以下是测试结果:enter image description here

也许,当N = 10000时,它将是平等的...但对于我的应用来说,这是一个糟糕的安慰。

4 个答案:

答案 0 :(得分: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  + "%");
        }

答案 1 :(得分:1)

不要使用

Random rnd = new Random();

每次你想要一个号码。使rnd成为更广泛的范围变量(实例,类等),然后运行一次以初始化它。

然后你只需使用

int whatever = rnd.nextInt(WordsNumber);

当你想要一个新号码时。

创建new Random()时,它会将种子设置为当前时间初始化新的PRNG。如果自上次调用之后时间没有改变,您将得到相同的数字序列。

答案 2 :(得分:0)

首先,您可以查看此问题:

Getting random numbers in Java

并且可以查看Math.random课程。

其次,在一小部分选择中,随机可以返回一个数字,而不是其他数字。 但是,如果测试规模足够大,它应该更均匀地传播。

答案 3 :(得分:0)

Geobits提出的shuffling algorithm是一个很好的解决方案。

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