2012-03-02 27 views
7

Używam Pythona i Flasku do wyświetlania losowej planszy i próbuję pozwolić ludziom powrócić do tej samej gry za pomocą nasion.Wysiewanie i ponowne wykorzystywanie losowych nasion Python

Jednak niezależnie od tego, czy używam losowego materiału siewnego, czy określam nasienie, wydaje mi się, że otrzymuję te same pseudolosowe sekwencje.

Wycinam większość mojego kodu (dużo dzielę i łączę z numpy), ale nawet poniższy prosty kod pokazuje błąd: bez względu na to, jaką wartość ma ziarno, podaję formularz, liczba wyświetlana przy przesyłaniu Jest taki sam. Przesłanie formularza bez określenia materiału siewnego pokazuje inną liczbę, ale pomimo pokazania różnych wartości początkowych podczas ponownego ładowania, ta inna liczba jest zawsze taka sama.

Czy robię coś nie tak z siewem?

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

Oto szablon kolba HTML

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

pomnożyć i podzielić nasiona przez 100000, tak aby dać większą wartość niezapomniany (powiedzmy, 4231 zamiast 4.231479094 ...). Czy istnieje lepszy sposób na użycie wartości liczb całkowitych?

AKTUALIZACJA: Tak, istnieje lepszy sposób na wartości początkowe całkowite - nie bałagan z dzielenia w ogóle. Na razie to właśnie robię:

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) 

To działa dobrze. np.random.seed() nie wydawało się zawsze mieć tę samą sekwencję, ale random.seed() nie ma nic przeciwko liczbom całkowitym, więc używam tego ostatniego.

Odpowiedz

6

Twój seed to prawdopodobnie liczba całkowita i dzielenie liczby całkowitej we wczesnej wersji Pythona nie da wartości float. Zatem

7078/100000 = 0 

To zawsze daje nasienie zera jeżeli ziarno jest < 100000 Mając to:

np.random.seed(seed) 

Nasienie powinno się zmienić. Bez argumentu np.random.seed powinien spróbować pobrać ziarno (zależne od systemu).

Jeśli chcesz przeczytać na PIP, który "naprawia" ten podział: patrz PEP 238. W Pythonie 3 to 2/5=0.4 w Pythonie 2.X 2/5=0. Można wymusić zmiennoprzecinkowych upcasting w górnej części kodu o tym wiersz:

from __future__ import division 

Dlaczego korzystania np.random zamiast Pythona random?

Z 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

Kiedy próbuję tej linii, otrzymuję ValueError: Przedmiotem zbyt małej głębokości do żądanej tablicy – mikelietz

+0

mój błąd, będę naprawić. Myślałem, że numpy seed wziął float, to ma int: http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.mtrand.RandomState.html – Hooked

+0

Jeśli wymuszam aktualizację zmiennoprzecinkową i przełączam do używania losowego (nie np.random), to działa z oryginalną wartością 100000. Czy byłby jakiś powód * nie * używać losowego zamiast np.random? – mikelietz

Powiązane problemy