繁体   English   中英

Python:如何修复进程内的随机种子?

[英]Python: How to fix random seed inside process?

我想让每个过程产生随机数,但我希望它们可以在运行中重现。

这是示例代码:

import random
from multiprocessing import Process

random.seed(2019)

def f2():
    print('from f2:')
    v = random.randint(0, 10)
    a = random.randint(0, 10)
    print('v:', v)
    return v, a


def python_process_test():
    n_workers = 2
    workers = []
    for i in range(n_workers):
        p = Process(target=f2, args=())
        p.start()
        workers.append(p)

    for p in workers:
        p.join()


if __name__ == '__main__':
    python_process_test()

这不是我们想要的行为,因为不同运行的值不同:

运行 1:

from f2:
v: 6
from f2:
v: 4

运行 2:

from f2:
v: 0
from f2:
v: 5

更新:

import time
import random
from multiprocessing import Process

random.seed(2019)

def get_random_sleep_time_v1():
    return random.randint(0,3)

def get_random_sleep_time_v2():
    from datetime import datetime
    random.seed(datetime.now())
    return random.randint(0,3)

def f2(rnd_seed, process_id):
    random.seed(rnd_seed)

    # To rundomize order in which process will print
    sleep_time = get_random_sleep_time_v1()
    #sleep_time = get_random_sleep_time_v2()
    time.sleep(sleep_time)

    print('process_id:', process_id)
    v = random.randint(0, 10)
    a = random.randint(0, 10)
    print('v:', v)
    return v, a


def python_process_test():
    n_workers = 4
    workers = []
    for i in range(n_workers):
        rnd_seed = random.randint(0,10)
        p = Process(target=f2, args=(rnd_seed,i))
        p.start()
        workers.append(p)

    for p in workers:
        p.join()


if __name__ == '__main__':
    python_process_test()

使用get_random_sleep_time_v1我得到了所需的行为,但进程的顺序不会从运行到运行改变:

run 1:

    process_id: 0
    v: 1
    process_id: 3
    v: 1
    process_id: 1
    v: 9
    process_id: 2
    v: 2

run 2:

    process_id: 0
    v: 1
    process_id: 3
    v: 1
    process_id: 1
    v: 9
    process_id: 2
    v: 2

使用get_random_sleep_time_v2进程顺序是随机的,但生成的值在运行中不一致:

run 1:
process_id: 3
v: 10
process_id: 1
v: 8
process_id: 2
v: 7
process_id: 0
v: 6

run 2:
process_id: 0
v: 8
process_id: 3
v: 10
process_id: 2
v: 10
process_id: 1
v: 8 

您需要在流程中设置种子:

import random
from multiprocessing import Process, Manager

def f2(i):
    random.seed(2019+i)
    print('from f2:')
    v = random.randint(0, 10)
    a = random.randint(0, 10)
    print('v:', v, 'a:', a)
    return v, a


def python_process_test():
    n_workers = 2
    workers = []

    for i in range(n_workers):
        p = Process(target=f2, args=([i]))
        p.start()
        workers.append(p)

    for p in workers:
        p.join()


if __name__ == '__main__':
    python_process_test()

这每次都会产生以下输出:

from f2:
v: 2 a: 3
from f2:
v: 9 a: 9

编辑:更新以显示由具有不同种子的工人重新播种每个进程的传递

import time
import random
from multiprocessing import Process
from datetime import datetime

random.seed(2222)

def get_random_sleep_time():
    random.seed(datetime.now().microsecond)
    return random.randint(0,3)

def f2(rnd_seed, process_id):
    # To randomize order in which process will print
    sleep_time = get_random_sleep_time()
    time.sleep(sleep_time)

    random.seed(rnd_seed)

    v = random.randint(0, 10)
    a = random.randint(0, 10)
    print('process_id:', process_id, 'v:', v)
    return v, a

def python_process_test():
    n_workers = 4
    workers = []
    for i in range(n_workers):
        rnd_seed = random.randint(0,10)
        p = Process(target=f2, args=(rnd_seed,i))
        p.start()
        workers.append(p)

    for p in workers:
        p.join()

if __name__ == '__main__':
    python_process_test()

一个简单的修复,所以不用担心:

如果要每次生成相同的数字,则每次都需要传递相同的种子值。 1

所以你需要做的就是在每个randint()之前调用random.seed(2019) randint()

本质上,每次使用 random 模块获取值时,它.seed()从当前系统时间中提取.seed()值。 所以你每次都必须手动设置种子,否则它会默认回到那个行为。

暂无
暂无

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

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