2014-11-08 20 views
5

Desidero scrivere un codice per generare un percorso casuale tramite un rettangolo di una determinata dimensione.Percorso casuale attraverso un rettangolo

inizierò dal punto (0,0) e andare up o right per raggiungere xlim e ylim.

Ecco il mio codice,

y = 10; 
x = 10; 
yOld = 0; 
xOld = 0; 
figure 
axis([0 x 0 y]) 
while yOld < y && xOld < x 
    DirectionChange = randi([0 1],1); 
    if DirectionChange == 0 
     yNew = yOld + 1; 
     xNew = xOld; 
    else 
     xNew = xOld + 1; 
     yNew = yOld; 
    end 
    line ([xOld xNew],[yOld yNew],'LineWidth',3);hold on 
    yOld = yNew; 
    xOld = xNew; 
end 
line ([xNew x],[yNew y],'LineWidth',3);hold off 

Il codice ha un while loop, e termina quando uno dei x o y raggiunge il suo limite.

Quindi funziona bene fornito x = y.

Tuttavia, quando y > x è più probabile che il percorso raggiunga xlim prima.

per 12 corse di x = 10, y = 10 ottengo (ho fatta colorato a guardare meglio!),

enter image description here

Impostazione x = 10, y = 20, ottengo,

enter image description here

Come si può vedere Perdo la casualità in quest'ultimo caso, poiché aumenta la probabilità di raggiungere il limite di x.

Qualche suggerimento su come conservare la casualità in caso di x~=y?

Grazie.

risposta

3

è sempre necessario fare passi X a destra, e passi y su. Quindi crea un array contenente questi passaggi come istruzioni codificate (una semplice matrice andrà bene qui, possiamo usare 0 per il passaggio orizzontale e 1 per il verticale). Quindi mischia l'array. Questo è garantito per colpire l'angolo senza alcuna regolazione, e anche tutti i possibili percorsi saranno ugualmente probabili (il più casuale possibile).

x = 10; 
y = 20; 
steps = [ zeros(1,x) ones(1,y) ]; 
steps = steps(randperm(x+y)); 

figure 
hold on; 

xOld = 0; 
yOld = 0; 
axis([0 x 0 y]) 
for step = steps, 
    if (step == 1) 
     yNew = yOld + 1; 
     xNew = xOld; 
    else 
     xNew = xOld + 1; 
     yNew = yOld; 
    end 
    line ([xOld xNew],[yOld yNew],'LineWidth',3); 
    yOld = yNew; 
    xOld = xNew; 
end 
line ([xNew x],[yNew y],'LineWidth',3); 
hold off 
2

Quello che vuoi fare è fare in modo che P(x increases) = x/(x+y) e P(y increases) = y/(x+y). In questo modo, la probabilità che x raggiunga il limite è uguale alla probabilità che raggiunga il limite.

Esempio: Per una data xlim 5 e un dato ylim 10, generare un numero casuale dalla continua intervallo [0,1]. Se questo numero casuale è inferiore a .333, ovvero xlim/(xlim+ylim), è necessario aumentare xOld. Altrimenti, aumentare yOld.

Utilizzare rand anziché randi.

+0

Non sono sicuro del downvote sull'altra soluzione. Penso che il problema potrebbe essere se y non è un multiplo di x quando y> x o x non è un multiplo di y quando x> y, altrimenti mi sembra a posto. Cosa ne pensi? – Divakar

+0

@Divakar La tua soluzione sembra a posto finchè OP va bene con la movimentazione di movimenti non interi. Le differenze tra le due soluzioni (Arpi/mia e la tua) sono che cambiamo la * probabilità * di movimento e cambi la quantità di movimento * per mantenere la probabilità di colpire entrambi i limiti allo stesso modo. Due soluzioni diverse e valide per la stessa domanda. – Luigi

+0

Va bene come un sollievo per me che sembra in qualche modo valido. Quindi, per quanto riguarda il downvote, è stato per qualche altro motivo? Mi dispiace disturbare, se non fosse stato tu. – Divakar

2

Un'opzione consisterebbe nel condizionare la scelta della direzione sul rapporto di dimensioni, ad es.

DirectionChange = rand(1); 

if DirectionChange < y/(x+y) 
    yNew = yOld + 1; 
    xNew = xOld; 
else 
    xNew = xOld + 1; 
    yNew = yOld; 
end 

enter image description here

Ci sono dei requisiti che dovrebbero essere tenuti? per esempio.passo costante dimensione

EDIT: strategia più efficace per evitare di colpire i 'muri':

DirectionChange = rand(1); 

% distance left to the end 
xLeft = x - xOld; 
yLeft = y - yOld; 

if DirectionChange < yLeft/(xLeft+yLeft) 
    yNew = yOld + 1; 
    xNew = xOld; 
else 
    xNew = xOld + 1; 
    yNew = yOld; 
end 
+0

La tua modifica non conserva la casualità - ti rende meno probabile che si muova in una direzione data una posizione che non è sulla diagonale tra l'angolo in alto a destra e in basso a sinistra. È possibile che OP desideri questo comportamento, ma voglio essere sicuro di far notare che il metodo tu (e io) usato inizialmente * correttamente * ridimensiona ad un caso in cui 'x <> y' – Luigi

+0

+1 per una buona risposta – Luigi

+0

Grazie per il commento, ne sono a conoscenza, ma l'OP non ha specificato i requisiti. Penso che la mia modifica conservi ancora la casualità, ma in modo non stazionario. – Arpi

Problemi correlati