2014-04-14 19 views
7

Sono una specie di nuovo nel fortran proramming. Qualcuno può aiutarmi con la soluzione. Sto avendo un problema di generare numero intero casuale nel range [0,5] in numero casuale FORTRAN utilizzando random_seed e randcome generare il numero casuale intero in fortran 90 nell'intervallo [0,5]?

+1

'rand' è un'estensione GNU. La combinazione di Fortran 95 è 'random_seed' e' random_number'. –

+1

Il risultato è esattamente 5 accettabile per te? O intendevi chiedere la gamma [0,5)? I suggerimenti che seguono non ti forniranno esattamente il valore dell'endpoint (tranne forse per arrotondamento). –

+1

@SteveLionel Non sono abbastanza sicuro di cosa intendi ... Potresti ampliarlo? –

risposta

3

Che dire:

program rand_test 
    use,intrinsic :: ISO_Fortran_env 
    real(REAL32) :: r(5) 
    integer  :: i(5) 

    ! call init_random_seed() would go here 

    call random_number(r) 

    ! Uniform distribution requires floor: Thanks to @francescalus 
    i = floor(r*6._REAL32) 

    print *, i 
end program 
+2

Usa 'reale :: ...' e '6.' quindi. Ma per favore, fai un favore a te stesso e passa alle definizioni esplicite! –

+0

'i = floor (r * 3.) - 1' –

+0

ok, ma darà una distribuzione uniforme .....? \ – user3531410

4

Per sostenere la answer da Alexander Vogt , Generalizzerò.

L'intrinseco random_number(u) restituisce un numero reale u (o un array di tale) dalla distribuzione uniforme nell'intervallo [0,1). [Ovvero, include 0 ma non 1.]

Per avere una distribuzione uniforme discreta sugli interi {n, n + 1, ..., m-1, m} intagliare la distribuzione continua in m + 1-n pezzi di dimensioni uguali, mappando ogni pezzo in un numero intero. Un modo potrebbe essere:

call random_number(u) 
j = n + FLOOR((m+1-n)*u) ! We want to choose one from m-n+1 integers 

Come si può vedere, per la domanda iniziale per {0, 1, 2, 3, 4, 5} Questo riduce al

call random_number(u) 
j = FLOOR(6*u)   ! n=0 and m=5 

e per l'altro caso nel tuo commento {-1, 0, 1}

call random_number(u) 
j = -1 + FLOOR(3*u)  ! n=-1 and m=1 

Naturalmente, altre trasformazioni saranno necessari per i set di numeri interi non contigui, e si dovrebbe prestare attenzione ai problemi numerici.

+0

per evitare l'obliquità a causa del numero limitato di bit in mantissa 'reale' (53 per IEEE 754 a doppia precisione, 24 per singolo -precisione), potresti dover chiamare 'random_number' diverse volte, ad esempio, vedi [come' _randbelow (n) 'è implementato tramite' random() 'in Python] (https://github.com/python/cpython/blob /1dae7450c68bad498e57800387b24cb103c461fa/Lib/random.py#L243-L248) – jfs

Problemi correlati