Der Einsatz evolutionärer Computermodelle bei der Untersuchung historischer und politischer Fragestellungen

Eckhart Arnold

1 Einleitung
2 Evolutionäre Erklärungen
3 Computermodelle zur Simulation evolutionärer Vorgänge
4 Beispiele für evolutionäre Erklärungsansätze im Bereich der Kulturwissenschaften
5 Zitierte Literatur
6 Anhang: Programmcode des Computerturniers
    6.1 Tournament.py
    6.2 Strategy.py

6.1 Tournament.py

"""Classes for matches and tournaments.

The the instances of the classes Match and Tournament can be
connected to visualizing objects by appending a signal function to
the signalXXXXXX lists of the class instance. Signal functions have
the general form:

    function(originating_object, *argument_list)

See the source code to find out which signals are defined and which
arguments are passed to the signals.

"""



###########################################################
#
#  class Match
#
###########################################################


class Match:
    """Let two strategies play one series of iterated prisoners
    dilemmas and record the results.

    signals:
        signalROUND_FINISHED (match)   - sent when one round of the match
                                         has been finished

    flags (read the "state" field, e.g.  m = Match(p1, p2); flag=m.state):
        MATCH_READY             - match has not yet started
        MATCH_RUNNING           - match is currently running
        MATCH_FINISHED          - match has been finished
    """


    def __init__(self, player1, player2, T=5, R=3, P=1, S=0, w=200):
        """Initialize class with player strategies."""

        self.signalROUND_FINISHED = []  # dummy function with
                                        # argument list

        self.player1 = player1          # strategy of player 1
        self.player2 = player2          # strategy of player 2
        self.moves1 = []                # sequence of moves from player 1
        self.moves2 = []                # sequence of moves from player 2   
        self.score1 = 0                 # absolute score of player 1
        self.score2 = 0                 # absolute score of player 2
        self.round = 0                  # number of round
        self.state = "MATCH_READY"

        self.T = T  # reward for defecting if the other player cooperated
        self.R = R  # reward for mutual cooperation
        self.P = P  # "reward" for mutual defection
        self.S = S  # "reward" for cooperation if the other player defected
        self.w = w  # number of rounds


    def score(self, m1, m2):
        """Return the score of player one for the moves m1 and m2 of
        player one and player two respectively. In order to determine the
        score of player two just swap the parameters m1 and m2."""

        if (m1, m2) == (0, 1):      return self.T
        elif (m1, m2) == (1, 1):    return self.R
        elif (m1, m2) == (0, 0):    return self.P
        else:                       return self.S


    def nextRound(self):
        """Let the players meet and update the respective variables with
        the results. Then, determine if iteration stops after this round
        (random > w). Return 0 if it does, 1 otherwise."""

        self.round += 1
        
        m1 = self.player1.nextMove(self.round, self.moves1, self.moves2)
        m2 = self.player2.nextMove(self.round, self.moves2, self.moves1)

        self.moves1.append(m1)
        self.moves2.append(m2)

        self.score1 += self.score(m1, m2)
        self.score2 += self.score(m2, m1)

        if self.round >= self.w:    return 0
        else:                       return 1


    def match(self):
        """Play one match. Call notifier function after each round."""

        self.state = "MATCH_RUNNING"

        cont = 1
        while cont:
            cont = self.nextRound()
            for s in self.signalROUND_FINISHED: s(self) # callback

        self.state = "MATCH_FINISHED"




###########################################################
#
#  class Tournament
#
###########################################################


class Tournament:
    """Set up and play a tournament.

    signals:
        signalENLIST_PLAYER (tournament, player)
            a new player has been enlisted
        signalNEW_MATCH (tournament, match)
            a new match has just begun
        signalMATCH_COMPLETED (tournament, match)
            match "match" has been completed
        signalTOURNAMENT_FINISHED (tournament)          
            the tournament has been finished

    flags (read the "state" field, e.g.  t = Tournament(); flag=t.state):
        TOURNAMENT_READY        - match has not yet started
        TOURNAMENT_RUNNING      - match is currently running
        TOURNAMENT_FINISHED     - match is finished
    """


    def __init__(self, name = "Tournament", T=5, R=3, P=1, S=0, w=200):
        """Initialize class with match notifier and 
        identification string."""

        self.signalENLIST_PLAYER       = []
        self.signalNEW_MATCH           = []
        self.signalMATCH_COMPLETED     = []
        self.signalTOURNAMENT_FINISHED = []
        
        self.name = name    # identification string
        self.player = []    # list of players
        self.match  = []    # list of matches
        self.score = {} # dictionary of player scores (indexed by players)
        self.state = "TOURNAMENT_READY"

        self.T = T  # Parameters defining the reward (or punishment resp.)
        self.R = R  # for cooperation or defection.
        self.P = P  # These parameters are directly passed to Match.__init__()
        self.S = S      
        self.w = w  # number of rounds



    def __cmpfunc(self, p1, p2):
        if self.score[p1] > self.score[p2]:     return -1
        elif self.score[p1] == self.score[p2]:  return 0
        else:                                   return 1


    def enlistPlayer(self, newPlayer):
        """Adds a new Player to the tournament."""

        self.player.append(newPlayer)
        for s in self.signalENLIST_PLAYER: s(self, newPlayer)


    def runTournament(self):
        """Run the tournament.

        Let each player play once against every other player.
        Invoke signalNEW_MATCH before a new new match is started and
        signalMATCH_COMPLETED after it is finished. When all matches are
        completed, calculate the scores of the players and sort
        self.player according to the players rank in the tournament."""

        self.state = "TOURNAMENT_RUNNING"

        self.match = []
        for p in self.player: self.score[p] = 0

        for i in range(len(self.player)):
            for k in range(i+1, len(self.player)):
                p1 = self.player[i]
                p2 = self.player[k]

                m = Match(p1, p2, self.T, self.R, self.P, self.S, self.w)

                self.match.append(m)
                for s in self.signalNEW_MATCH: s(self, m)
                
                m.match()
                self.score[p1] += m.score1
                self.score[p2] += m.score2
                for s in self.signalMATCH_COMPLETED: s(self, m)

        self.player.sort(self.__cmpfunc)

        self.state = "TOURNAMENT_FINISHED"
        for s in self.signalTOURNAMENT_FINISHED: s(self)


t g+ f @