2015-09-30 15 views
5

Ho riscontrato un problema con la distanza media in questo esercizio. Dovrebbe essere vicino al sqrt di N passi, ma è inferiore. Puoi aiutarmi a scoprire dov'è il mio errore?Simple 2D Random walk

passeggiata casuale 2D. Una camminata casuale bidimensionale simula il comportamento di una particella che si muove in una griglia di punti. Ad ogni passaggio, il walker casuale si sposta verso nord, sud, est o ovest con probabilità 1/4, indipendentemente dalle mosse precedenti. Determina quanto lontano (in media) il walker casuale è dal punto di partenza dopo N passi. (risposta teorica:. Dell'ordine di 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"); 
    } 
} 
+0

La gamma da <0,1> è più grande di (3,4> quindi iniziarei a renderli anche utilizzando meno di un confronto in tutto il mondo. L'ho testato ma non ha apportato modifiche significative, ancora ... inizia da qui. – zubergu

+1

Non penso che dovrebbe convergere in sqrt (N) o qualcosa del genere. Dovrebbe essere dell'ordine di grandezza di sqrt (N) o alcuni di questi. O mb O (sqrt (N)). Math ... –

+0

Quindi immagino che la mia soluzione sia giusta? –

risposta

3

ho fatto un paio di test sul codice con citato cambio di gamme < 0,1), < 1,2), < 2,3), < 3,4) rendendoli uniformi.

e si fa in quel modo:

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

Avviso < = diventare <.

100000 prove di 100 passaggi ogni dato quei resutls:

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

, dove W, E, N, S vengono sommati passaggi per data direzione durante tutte le prove. Hanno un bell'aspetto.

L'esecuzione di un tale caso di test per un paio di volte rivela che non esiste una direzione preferibile. Potresti usare altri metodi per ottenere numeri casuali, ma quello sarebbe testare i generatori, non il tuo caso. Il tuo codice sembra ok dal mio punto di vista.

Frase dalla dichiarazione del problema ti dà anche un indizio: teorica risposta: sul ordine di sqrt (N).

+0

Grazie. L'inglese non è la mia lingua madre, quindi a volte non capisco tutti i dettagli. –

+0

@zubergu: Nitpicking: * se * Non mi sbaglio, [Math.random] (http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#random%28% 29) 'restituisce un doppio valore con un segno positivo, maggiore o uguale a 0.0 e minore di 1.0', ovvero' [0.0, 1.0) ', quindi il codice originale di OP lo divide in' [0.0, 1.0], (1.0, 2.0], (2.0, 3.0], (3.0, 4.0) '. –

+1

@TobiaTesan Esattamente, e passando da meno o uguale a solo meno di tutti gli intervalli anche se è aperto da un lato e chiuso su un altro Sto modificando e dando esempi di codice per chiarire questo. – zubergu

1

Penso che questa linea non funziona:

nextStep = Math.random()*4; 

la spiegazione è una logica. Penso che sarebbe meglio usare Integers per il tuo scopo perché vuoi calcolare con step, che è un'unità statica. Bene, questo è basato sull'opinione, ma consiglio di contare il numero completo di passi invece di seguire i passaggi parziali.

Prova a modificare:

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

Inoltre dal nextInt() genera casuali Integer valori è necessario utilizzare l'operatore di == invece di <= nei vostri if/else.

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

quanto riguarda Tom (non io, quello nei commenti!)

+0

Non capisco il tuo ragionamento, vorresti approfondire un po '? –

+0

Nota che l'OP ha 'if (nextStep <= 1)' etc –

+0

@TomWellbrock: ora sono * più * perplesso. 'Math.random() * (4 - 0);' dovrebbe essere esattamente lo stesso (come in, compilando lo stesso bytecode). Cosa mi manca? –