并行化Python for-loop,相互扮演两个玩家(游戏理论模拟)

时间:2014-04-15 21:07:42

标签: python multithreading parallel-processing multiprocessing game-theory

我正在用Python编写游戏理论模拟。作为模拟的一部分,每一代,两个玩家配对并相互对战(每个玩家都是Player1Player2类的实例)。简化了一下,代码看起来像这样:

pool1 = [Player1() for _ in range(50)]
pool2 = [Player2() for _ in range(50)]

assignments = range(50)
random.shuffle(assignments)

pairs = []
for i, assignment in enumerate(assignments):
    pairs.append((pool1[i], pool2[assignment]))

for player1, player2 in pairs:
    repeat = True
    while repeat:
        repeat = play_game(player1, player2)

支付作为玩家的属性保留。在每轮结束时,根据玩家的移动,游戏将继续或结束(play_game将分别返回True或False。)

如何让这段代码并行运行?也就是说,如何一次玩多对一对玩?我已经用Google搜索了一下并发现了Python multiprocessing库,但我无法弄清楚如何将它应用到这段代码中。

谢谢!

2 个答案:

答案 0 :(得分:1)

我会创建一个继承自Game的类threading.Thread,因此它的行为类似于线程。 Game类构造函数接受两个玩家对象和number游戏。

number需要通过共享变量resultList将游戏结果返回到主程序中(列表在Python中是线程安全的)。 resultList是一个列表列表,每个Game实例根据其resultList将结果放入number的相应单元格。

每个run()实例的

Game()方法在不同的线程中执行,因此所有游戏​​都是并行进行的。

import threading
numOfGames = 10
resultList = [[] for x in xrange(numOfGames)]

class Game(threading.Thread):

    def __init__(self, player1, player2, number):
        threading.Thread.__init__(self)
        self.number = number
        self.player1 = player1
        self.player2 = player2

    def run(self):

        #Your game algorithm between self.player1 and self.player2 is here

        #Put game result into shared list
        resultList[self.number] = <result>

要使用Game课程,请执行以下操作:

#Create instances of the Game() class, pass your Player() objects
#You can do the step in loop
game0 = Game(<PlayerObj>,<PlayerObj>,0)
game1 = Game(<PlayerObj>,<PlayerObj>,1)

#Start execution of Game.run() methods of all Game() objects in separate threads
#You can do the step in loop
game0.start()
game1.start()

#Wait until all Game.run() methods are executed = all threads are finished
#You can do the step in loop
game0.join()
game1.join()

#In the shared list you have corresponding return values, 
#whatever they are in your case [[result of Game 0],[result of Game 1],[]...]
print resultList

PS:我不推荐使用多处理,因为创建流程需要大量开销(需要分配堆栈等)。在您的情况下,多处理就足够了,因为您的应用程序不需要内存隔离。

答案 1 :(得分:1)

只是评论您帖子的评论(没有足够的代表评论),由于创建了这么多进程引起的开销,它可能会更慢。除非play_game是CPU密集型或长时间运行,否则您可能不需要单独的进程。线程的启动通常较少(在Windows上比Unix / Linux更真实,因为Unix / Linux将线程视为进程),并且可能更接近您的需要。

问题的一部分是你对结果的使用。看起来play_game可以返回False并终止循环,但是这个模型不能用于线程,因为它们不再以线性方式执行。如果你只想运行所有这些,你可以改变

for player1, player2 in pairs:
    repeat = True
    while repeat:
        repeat = play_game(player1, player2)

thread_list = []
for player1, player2 in pairs:
    thread_list.append(threading.Thread(target=play_game,args=(player1,player2)))
for wait_thread in thread_list:
    wait_thread.join()

立即启动所有这些不同配对的线程。如果你想能够杀死所有正在运行的线程,如果其中一个没有返回True,你将需要查看线程之间的通信,并且你需要在主程序中有一个监听器线程在线程运行时读取线程的输出。