2012-03-02 9 views
7

Estoy usando Python y Flask para mostrar un tablero de juego aleatorizado e intentar permitir que las personas vuelvan al mismo juego usando una semilla.Siembra y reutilización de semillas aleatorias de Python

Sin embargo, si uso una semilla aleatoria, o especifico una semilla, parezco obtener las mismas secuencias pseudoaleatorias.

Recorto la mayor parte de mi código (hago muchas divisiones y uniéndome con numpy) pero incluso el sencillo código siguiente muestra el error: no importa qué valor de semilla le dé al formulario, el número que se muestra en el envío es el mismo. Al enviar el formulario sin especificar la semilla se muestra un número diferente, pero a pesar de mostrar diferentes valores iniciales al recargar, ese otro número siempre es el mismo.

¿Estoy haciendo algo mal con la siembra?

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() 

Aquí es la plantilla HTML frasco

<!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> 

que multiplicar y dividir las semillas de 100.000 a fin de dar un valor más memorable (por ejemplo, 4231 en lugar de 4,231479094 ...). ¿Hay una mejor manera de tener valores de semilla enteros utilizables?

ACTUALIZADO: Sí, hay una mejor manera de hacer valores enteros de inicialización - no meterse con la división en absoluto. Por el momento esto es lo que estoy haciendo:

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) 

Esto funciona bien. np.random.seed() no parece tener siempre la misma secuencia, pero a random.seed() no le importa un entero, entonces estoy usando el último.

Respuesta

6

Tu semilla es probablemente un número entero y la división entera de principios de Python no dará un flotador. Por lo tanto

7078/100000 = 0 

Esto siempre da una semilla de cero si la semilla es < 100000. Con este:

np.random.seed(seed) 

La semilla deberá cambiar. Sin un argumento np.random.seed debería tratar de tomar una semilla (dependiente del sistema).

Si quiere leer en el PIP que "arregla" esta división: vea PEP 238. En Python 3 este 2/5=0.4 en Python 2.X 2/5=0. Puede forzar el punto upcasting flotando en la parte superior de su código mediante la inclusión de la línea:

from __future__ import division 

¿Por qué usar np.random en lugar de Python de random?

Desde el 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

Cuando trato de esa línea, me sale el ValueError: objeto de demasiado pequeña profundidad de la matriz deseada – mikelietz

+0

Mi error, voy a arreglar. Pensé que la semilla numpy tomó un flotador, se necesita un int: http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.mtrand.RandomState.html – Hooked

+0

Si fuerzo el upcasting de coma flotante, y cambio usar aleatorio (no np.random) entonces funciona con el valor 100000 original. ¿Habría alguna razón * no * para usar random en lugar de np.random? – mikelietz

Cuestiones relacionadas