Посев и повторное использование случайных семян Python - PullRequest
8 голосов
/ 02 марта 2012

Я использую Python и Flask для отображения рандомизированного игрового поля и пытаюсь позволить людям вернуться в ту же игру, используя начальное число.

Однако, использую ли я случайное начальное число или задаю начальное число, я, кажется, получаю те же псевдослучайные последовательности.

Я вырезал большую часть своего кода (я делаю много разбиений и объединений с numpy), но даже простой код, приведенный ниже, показывает ошибку: независимо от того, какое значение seed я придаю форме, отображаемое числопри отправке то же самое.При отправке формы без указания начального числа отображается другое число, но, несмотря на то, что при повторной загрузке отображаются другие начальные значения, это же число всегда одинаково.

Что-то не так с заполнением?

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

Вот 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>

Я умножаю и делю семена на 100 000, чтобы получить более запоминающееся значение (скажем, 4231 вместо 4.231479094 ...).Есть ли лучший способ использовать целочисленные начальные значения?

ОБНОВЛЕНО: Да, есть лучший способ сделать целочисленные начальные значения - вообще не мешать делению.На данный момент это то, что я делаю:

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 )

Это прекрасно работает.np.random.seed (), похоже, не всегда получает одну и ту же последовательность, но random.seed () не имеет значения для целого числа, поэтому я использую последнее.

1 Ответ

6 голосов
/ 02 марта 2012

Ваше семя, вероятно, представляет собой целочисленное и целочисленное деление в раннем Python, которое не даст float.Таким образом,

7078 / 100000 = 0

Это всегда дает начальное число ноль, если начальное число <100000. При этом: </p>

np.random.seed( seed )

Семя должно измениться.Без аргумента np.random.seed следует попытаться взять (системно-зависимое) начальное число.

Если вы хотите прочитать о PIP, который «исправляет» это разделение: см. PEP 238 ,В Python 3 это 2/5=0.4, в Python 2.X 2/5=0.Вы можете принудительно преобразовать число с плавающей запятой вверху кода, добавив строку:

from __future__ import division

Зачем использовать np.random вместо Python random?

Из документации :

Модуль Python stdlib «random» также содержит генератор псевдослучайных чисел Mersenne Twister с рядом методов, аналогичных тем, которые доступны в RandomState.,RandomState, помимо того, что поддерживает NumPy, обладает тем преимуществом, что предоставляет гораздо большее число вероятностных распределений на выбор.

...