2012-03-02 12 views
7

Sto usando Python e Flask per visualizzare una tavola di gioco randomizzata, e cercando di permettere alle persone di tornare allo stesso gioco usando un seme.Semina e riutilizzo di semi casuali Python

Tuttavia, sia che io usi un seme casuale, sia che specifichi un seme, mi sembra di ottenere le stesse sequenze pseudocasuali.

Ho tagliato la maggior parte del mio codice (faccio un sacco di divisioni e mi unisco a Numpy) ma anche il semplice codice qui sotto mostra il bug: non importa quale valore di seed do il form, il numero visualizzato su submit è la stessa. L'invio del modulo senza specificare il seme mostra un numero diverso, ma nonostante mostri valori seme diversi durante il ricaricamento, quell'altro numero è sempre lo stesso.

Sto facendo qualcosa di sbagliato con la semina?

from flask import Flask, request, render_template 
import numpy as np 
import random 

app = Flask(__name__) 

@app.route('/') 
def single_page(): 
    return render_template('page.html', title = 'empty form') 

@app.route('/number', methods = [ 'POST', 'GET' ]) 
def render_page(title = 'generated random number', error = []): 
    error = [] 
    if request.method == 'POST': 
     if request.form['seed'].isdigit(): 
     seed = int(request.form['seed']) 
     error.append("seed set: " + str(seed) + ".") 
     np.random.seed(seed/100000) 
     else: 
     seed = int(100000 * random.random()) 
     error.append("seed not set, " + str(seed) + " instead.") 
     np.random.seed(seed/100000) 

     n = np.random.random() * 100; 

     return render_template('page.html', title=title, error=error, n=n, seed=seed) 

    else: 
     return render_template('page.html', title = 'empty form') 

if __name__ == '__main__': 
    app.debug = True 
    app.run() 

Ecco il template HTML pallone

<!doctype html> 
<html> 
<head><title>{{title}}</title> 
</head> 
<body> 
{% if error != '' %} 
{% for message in error %} 
    <h2>{{message}}</h2> 
{% endfor %} 
{% endif %} 

{% if n %} 
    <h2>Random number is {{n}}</h2> 

    <h6>seed = {{ seed }}</h6> 
{% else %} 
    <div id="form"> 
    <form id="the_form" method="POST" action="number"> 
    Seed: <input type="number" min="1" max="99999" id="seed" name="seed"><br> 
    <button id="submit" type="submit">Submit</button> 
    </form> 
{% endif %} 
</div> 
</body> 
</html> 

ho moltiplicare e dividere i semi per 100.000 in modo da dare un valore più memorabile (per esempio, invece di 4231 4,231,479094 millions ...). C'è un modo migliore per avere valori seme interi utilizzabili?

AGGIORNATO: Sì, esiste un modo migliore per eseguire valori di seme interi, senza comprometterne la divisione. Per ora questo è quello che sto facendo:

import numpy as np 
import random 
. 
. 
. 
     if request.form['seed'].isdigit(): 
     seed = int(request.form['seed']) 
     error.append("seed set: " + str(seed) + ".") 
     random.seed(seed) 
     else: 
     seed = int(100000 * np.random.random()) 
     error.append("seed not set, " + str(seed) + " instead.") 
     random.seed(seed) 

     n = random.random() * 100; 

     return render_template('page.html', title=title, error=error, n=n, seed=seed) 

Questo funziona bene. np.random.seed() non sembra avere sempre la stessa sequenza, ma random.seed() non si occupa di un intero, quindi sto usando quest'ultimo.

risposta

6

Il tuo seme è probabilmente un intero e una divisione intera in Python non darà un float. Così

7078/100000 = 0 

Questo dà sempre un seme di zero se seme è < 100000. Con questo:

np.random.seed(seed) 

Il seme dovrebbe cambiare. Senza un argomento, np.random.seed dovrebbe provare a prendere un seme (dipendente dal sistema).

Se si desidera leggere sul PIP che "corregge" questa divisione: vedere PEP 238. In Python 3 questo 2/5=0.4 in Python 2.X 2/5=0. È possibile forzare floating point upcasting nella parte superiore del vostro codice, includendo la linea:

from __future__ import division 

Perché utilizzare np.random invece di Python di random?

Dal documentation:

The Python stdlib module “random” also contains a Mersenne Twister pseudo-random number generator with a number of methods that are similar to the ones available in RandomState. RandomState, besides being NumPy-aware, has the advantage that it provides a much larger number of probability distributions to choose from.

+0

Quando provo quella linea, ho la ValueError: oggetto di troppo piccola profondità di gamma desiderata – mikelietz

+0

Il mio errore, io risolvere. Ho pensato che numpy seed ha preso un float, ci vuole un int: http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.mtrand.RandomState.html – Hooked

+0

Se imposto il upcasting a virgola mobile, e cambio utilizzare casuale (non np.random) quindi funziona con il valore originale di 100000. Ci sarebbe qualche ragione * non * da usare a caso invece di np.random? – mikelietz