简体   繁体   English

用 Python 生成第 n 个随机数

[英]Generate the n-th random number with Python

I am trying to generate random numbers that are used to generate a part of a world (I am working on world generation for a game).我正在尝试生成用于生成世界一部分的随机数(我正在为游戏进行世界生成)。 I could create these with something like [random.randint(0, 100) for n in range(1000)] to generate 1000 random numbers from 0 to 100, but I don't know how many numbers in a list I need.可以[random.randint(0, 100) for n in range(1000)]类的东西创建这些,以生成从 0 到 100 的 1000 个随机数,我不知道我需要列表中有多少个数字。 What I want is to be able to say something like random.nth_randint(0, 100, 5) which would generate the 5th random number from 0 to 100. (The same number every time as long as you use the same seed) How would I go about doing this?我想要的是能够说出像random.nth_randint(0, 100, 5)这样的东西random.nth_randint(0, 100, 5)它会生成从 0 到 100 的第 5 个随机数。(只要你使用相同的种子,每次都是相同的数字)怎么会我去做这个? And if there is no way to do this, how else could I get the same behavior?如果没有办法做到这一点,我怎么能得到同样的行为呢?

Python's random module produces deterministic pseudo random values. Python 的 random 模块产生确定性的伪随机值。

In simpler words, it behaves as if it generated a list of predetermined values when a seed is provided (or when default seed is taken from OS), and those values will always be the same for a given seed.简而言之,当提供种子时(或从操作系统获取默认种子时),它的行为就好像它生成了一个预定值列表,并且对于给定的种子,这些值将始终相同。 Which is basically what we want here.这基本上就是我们在这里想要的。

So to get nth random value you need to either remember its state for each generated value (probably just keeping track of the values would be less memory hungry) or you need to reset (reseed) the generator each time and produce N random numbers each time to get yours.因此,要获得第 n 个随机值,您需要记住每个生成值的状态(可能只是跟踪这些值会减少内存占用),或者您需要每次重置(重新设置)生成器并每次生成 N 个随机数得到你的。

def randgen(a, b, n, seed=4):
    # our default seed is random in itself as evidenced by https://xkcd.com/221/
    random.seed(seed)
    for i in range(n-1):
        x = random.random()
    return random.randint(a, b)

If I understood well your question you want every time the same n-th number.如果我理解你的问题,你每次都想要相同n-th数字。 You may create a class where you keep track of the generated numbers (if you use the same seed ).您可以创建一个类来跟踪生成的数字(如果您使用相同的seed )。
The main idea is that, when you ask for then nth-number it will generate all the previous in order to be always the same for all the run of the program.主要思想是,当您要求 nth-number 时,它将生成所有以前的数字,以便在程序的所有运行中始终相同。

import random

class myRandom():
    def __init__(self):
        self.generated = []
        #your instance of random.Random()
        self.rand = random.Random(99)

    def generate(self, nth):
        if nth < len(self.generated) + 1:
            return self.generated[nth - 1]
        else:
            for _ in range(len(self.generated), nth):
                self.generated.append(self.rand.randint(1,100))
            return self.generated[nth - 1]

r = myRandom()
print(r.generate(1))
print(r.generate(5))
print(r.generate(10))

Using a defaultdict , you can have a structure that generates a new number on the first access of each key.使用defaultdict ,您可以拥有一个在第一次访问每个键时生成一个新数字的结构。

from collections import defaultdict
from random import randint

random_numbers = defaultdict(lambda: randint(0, 100))

random_number[5] # 42
random_number[5] # 42

random_number[0] # 63

Numbers are thus lazily generated on access.因此,在访问时会延迟生成数字。

Since you are working on a game, it is likely you will then need to preserve random_numbers through interruptions of your program.由于您正在开发游戏,因此您可能需要通过中断程序来保留random_numbers You can use pickle to save your data.您可以使用pickle来保存数据。

import pickle

random_numbers[0] # 24

# Save the current state
with open('random', 'wb') as f:
    pickle.dump(dict(random_numbers), f)

# Load the last saved state
with open('random', 'rb') as f:
    opened_random_numbers = defaultdict(lambda: randint(0, 100), pickle.load(f))

opened_random_numbers[0] # 24

Numpy's new random BitGenerator interface provides a method advance(delta) some of the BitGenerator implementations (including the default BitGenerator used). Numpy 的新随机 BitGenerator 接口提供了一个方法 Advance advance(delta)一些 BitGenerator 实现(包括使用的默认 BitGenerator)。 This function allows you to seed and then advance to get the n-th random number.此功能允许您播种,然后前进以获取第 n 个随机数。

From the docs:从文档:

Advance the underlying RNG as-if delta draws have occurred.推进基础 RNG,就像发生了 delta 绘制一样。

https://numpy.org/doc/stable/reference/random/bit_generators/generated/numpy.random.PCG64.advance.html#numpy.random.PCG64.advance https://numpy.org/doc/stable/reference/random/bit_generators/generated/numpy.random.PCG64.advance.html#numpy.random.PCG64.advance

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

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