If a particle takes 25 random steps, how far from its starting point will it end up? One path cannot answer that question reliably, but many simulated paths can help us estimate a typical distance and the chance of ending near the start.
NoteReading and code
Read textbook Module 9.5, “Random Walk.” This continues the Monte Carlo ideas from Module 9.2. The book also has Module 9.3 on distributions; Monday’s runif()/rnorm() comparison introduced that idea, but we are not working through all of 9.3 here. Download the complete R script after coding along.
One simple pseudorandom number generator is a linear congruential generator (LCG). It starts with a seed and repeatedly applies the same rule:
\[
x_{\text{next}}=(a x_{\text{current}}+b)\bmod m.
\]
The remainder (%% in R) keeps each result between 0 and \(m-1\). If we divide by \(m\), we get a number between 0 and 1 that we could use in a simulation. The sequence is completely determined by its seed and constants, however. It is not a source of physical randomness.
Here is a small example. Predict the first value when the seed is 5. Then trace a few values and look for a repeat.
a <-3b <-14m <-10seed <-5lcg_values <-numeric(6)lcg_values[1] <- seedfor (i in2:length(lcg_values)) { lcg_values[i] <- (a * lcg_values[i -1] + b) %% m}data.frame(value = lcg_values, between_0_and_1 = lcg_values / m)
The first new value is \((3\cdot5+14)\bmod10=9\). To use that result for an east/west choice, we could treat 9 / 10 like a draw from 0 to 1: 9 / 10 < 0.5 is false, so this rule would choose west. But the tiny generator soon repeats 5, 9, 1, 7, 5, ...; its choices would repeat too. This is a teaching example, not the generator we will use for the random walk. We will use runif() and set.seed() so the walk is reproducible without relying on this poor four-value cycle.
Decide the rules before drawing a path
The particle begins at \((0,0)\). On each step, it moves one unit east or west and one unit north or south. Two independent, fair coin flips choose those directions. Each step is therefore diagonal: northeast, northwest, southeast, or southwest, each with probability \(1/4\).
We can simulate each fair coin flip with runif(1) < 0.5. A uniform draw is appropriate here because it gives equal chances to values below and above 0.5. A normal draw would represent a different rule; swapping runif() for rnorm() without changing the test would not preserve our model.
Before coding: after 25 steps, how many positions must we store? Could the particle end at \((0,0)\) after an odd number of diagonal steps?
Build one walk
Store the starting point first. In each loop iteration, calculate the new position from the previous one. We do not need a function.
set.seed(205) # lets us replay this particular pathnumber_of_steps <-25x <-numeric(number_of_steps +1)y <-numeric(number_of_steps +1)x[1] <-0# starting positiony[1] <-0for (i in2:length(x)) {# First coin flip: east or west.if (runif(1) <0.5) { x[i] <- x[i -1] +1 } else { x[i] <- x[i -1] -1 }# Second, independent coin flip: north or south.if (runif(1) <0.5) { y[i] <- y[i -1] +1 } else { y[i] <- y[i -1] -1 }}head(data.frame(step =0:number_of_steps, x, y))
Check the first few rows: do both coordinates change by exactly 1 (up or down) at every step? The first row is step 0, not step 1.
Draw the path
plot(x, y, type ="o", pch =16, cex =0.5, asp =1,col ="steelblue", xlab ="East-west position",ylab ="North-south position", main ="One 25-step random walk")points(x[1], y[1], pch =16, cex =1.5, col ="darkgreen")points(x[length(x)], y[length(y)], pch =16, cex =1.5,col ="firebrick")legend("topright", c("Start", "Finish"),col =c("darkgreen", "firebrick"), pch =16, bty ="n")
The path can cross itself and return to a place it visited earlier. The colored endpoints tell us where it started and finished, not how much ground it covered.
Distance traveled is not displacement
Every diagonal step has length \(\sqrt{1^2+1^2}=\sqrt{2}\). After 25 steps, the distance traveled along the path is always \(25\sqrt{2}\). The displacement is the straight-line distance from \((0,0)\) to the final position:
Which quantity changes when we rerun the simulation with a different seed? Can the displacement be larger than the path length? Why not?
Ask a question one walk cannot answer
What fraction of 25-step walks finish within 5 units of the start? This is a probability question, so we need many independent walks. We no longer need to save every point of every path—only each walk’s final distance.
The outer loop repeats the experiment. The inner loop takes the 25 steps. Notice where x_position and y_position are reset to zero; moving those lines outside the outer loop would accidentally join all the walks into one long path.
final_distances <= 5 produces TRUE or FALSE for each run. R treats these as 1 and 0 when calculating mean(), so the mean is the fraction of simulated walks that finished within 5 units. It is an estimate under our model, not a universal fact about real particles.
hist(final_distances, breaks =15, col ="skyblue2",main ="Final distances from 500 walks",xlab ="Distance from start after 25 steps")abline(v =5, col ="firebrick", lwd =2, lty =2)
Do most walks finish near the start, or far away? Some histogram bins may be empty because a 25-step grid walk can finish at only certain coordinates. Compare the mean displacement with the fixed path length of \(25\sqrt{2}\). Why are they so different?
If we have time: change one assumption
In the repeated-walk code, change only the east-west test from < 0.5 to < 0.65. That makes east more likely than west. Keep the same seed and number of runs, then compare the histogram and fraction_within_5 with the fair-walk results. Which changed, and why? Is the biased rule plausible for the real system you are trying to model?
ImportantWhat Monte Carlo adds
A single simulated path is an example. Repeated independent paths give an estimated distribution of possible outcomes. More runs can stabilize that estimate, but they cannot repair a bad movement rule or tell us whether this grid is a good representation of a real particle.
The random walk is a new example, not an added requirement for Project 3.