【问题标题】:Simple 2D Random walk简单的 2D 随机游走
【发布时间】:2015-09-30 12:49:26
【问题描述】:

我在这个练习中遇到了平均距离问题。它应该接近 N 步的 sqrt,但它更低。你能帮我找出我的错误在哪里吗?

2D 随机游走。 二维随机游走模拟粒子在点网格中移动的行为。 在每一步,随机游走者以 1/4 的概率向北、向南、向东或向西移动, 独立于之前的动作。确定随机游走者在 N 步后离起点有多远(平均)。 (理论答案:在 sqrt(N) 的数量级上。)

public class RandomWalk{
    public static void main(String[] args){

    int N = Integer.parseInt(args[0]);

    double nextStep = 0;
    double averageDistance = 0;
    int COUNT = 1000;

    for (int j = 0; j < COUNT; j++){
        int moveWest = 0;
        int moveEast = 0;
        int moveSouth = 0;
        int moveNorth = 0;
        double distance = 0;

        for (int i = 0; i < N; i++){
        nextStep = Math.random()*4;
        if (nextStep <= 1) ++moveWest;
          else if (nextStep <= 2) ++moveEast;
            else if (nextStep <= 3) ++moveSouth;
              else if (nextStep <= 4)++moveNorth;       
        }

        moveEast = moveEast - moveWest;
        moveNorth = moveNorth - moveSouth;
        distance = Math.sqrt((moveEast * moveEast) + (moveNorth * moveNorth));
        averageDistance += distance; 

        System.out.println("Walker is " + distance + "\t steps away of from the starting point");
        //System.out.println("Sqrt of N is " + Math.sqrt(N));

    }
    System.out.println("Average distance is " + averageDistance/COUNT + " steps away of from the starting point");
    }
}

【问题讨论】:

  • 的范围大于 (3,4> 所以我会开始制作它们,即使在任何地方都使用小于比较。我测试了它但没有做出重大改变,还是……从这里开始。
  • 我认为它不应该收敛到 sqrt(N) 或类似的东西。它应该在 sqrt(N) 或类似的数量级上。或 mb O(sqrt(N))。数学...
  • 那我猜我的解决方案是对的?

标签: java random


【解决方案1】:

我对您的代码进行了一些测试,上面提到的范围变化

然后你就这样做了:

if (nextStep < 1) ++moveWest;
          else if (nextStep < 2) ++moveEast;
            else if (nextStep < 3) ++moveSouth;
              else if (nextStep < 4)++moveNorth;

注意 变为

100000 次试验,每次 100 步给出了这些结果:

Average distance is 8.873435509749317 steps away of from the starting point
W=2498906
E=2501447
N=2500022
S=2499625

, 其中 W,E,N,S 是所有试验期间给定方向的总步数。 它们看起来不错。

多次运行这样的测试用例表明没有更好的方向。您可能会使用其他方法来获取随机数,但这将是测试生成器,而不是您的情况。从我的角度来看,您的代码看起来不错。

问题陈述中的一句话也给了你一个线索:理论答案:顺序 sqrt(N)。

【讨论】:

  • 谢谢。英语不是我的母语,所以有时我无法理解所有细节。
  • @zubergu: Nitpicking: if 我没记错,Math.randomreturns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0,又名[0.0, 1.0),所以OP的原始代码将其划分为[0.0, 1.0], (1.0, 2.0], (2.0, 3.0], (3.0, 4.0)
  • @TobiaTesan 完全正确,通过从小于或等于小于切换,您可以使所有范围即使在一端打开而在另一端关闭。我正在编辑并提供代码示例来澄清这一点。
【解决方案2】:

我认为这条线行不通:

nextStep = Math.random()*4;

解释是合乎逻辑的。我认为最好使用整数来达到你的目的,因为你想用步骤来计算,这是一个静态单位。嗯,这是基于意见的,但我建议计算完整的步数,而不是跟踪部分步数。

试试这个:

Random rand = new Random(); 
nextStep = rand.nextInt(4)+1; //random numbers {1,2,3,4}

此外,由于 nextInt() 会生成随机的 Integer 值,因此您需要在 if/else 语句中使用 == 运算符而不是 &lt;=

if (nextStep == 1) ++moveWest;
          else if (nextStep == 2) ++moveEast;
            else if (nextStep == 3) ++moveSouth;
              else if (nextStep == 4)++moveNorth;     

问候 Tom(不是我,是 cmets 中的那个!)

【讨论】:

  • 我不明白你的推理,你能详细说明一下吗?
  • 请注意,OP 有if (nextStep &lt;= 1)
  • @TomWellbrock:double Math.random() 的共域是[0.0, 1.0)恰好 1 或 2, 3, 4 命中的概率不是转到0 吗?
  • @TomWellbrock:公平的警告,如果您继续编辑您的答案,提出随机想法,您的名字就会被否决:)
  • 好的,现在我重新阅读它不再“错误”,但我发现它存在三个问题: 1. 为什么要这样做而不是 nextInt(4) 然后是 @987654333 @ 2. 在实践中,它给出的结果非常接近于 OP 的 3。最重要的是,在我看来,这个问题的实际答案是 @zubergu 的:“亲爱的 OP,它不应该收敛到 sqrt( n),只需 O(sqrt(n))"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
相关资源
最近更新 更多