1

Python でゲーム理論シミュレーションを書いています。シミュレーションの一環として、世代ごとに 2 人のプレーヤーがペアになり、互いに対戦します (各プレーヤーはPlayer1またはPlayer2クラスのインスタンスです)。少し簡略化すると、コードは次のようになります。

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 を返します)。

このコードを並行して実行するにはどうすればよいですか? つまり、一度に複数のペアをプレイするにはどうすればよいですか? 少しグーグルで調べたところ、Pythonマルチプロセッシングライブラリが見つかりましたが、それをこのコード スニペットに適用する方法がわかりません。

ありがとう!

4

2 に答える 2

1

投稿のコメントにコメントするだけです (コメントに十分な担当者がいません)。非常に多くのプロセスを作成することによって生じるオーバーヘッドが原因で、処理が遅くなる可能性があります。play_game が CPU を集中的に使用したり長時間実行したりしない限り、そのために個別のプロセスは必要ないでしょう。スレッドは一般的に開始するのにあまり集中的ではなく (Unix/Linux はスレッドをプロセスとして扱うため、Unix/Linux よりも Windows に当てはまります)、おそらく必要なものに近いものです。

問題の一部は結果の使用です。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()

これらの異なる組み合わせすべてのスレッドを一度に開始します。実行中のスレッドの 1 つが True を返さない場合にすべての実行中のスレッドを強制終了できるようにしたい場合は、スレッド間の通信を確認する必要があり、メイン プログラムにリスナー スレッドを用意する必要があります。実行中にスレッドの出力を読み取ります。

于 2014-04-16T15:36:13.643 に答える
1

Gameから継承されるクラスを作成するthreading.Threadので、スレッドと同様に動作します。Gameクラス コンストラクターはnumber、ゲームの 2 つのプレーヤー オブジェクトと を受け入れます。

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 に答える