随机数生成器

3

我需要用Java编写一个程序,使用公式生成范围在 [0,1] 内的随机数:

Xi = (aXi-1 + b) mod m

假设 a、b 和 m 是固定的整数值,而 X0 = 0.5(即 i=0)。

我该如何着手实现呢?

我尝试过下面的代码,但显然是错误的:

int a = 25173, b = 13849, m = 32768;
double X_[i];
for (int i = 1; i<100; i++)
   X_[i] = (a*(X_[i]-1) + b) % m;
double X_[0] = 0.5;
double double = new double();
System.out.println [new double];
6个回答

8
以下是一些提示:
int a, d, m, x;

乘法是*,取模是%

更新

好的,我会给你一个更明显的提示。你只需要一个变量,不需要所有这些数组;因为你只使用整数,所以不需要任何浮点数或双精度浮点数。

重要的代码行将是

x = (a * x + b) % m ;

你不需要再加上另一个x,因为等号右边的x是旧的xxi-1;左边的那个将会是你的“新”xxi

现在,从这里开始,你需要编写Java包装器,让它变成一个方法,这意味着要写一个


4
听起来像是作业...所以我不会给你一个代码解决方案。
无论如何,你需要一个线性同余发生器
提示:你需要将那个数学公式写成一个函数。
步骤:
1.创建一个类。
2.将所需状态作为类的成员添加进去。
3.在类中编写一个函数。根据需要进行输入。
4.用Java编写同余发生器的公式(查找Java中的数学运算)。
5.返回结果。
我的Java已经有点生疏了,所以我不能确定这些是否错误。
int a = 25173, b = 13849, m = 32768;
double X_[i];//You need to define a constant array or use perhaps a list, you can't use i without defining it
for (int i = 1; i<100; i++)
   X_[i] = (a*(X_[i]-1) + b) % m;
double X_[0] = 0.5;
double double = new double(); //You can't name a variable double, also types like double, don't need to be newed (I think)
System.out.println [new double]; //println uses () not [], in Java I think all functions need to use (), its not implied

谢谢,但我不需要代码,我是Java的新手,我需要知道要遵循哪些步骤。 - Bongers
1
不要使用2,现在我不知道你需要遵循两个步骤还是需要知道要遵循哪些步骤。 - Robert Gould
@Robert Gould,请修改您最后一句话。除非我误解了什么,否则我不明白它的相关性在哪里。 - strager
再次感谢罗杰特,我会写一个“hello world”程序,我实际上也写了一些无法运行的代码,出现了太多错误(我不会使用2个)。不过我会继续尝试的。 - Bongers
考虑到所有因素,这是可能的。 - Robert Gould
显示剩余5条评论

1
线性同余生成器基本上是一个表达式,它修改给定的值以产生系列中的下一个值。它的形式如下:
xi+1 = (a.xi + b) mod m
正如你已经指定的(稍微有些不同:我被教导总是把 xi+1 放在左边,25年后我仍然害怕我的数学老师:-)),其中 abm 的值是经过精心选择的,以给出一个合理的值范围。请注意,使用 mod 运算符,你将始终得到一个介于 0m-1 之间的值。
还要注意,这些值往往是整数而不是浮点数,所以如果按照你的要求,你需要一个在 0-0.999... 范围内的值,你需要将整数值除以 m 来获得这个值。
在解释了它的工作原理之后,这里有一个简单的 Java 程序,使用你问题中的 abm 值来实现它:
public class myRnd {
    // Linear congruential values for x(i+1) = (a * x(i) + b) % m.
    final static int a = 25173;
    final static int b = 13849;
    final static int m = 32768;

    // Current value for returning.
    int x;

    public myRnd() {
        // Constructor simply sets value to half of m, equivalent to 0.5.
        x = m / 2;
    }

    double next() {
        // Calculate next value in sequence.
        x = (a * x + b) % m;

        // Return its 0-to-1 value.
        return (double)x / m;
    }

    public static void main(String[] args) {
        // Create a new myRnd instance.
        myRnd r = new myRnd();

        // Output 20 random numbers from it.
        for (int i = 0; i < 20; i++) {
            System.out.println (r.next());
        }
    }   
}

这里是输出结果,不管怎样看起来都很随机 :-).

0.922637939453125
0.98748779296875
0.452850341796875
0.0242919921875
0.924957275390625
0.37213134765625
0.085052490234375
0.448974609375
0.460479736328125
0.07904052734375
0.109832763671875
0.2427978515625
0.372955322265625
0.82696533203125
0.620941162109375
0.37451171875
0.006134033203125
0.83465576171875
0.212127685546875
0.3128662109375

1

编辑:

  1. [ ]是特殊符号,如果你想让你的变量名为“X_[ i ]”,那是行不通的。如果你想创建一个数组,那么你正在把它变得太复杂了。

  2. 你需要确定原方程是Xi - 1还是X(i-1),因为这在你的编程中有很大的区别。Xi - 1只比Xi少1。X(i-1)是前一个随机数。

  3. 尝试在网上做一些初学者Java教程。这里是一个很好的开始。在继续解决问题之前,真正努力理解教程。

  4. 从这个角度考虑你的问题。[假设方程是X(i-1)]要生成第三个随机数X3,你需要生成X2,而X2需要X1,X1需要X0。但是你有X0。所以对于任何Xi,都从X0开始,生成X1,然后生成X2,依此类推,直到Xi。

你可能不需要像我一开始建议的那样深入研究递归


我真的很怀疑。你只需要在类中保持状态,递归可能是下周的作业。 - Robert Gould
好的,这个函数处理Xi和Xi-1以及X0的基本情况。如果我是一位教授,这可能就是我介绍递归的方式。 - Perchik
@Perchik,我认为使用循环更好解决这个问题。想一下阶乘的递归实现方式。递归的更好应用是树的遍历。 - strager
@Perchik,还请注意这是一个随机数生成器。'i'将不断地递增。使用状态变量更有效地处理它(而不是通过递归和重复计算 i-1 次)。 - strager
@straeger 啊,我刚开始没有完全理解你的意思,现在我懂了。我觉得递归是有道理的,但状态变量确实可以让它更高效。迭代总是比递归更好。 - Perchik
显示剩余2条评论

0
public class generate_random_numbers {

    public static void main(String[] args) {
        int a = 25173, b = 13849, m = 32768;
        Double[] X_ = new Double[100];
        X_[0] = 0.5;
        for (int i = 1; i < 100; i++) {
            X_[i] = (a * X_[i - 1] + b) % m;
            X_[i] = X_[i] / m;
            System.out.println("X_[" + i + "] = " + X_[i]);
        }
    }
}

0
我会先创建一个类,其中包含a、b、m、最新的x(初始化为0.5),以及一个名为getNextNumber()的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接