1

我正在用 Python 编写博弈论模拟。作为模拟的一部分,每一代,两个玩家配对并相互对抗(每个玩家都是Player1orPlayer2类的一个实例)。稍微简化一下,代码如下所示:

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)。

如何使此代码并行运行?也就是说,我怎样才能同时玩超过 1 对玩对方?我用谷歌搜索了一下,发现了 Python多处理库,但我不知道如何将它应用到这段代码中。

谢谢!

4

2 回答 2

1

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

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

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:我不建议使用多处理,因为创建进程会产生大量开销(需要分配堆栈等)。在您的情况下,多处理就足够了,因为您的应用程序不需要内存隔离。

于 2014-04-16T14:59:17.490 回答
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 的情况下杀死所有正在运行的线程,您将需要查看线程之间的通信,并且您需要在主程序中有一个侦听器线程来在线程运行时读取线程的输出。

于 2014-04-16T15:36:13.643 回答