(伪)在Python中生成随机数而无需使用模块和时钟 [英] (Pseudo) Random number generation in Python without using modules and clock

查看:142
本文介绍了(伪)在Python中生成随机数而无需使用模块和时钟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Python进行比赛,我正在创建一个机器人来玩游戏.问题是,它没有安装任何c支持,因此我无权访问randomnumpyscipy模块.

I'm using Python for a competition in which I am creating a bot to play a game. The problem is, it does not have anything of c support installed, so I do not have access to the random, numpy, and scipy modules.

我将有大约400mb的可用内存,并且我正在寻找一种方法来生成0到1之间的统一随机数,以便在游戏过程中进行仿真.

I will have roughly 400mb ram available, and I am looking for a way to produce uniform random numbers between 0 and 1 for simulation purposes during the game.

请注意,我之前曾使用时钟时间生成一个数字,但问题是我需要大量数字,而时钟变化不大,这将导致不断产生相同的数字.实际上,对于10万个数字,我最多只能有1秒的时间.

Note that I have used the clock time before to generate a single number, but the issue is that I will need loads of numbers without the clock changing much, which would result in constantly the same number. In fact, I am limited to a maximum of 1 second for, say, 100k numbers.

我正在考虑加载数据,但是问题是该机器人将始终使用相同的数字.再说一次,我需要使用数字的情况略有不同.

I'm considering loading in data, but the problem would then be that the bot would always use the same numbers. Then again, the circumstances for which I need to use the numbers vary slightly.

使用Python 2.7,希望人们有一些建议.

Using Python 2.7, hoping people have some suggestions.

推荐答案

您可以使用 Mersenne Twister 实施.我发现这一个,它是根据Wikipedia上的伪代码建模的.

You can use a Mersenne Twister implementation. I found this one, which is modeled after the pseudocode on Wikipedia.

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Based on the pseudocode in https://en.wikipedia.org/wiki/Mersenne_Twister. Generates uniformly distributed 32-bit integers in the range [0, 232 − 1] with the MT19937 algorithm

Yaşar Arabacı <yasar11732 et gmail nokta com>
"""
# Create a length 624 list to store the state of the generator
MT = [0 for i in xrange(624)]
index = 0

# To get last 32 bits
bitmask_1 = (2 ** 32) - 1

# To get 32. bit
bitmask_2 = 2 ** 31

# To get last 31 bits
bitmask_3 = (2 ** 31) - 1

def initialize_generator(seed):
    "Initialize the generator from a seed"
    global MT
    global bitmask_1
    MT[0] = seed
    for i in xrange(1,624):
        MT[i] = ((1812433253 * MT[i-1]) ^ ((MT[i-1] >> 30) + i)) & bitmask_1


def extract_number():
    """
    Extract a tempered pseudorandom number based on the index-th value,
    calling generate_numbers() every 624 numbers
    """
    global index
    global MT
    if index == 0:
        generate_numbers()
    y = MT[index]
    y ^= y >> 11
    y ^= (y << 7) & 2636928640
    y ^= (y << 15) & 4022730752
    y ^= y >> 18

    index = (index + 1) % 624
    return y

def generate_numbers():
    "Generate an array of 624 untempered numbers"
    global MT
    for i in xrange(624):
        y = (MT[i] & bitmask_2) + (MT[(i + 1 ) % 624] & bitmask_3)
        MT[i] = MT[(i + 397) % 624] ^ (y >> 1)
        if y % 2 != 0:
            MT[i] ^= 2567483615

if __name__ == "__main__":
    from datetime import datetime
    now = datetime.now()
    initialize_generator(now.microsecond)
    for i in xrange(100):
        "Print 100 random numbers as an example"
        print extract_number()

这篇关于(伪)在Python中生成随机数而无需使用模块和时钟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆