2

I'm trying to perform explore a grid in a random fashion.
The five possible directions I can go are north, east, south, west, and stay, all of which are equally likely, at least initially.

The trouble with simply choosing a random direction from the above is that it ends up keeping my agent too close to the center (two random directions can cancel each other out very easily), which completely defeats the purpose of the random walk.

What I would like to do is to generate random directions in a random fashion that is unbiased as a whole, but which is more likely to choose a direction close to the the previously chosen direction.

Put another way, I need my RNG to have some kind of "momentum".

I came up with this algorithm:

def RandomWithMomentum(n, momentum=0.5):
    from random import uniform
    v = uniform(-1, 1)
    for i in range(n):
        yield v
        v = v * momentum + uniform(-1, 1) * (1 - momentum)

which seems to give excellent results:

-0.04367186243339227
-0.1798381656787107
-0.07608795741137708
-0.0728742899528114
-0.06215075604982321
 0.17952360050689026
 0.016352984710556573
 0.16954506853320414
 0.3947467183848671
 0.12785652121165636

... except that while this algorithm guarantees that positive and negative numbers are equally likely, it does not guarantee a uniform distribution in the interval from -1 to +1!

(This should be obvious if you realize that the numbers aren't necessarily bounded by -1 and +1!)

So my question is, how would I extend this (or some other algorithm) to choosing one of the five directions, instead of just a positive or negative number?

user541686
  • 205,094
  • 128
  • 528
  • 886

3 Answers3

2

You could use turn right, turn left, move forward as possible moves.

So now you need random to one direction twice to go back.

Kabie
  • 10,489
  • 1
  • 38
  • 45
  • Oooh this is interesting... while I don't want to exclude the possibility of moving backward completely, I could also add "stay" and "turn 180 degree", and then just put less weight on them! I like this, I think it'd work. +1 – user541686 Nov 22 '12 at 10:09
1

Are you allowed to store the momentum (velocity) in between steps?

If so, then perhaps the best thing to do is to choose a velocity -- i.e., speed and direction -- at each time step, which adds like a vector to the previous velocity. This is more realistic physics, anyway, since a force changes momentum.

(But given that you live on a grid, there is the complication of how you quantize things so that you end up only moving NESW.)

Andrew Jaffe
  • 26,554
  • 4
  • 50
  • 59
  • It sounds like a good idea, but how do I do it in 2D? Do I do X and Y separately, and see which of NESW the vector is closest to? If so, then how do I know whether I should 'stop' or whether I should move? – user541686 Nov 22 '12 at 09:35
  • Use two direction (basis) vectors (x and y) and set a maximum and minimum radius. The radius is sqrt(x*x+y*y). If the length of your direction vector grows larger, truncate it to the max length, but keep the direction. If your direction doesn't meet the minimum length, it means "don't move", otherwise move in the general direction. – cxxl Nov 22 '12 at 10:54
1

Why not just create a random number 0 <= r <= 4 and map that to a direction (let's say, direction 0 is "don't move")?

I see your problem with the random walk being too random and I would probably try to stick to your direction for some time (you can use a random number as well to determine for how long) and then re-decide. That seems to me to be based in reality at least a bit: usually if you decide to walk into a certain direction, you do it for some time and don't think about changing your mind every x seconds.

http://docs.python.org/2/library/random.html shows how to use the random number functions. random.uniform() gives you uniform distribution as float. use random.randint() for integer results (also uniform, I presume).

cxxl
  • 4,939
  • 3
  • 31
  • 52
  • I'm not sure I really want to "stick with the current direction"... there are cases where I really don't want to outrule moving backward completely. Rather, I want the directions to be *similar* to the previous directions... so that it's less likely for me to go south immediately after going north than it is for me to first go east. And the trouble with choosing a random integer on [0, 4] is that I can't find a good way to make it capture that similarity requirement. – user541686 Nov 22 '12 at 10:07