Посев и повторное использование случайных семян Python

Я использую 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>

Я умножаю и делю семена на 100000, чтобы получить более запоминающееся значение (скажем, 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 ответ

Решение

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

7078 / 100000 = 0

Это всегда дает начальное значение нуля, если начальное число < 100000. При этом:

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 вместо питона random ?

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

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

Другие вопросы по тегам