简体   繁体   English

播种和重用Python随机种子

[英]Seeding and reusing Python random seeds

I'm using Python and Flask to display a randomized game board, and trying to allow people to return to the same game by using a seed. 我正在使用Python和Flask来显示一个随机游戏板,并试图让人们通过使用种子回到同一个游戏。

However, whether I use a random seed, or specify a seed, I seem to get the same pseudorandom sequences. 但是,无论我使用随机种子还是指定种子,我似乎都得到了相同的伪随机序列。

I cut out the majority of my code (I do a lot of splitting and joining with numpy) but even the simple code below shows the bug: no matter what value of seed I give the form, the number displayed on submit is the same. 我删除了大部分代码(我做了很多分裂并加入了numpy)但是即使是下面的简单代码也显示了错误:无论我给表单的种子值是多少,提交时显示的数字都是相同的。 Submitting the form without specifying the seed shows a different number, but despite showing different seed values on reloading, that other number is always the same as well. 在不指定种子的情况下提交表单会显示不同的数字,但尽管在重新加载时显示不同的种子值,但其他数字也始终相同。

Am I doing something wrong with seeding? 播种时我做错了吗?

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

Here is the flask HTML template 这是烧瓶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>

I multiply and divide the seeds by 100,000 so as to give a more memorable value (say, 4231 instead of 4.231479094...). 我将种子乘以并除以100,000,以便给出更值得纪念的值(例如,4231而不是4.231479094 ......)。 Is there is a better way to have usable integer seed values? 是否有更好的方法来获得可用的整数种子值?

UPDATED: Yes, there is a better way to do integer seed values - not mess with dividing at all. 更新:是的,有一个更好的方法来做整数种子值 - 根本没有分解。 For the time being this is what I'm doing: 暂时这就是我正在做的事情:

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 )

This works fine. 这很好用。 np.random.seed() didn't seem to always get the same sequence, but random.seed() doesn't mind an integer, so I'm using the latter. np.random.seed()似乎并不总是得到相同的序列,但random.seed()并不介意整数,所以我使用后者。

Your seed is probably an integer and integer division in early Python won't give a float. 你的种子可能是一个整数,早期Python中的整数除法不会给出浮动。 Thus 从而

7078 / 100000 = 0

This always gives a seed of zero if seed is < 100000. With this: 如果种子<100000,则总是给出零种子。使用此:

np.random.seed( seed )

The seed should change. 种子应该改变。 Without an argument np.random.seed should try to take a (system-dependent) seed. 如果没有参数, np.random.seed应该尝试采用(系统相关的)种子。

If you want to read up on the PIP that "fixes" this the division: see PEP 238 . 如果你想阅读PIP“修复”这个部门:参见PEP 238 In Python 3 this 2/5=0.4 in Python 2.X 2/5=0 . 在Python 3中,这个2/5 2/5=0.4在Python 2.X 2/5 2/5=0 You can force floating point upcasting at the top of your code by including the line: 您可以通过包含以下行来强制在代码顶部浮点向上转换:

from __future__ import division

Why use np.random instead of Python's random ? 为什么使用np.random而不是Python的random

From the 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. Python stdlib模块“random”还包含一个Mersenne Twister伪随机数生成器,其中包含许多与RandomState中可用的方法类似的方法。 RandomState, besides being NumPy-aware, has the advantage that it provides a much larger number of probability distributions to choose from. 除了NumPy感知之外,RandomState的优势在于它提供了更多的概率分布可供选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM