播种和重复使用Python随机种子

9
我正在使用Python和Flask来展示一个随机游戏板,而且想要通过使用种子让人们回到同一个游戏。然而,无论我使用随机种子还是指定种子,我似乎都得到相同的伪随机序列。
我删掉了大部分代码(我用numpy进行了很多拆分和连接),但即使是下面的简单代码也显示了错误:无论我给表单什么值的种子,提交时显示的数字都是相同的。在没有指定种子的情况下提交表单会显示不同的数字,但尽管重新加载时显示不同的种子值,那个数字始终是相同的。
我在种子方面做错了什么吗?
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()

这是 Flask 的 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>

我将种子乘以和除以一百万,以便给出一个更易于记忆的值(比如说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

你的种子可能是一个整数,而早期的Python中整数除法不会得到一个浮点数。因此

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而不是Python的random

文档中了解到:

Python标准库模块“random”也包含一个梅森旋转伪随机数生成器,它具有许多类似于在RandomState中可用的方法。 RandomState除了意识到NumPy外,还具有提供更多的概率分布以供选择的优势。


当我尝试执行那行代码时,出现了ValueError: 对象深度太小,无法生成所需的数组。 - mikelietz
我的错误,我会修复的。我以为numpy seed需要一个浮点数,但实际上它需要一个整数:http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.mtrand.RandomState.html - Hooked
如果我强制将浮点数向上转换,并切换到使用随机数(而不是np.random),那么它可以使用原始的100,000值。是否有任何理由使用随机数而不是np.random? - mikelietz
random 接受任何可哈希对象(因此浮点数也可以在此处使用),而 np.random 只接受 int。就我个人而言,我不知道这两个生成器之间的区别。 - Hooked
由于np.random.seed()使用整数,我不再需要通过除以100000来进行操作。谢谢! - mikelietz
事实上,random.seed() 可以使用相同的整数。 - mikelietz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接