Passeggiate casuali

Simulazioni di passeggiate senza memoria, a passo costante, simmetriche.

Possiamo immaginare un ubriaco che, a passo costante, si muove lungo un percorso già segnato, unidimensionale, per semplicità rettilineo, indifferentemente in un verso oppure in quello opposto.

Supponiamo faccia passi.

Ogni volta, dopo ogni passo, la scelta di andare nel verso che considereremo positivo, +1, oppure nel verso opposto, – 1, è casuale, come lanciando ogni volta una moneta per poi seguire un verso o l'altro a seconda che esca testa oppure croce.

Possiamo simulare e studiare tali moti sulla pagina web servendosi di JavaScript con la funzione random, che ogni linguaggio di programmazione mette a disposizione per fornire numeri pseudocasuali tra 0 e 1, tutti con la stessa probabilità di essere scelti.

Una scelta casuale tra due valori, -1 e +1, può essere fatta ad esempio elevando -1 a esponente casuale $\delta \in \{0,1\}$.

Math.pow(-1,Math.round(Math.random()))
Alternativamente e più semplicemente si può usare l'espressione $2\delta -1$ sia come
2*Math.round(Math.random()) - 1
sia come
2*Math.floor(Math.random()*2) - 1
Ci si può servire anche dell'operatore per alternative.
(Math.random()<0.5)? -1: 1

Per creare poi un elenco o lista di queste scelte si ricorrerà a una iterazione.

v = []; for (var i=0; i<n; i++) v.push((Math.random()<0.5)? -1: 1)
Ciò può essere condensato in una sola riga sfruttando il metodo per costruire un array vuoto di data lunghezza e riempirlo di qualcosa che con il metodo map può essere riempito con il risultato di un'espressione.
new Array(n).fill().map(() => (Math.random()<0.5)? -1: 1)
Otterremo ad esempio:

Si osservi che a ogni passeggiata si può associare un numero reale tra 0 e 1. Infatti se la sequenza $v_1,v_2, \dots$ dei passi è trasformata in una sequenza $b_1,b_2,\dots$ di 0 e 1 anziché -1 e 1 e consideriamo il numero la cui rappresentazione binaria è $0.b_1b_2\dots$.

Le posizioni via via occupate per effetto di queste scelte, \[\displaystyle pos(n+1)=pos(n)+passo(n)=pos(0)+\sum_{k=0}^npasso(k),\] possono così essere calcolate come somme cumulate:

pos = [0]; for (var i=0; i<n+1; i++) pos.push(pos[i]+v[i])
oppure in una sola riga:
pos = [0,...v.reduce((pos, x, i) => [...pos, x + (pos[i] || 0)], [0])]
o anche
pos = [0,...v.map((sum => value => sum += value)(0))]

ottenendo così:

Il seguente è poi il grafico spazio-tempo della passeggiata dell'ubriaco.

❯❯