0

Python で繰り返される囚人のジレンマの実装を書いていて、次の問題が発生しています。

for p in players:
    for o in players:
        if p.name != o.name:
            try:
                p.history[o.name]
            except KeyError:
                p.history[o.name] = []
                o.history[p.name] = []
                for i in xrange(0,2):
                    result = play(p.logic(p.history[o.name]),
                                  o.logic(o.history[p.name]))
                    p.history[o.name].append(result[0])
                    o.history[p.name].append(result[1])

これは私が持っているコードです。'players' リストは、'name' という文字列と 'logic' という関数を持つ Strategy オブジェクトのリストです。私が抱えている問題は回線で発生します

p.history[o.name].append(result[0])

次の辞書を作成しようとしています。

Player 1.history = {"Player 2 Name": [result, result, result]}
Player 2.history = {"Player 1 Name": [result, result, result]}

しかし、私は代わりにこれを取得します:

Player 1.history = {"Player 1 Name": [wrong results], 
                    "Player 2 Name": [wrong results]}

結果はすべて間違っているわけではありませんが、いくつかは間違っています。結果が正しくない理由、またはプレイヤー 1 の辞書に「プレイヤー 1 の名前」、プレイヤー 2 の辞書に「プレイヤー 2 の名前」というキーがある理由を知っている人はいますか?

編集:リクエストに応じてさらにコードを追加

class Strategy:
    """Basic class for all strategies to use. The 'logic' function is defined oustide and governs behavior"""
    def __init__(self, logic, name):
        self.logic = logic
        self.name = name
    history = {}

def makePlayer(name):
    if name == "Defects":
        def logic(hist):
            return 1
    if name == "Tit for Tat":
        def logic(hist):
            for i in xrange(1,3):
                try:
                    if hist[len(hist) -  i][1] == 1:
                        return 1
                except IndexError:
                    pass
            return 0
    return Strategy(logic, name)

payoff = [[100, 0], [101, 1]]

def play(choice1, choice2): #choiceFoo = 0 => cooperate; 1 => defect
    return [[choice1, choice2, payoff[choice1][choice2]], [choice2, choice1, payoff[choice2][choice1]]]
4

1 に答える 1

1

これは完全な答えではありませんが、例外ブロックで「実際の作業」を行うと、混乱が生じる可能性があります。ディクショナリにキーがあるかどうかを確認したい場合は、in操作で明示的に確認してください。

条件を次のように変更することで、try/except ブロックを削除できます。

if p.name != o.name and o.name not in p.history:

繰り返しになりますが、繰り返される囚人のジレンマの一部は、戦略がそれ自体に対抗する必要があるため、次のように優れている可能性があることです。

if o.name not in p.history:

厄介なコード (例: play) がなければ、この問題についてこれ以上のアドバイスを与えることは困難です。

于 2013-02-25T15:33:43.000 に答える