def _generate_data(interactions: dict, points: list, edges: list) -> dict: """Generates useful data from a spatial tournament. Matches interactions from `results` to their corresponding Point in `probe_points`. Parameters ---------- interactions : dict A dictionary mapping edges to the corresponding interactions of those players. points : list of Point objects with coordinates (x, y). edges : list of tuples A list containing tuples of length 2. All tuples will have either 0 or 1 as the first element. The second element is the index of the corresponding probe (+1 to allow for including the Strategy). Returns ---------- point_scores : dict A dictionary where the keys are Points of the form (x, y) and the values are the mean score for the corresponding interactions. """ edge_scores = [ np.mean( [compute_final_score_per_turn(scores)[0] for scores in interactions[edge]] ) for edge in edges ] point_scores = dict(zip(points, edge_scores)) return point_scores
def test_compute_final_score_per_turn(self): for inter, final_score_per_round in zip( self.interactions, self.final_score_per_turn ): self.assertEqual( final_score_per_round, iu.compute_final_score_per_turn(inter) )
def _generate_data(interactions: dict, points: list, edges: list) -> dict: """Generates useful data from a spatial tournament. Matches interactions from `results` to their corresponding Point in `probe_points`. Parameters ---------- interactions : dict A dictionary mapping edges to the corresponding interactions of those players. points : list of Point objects with coordinates (x, y). edges : list of tuples A list containing tuples of length 2. All tuples will have either 0 or 1 as the first element. The second element is the index of the corresponding probe (+1 to allow for including the Strategy). Returns ---------- point_scores : dict A dictionary where the keys are Points of the form (x, y) and the values are the mean score for the corresponding interactions. """ edge_scores = [ np.mean([ compute_final_score_per_turn(scores)[0] for scores in interactions[edge] ]) for edge in edges ] point_scores = dict(zip(points, edge_scores)) return point_scores
def build_score_diffs(self): """ Returns: -------- Returns the score differences between players. List of the form: [ML1, ML2, ML3..., MLn] Where n is the number of players and MLi is a list of the form: [pi1, pi2, pi3, ..., pim] Where m is the number of players and pij is a list of the form: [uij1, uij2, ..., uijk] Where k is the number of repetitions and uijm is the difference of the scores per turn between player i and j in repetition m. """ plist = list(range(self.nplayers)) score_diffs = [[[0] * self.nrepetitions for opponent in plist] for player in plist] for player in plist: for opponent in plist: if (player, opponent) in self.interactions: for repetition, interaction in enumerate( self.interactions[(player, opponent)]): scores = iu.compute_final_score_per_turn( interaction, self.game) diff = (scores[0] - scores[1]) score_diffs[player][opponent][repetition] = diff if (opponent, player) in self.interactions: for repetition, interaction in enumerate( self.interactions[(opponent, player)]): scores = iu.compute_final_score_per_turn( interaction, self.game) diff = (scores[1] - scores[0]) score_diffs[player][opponent][repetition] = diff return score_diffs
def build_payoffs(self): """ Returns: -------- The list of per turn payoffs. List of the form: [ML1, ML2, ML3..., MLn] Where n is the number of players and MLi is a list of the form: [pi1, pi2, pi3, ..., pim] Where m is the number of players and pij is a list of the form: [uij1, uij2, ..., uijk] Where k is the number of repetitions and uijk is the list of utilities obtained by player i against player j in each repetition. """ plist = list(range(self.nplayers)) payoffs = [[[] for opponent in plist] for player in plist] for player in plist: for opponent in plist: utilities = [] for index_pair, repetitions in self.interactions.items(): if (player, opponent) == index_pair: for interaction in repetitions: utilities.append( iu.compute_final_score_per_turn( interaction, self.game)[0]) elif (opponent, player) == index_pair: for interaction in repetitions: utilities.append( iu.compute_final_score_per_turn( interaction, self.game)[1]) payoffs[player][opponent] = utilities return payoffs
def build_payoffs(self): """ Returns: -------- The list of per turn payoffs. List of the form: [ML1, ML2, ML3..., MLn] Where n is the number of players and MLi is a list of the form: [pi1, pi2, pi3, ..., pim] Where m is the number of players and pij is a list of the form: [uij1, uij2, ..., uijk] Where k is the number of repetitions and uijk is the list of utilities obtained by player i against player j in each repetition. """ plist = list(range(self.nplayers)) payoffs = [[[] for opponent in plist] for player in plist] for player in plist: for opponent in plist: utilities = [] for index_pair, repetitions in self.interactions.items(): if (player, opponent) == index_pair: for interaction in repetitions: utilities.append(iu.compute_final_score_per_turn( interaction, self.game)[0]) elif (opponent, player) == index_pair: for interaction in repetitions: utilities.append(iu.compute_final_score_per_turn( interaction, self.game)[1]) payoffs[player][opponent] = utilities return payoffs
def build_score_diffs(self): """ Returns: -------- Returns the score differences between players. List of the form: [ML1, ML2, ML3..., MLn] Where n is the number of players and MLi is a list of the form: [pi1, pi2, pi3, ..., pim] Where m is the number of players and pij is a list of the form: [uij1, uij2, ..., uijk] Where k is the number of repetitions and uijm is the difference of the scores per turn between player i and j in repetition m. """ plist = list(range(self.nplayers)) score_diffs = [[[0] * self.nrepetitions for opponent in plist] for player in plist] for player in plist: for opponent in plist: if (player, opponent) in self.interactions: for repetition, interaction in enumerate(self.interactions[(player, opponent)]): scores = iu.compute_final_score_per_turn(interaction, self.game) diff = (scores[0] - scores[1]) score_diffs[player][opponent][repetition] = diff if (opponent, player) in self.interactions: for repetition, interaction in enumerate(self.interactions[(opponent, player)]): scores = iu.compute_final_score_per_turn(interaction, self.game) diff = (scores[1] - scores[0]) score_diffs[player][opponent][repetition] = diff return score_diffs
def build_payoff_diffs_means(self): """ Returns: -------- The score differences between players. List of the form: [ML1, ML2, ML3..., MLn] Where n is the number of players and MLi is a list of the form: [pi1, pi2, pi3, ..., pim] Where pij is the mean difference of the scores per turn between player i and j in repetition m. """ plist = list(range(self.nplayers)) payoff_diffs_means = [[0 for opponent in plist] for player in plist] for player in plist: for opponent in plist: diffs = [] for index_pair, repetitions in self.interactions.items(): if (player, opponent) == index_pair: for interaction in repetitions: scores = iu.compute_final_score_per_turn(interaction, self.game) diffs.append(scores[0] - scores[1]) elif (opponent, player) == index_pair: for interaction in repetitions: scores = iu.compute_final_score_per_turn(interaction, self.game) diffs.append(scores[1] - scores[0]) if diffs: payoff_diffs_means[player][opponent] = mean(diffs) else: payoff_diffs_means[player][opponent] = 0 return payoff_diffs_means
def build_payoff_diffs_means(self): """ Returns: -------- The score differences between players. List of the form: [ML1, ML2, ML3..., MLn] Where n is the number of players and MLi is a list of the form: [pi1, pi2, pi3, ..., pim] Where pij is the mean difference of the scores per turn between player i and j in repetition m. """ plist = list(range(self.nplayers)) payoff_diffs_means = [[0 for opponent in plist] for player in plist] for player in plist: for opponent in plist: diffs = [] for rep in self.interactions: if (player, opponent) in rep: scores = iu.compute_final_score_per_turn( rep[(player, opponent)]) diffs.append(scores[0] - scores[1]) if (opponent, player) in rep: scores = iu.compute_final_score_per_turn(rep[(opponent, player)]) diffs.append(scores[1] - scores[0]) if diffs: payoff_diffs_means[player][opponent] = mean(diffs) else: payoff_diffs_means[player][opponent] = 0 return payoff_diffs_means
def build_normalised_scores(self): """ Returns: -------- The total mean scores per turn per layer for each repetition lengths. List of the form: [ML1, ML2, ML3..., MLn] Where n is the number of players and MLi is a list of the form: [pi1, pi2, pi3, ..., pim] Where m is the number of repetitions and pij is the mean scores per turn obtained by each player in repetition j. In Axelrod's original tournament, there were no self-interactions (e.g. player 1 versus player 1) and so these are also ignored. """ normalised_scores = [ [[] for rep in range(self.nrepetitions)] for _ in range(self.nplayers)] # Getting list of all per turn scores for each player for each rep for index_pair, repetitions in self.interactions.items(): for repetition, interaction in enumerate(repetitions): if index_pair[0] != index_pair[1]: # Ignore self interactions scores_per_turn = iu.compute_final_score_per_turn( interaction, self.game) for player in range(2): player_index = index_pair[player] score_per_turn = scores_per_turn[player] normalised_scores[player_index][repetition].append(score_per_turn) # Obtaining mean scores and overwriting corresponding entry in # normalised scores for i, rep in enumerate(normalised_scores): for j, player_scores in enumerate(rep): normalised_scores[i][j] = mean(player_scores) return normalised_scores
def build_normalised_scores(self): """ Returns: -------- The total mean scores per turn per layer for each repetition lengths. List of the form: [ML1, ML2, ML3..., MLn] Where n is the number of players and MLi is a list of the form: [pi1, pi2, pi3, ..., pim] Where m is the number of repetitions and pij is the mean scores per turn obtained by each player in repetition j. In Axelrod's original tournament, there were no self-interactions (e.g. player 1 versus player 1) and so these are also ignored. """ normalised_scores = [[[] for rep in range(self.nrepetitions)] for _ in range(self.nplayers)] # Getting list of all per turn scores for each player for each rep for index_pair, repetitions in self.interactions.items(): for repetition, interaction in enumerate(repetitions): if index_pair[0] != index_pair[1]: # Ignore self interactions scores_per_turn = iu.compute_final_score_per_turn( interaction, self.game) for player in range(2): player_index = index_pair[player] score_per_turn = scores_per_turn[player] normalised_scores[player_index][repetition].append( score_per_turn) # Obtaining mean scores and overwriting corresponding entry in # normalised scores for i, rep in enumerate(normalised_scores): for j, player_scores in enumerate(rep): normalised_scores[i][j] = mean(player_scores) return normalised_scores
def _calculate_results(self, interactions): results = [] scores = iu.compute_final_score(interactions, self.game) results.append(scores) score_diffs = scores[0] - scores[1], scores[1] - scores[0] results.append(score_diffs) turns = len(interactions) results.append(turns) score_per_turns = iu.compute_final_score_per_turn( interactions, self.game) results.append(score_per_turns) score_diffs_per_turns = score_diffs[0] / turns, score_diffs[1] / turns results.append(score_diffs_per_turns) initial_coops = tuple( map(bool, iu.compute_cooperations(interactions[:1]))) results.append(initial_coops) cooperations = iu.compute_cooperations(interactions) results.append(cooperations) state_distribution = iu.compute_state_distribution(interactions) results.append(state_distribution) state_to_action_distributions = iu.compute_state_to_action_distribution( interactions) results.append(state_to_action_distributions) winner_index = iu.compute_winner_index(interactions, self.game) results.append(winner_index) return results
def _calculate_results(self, interactions): results = [] scores = iu.compute_final_score(interactions, self.game) results.append(scores) score_diffs = scores[0] - scores[1], scores[1] - scores[0] results.append(score_diffs) turns = len(interactions) results.append(turns) score_per_turns = iu.compute_final_score_per_turn(interactions, self.game) results.append(score_per_turns) score_diffs_per_turns = score_diffs[0] / turns, score_diffs[1] / turns results.append(score_diffs_per_turns) initial_coops = tuple(map(bool, iu.compute_cooperations(interactions[:1]))) results.append(initial_coops) cooperations = iu.compute_cooperations(interactions) results.append(cooperations) state_distribution = iu.compute_state_distribution(interactions) results.append(state_distribution) state_to_action_distributions = iu.compute_state_to_action_distribution( interactions ) results.append(state_to_action_distributions) winner_index = iu.compute_winner_index(interactions, self.game) results.append(winner_index) return results
def final_score_per_turn(self): """Returns the mean score per round for a Match""" return iu.compute_final_score_per_turn(self.result, self.game)
def _build_score_related_metrics(self, progress_bar=False, keep_interactions=False): """ Read the data and carry out all relevant calculations. Parameters ---------- progress_bar : bool Whether or not to display a progress bar keep_interactions : bool Whether or not to lad the interactions in to memory """ match_chunks = self.read_match_chunks(progress_bar) for match in match_chunks: p1, p2 = int(match[0][0]), int(match[0][1]) for repetition, record in enumerate(match): interaction = record[4:] if keep_interactions: try: self.interactions[(p1, p2)].append(interaction) except KeyError: self.interactions[(p1, p2)] = [interaction] scores_per_turn = iu.compute_final_score_per_turn(interaction, game=self.game) cooperations = iu.compute_cooperations(interaction) state_counter = iu.compute_state_distribution(interaction) self._update_match_lengths(repetition, p1, p2, interaction) self._update_payoffs(p1, p2, scores_per_turn) self._update_score_diffs(repetition, p1, p2, scores_per_turn) self._update_normalised_cooperation(p1, p2, interaction) if p1 != p2: # Anything that ignores self interactions for player in [p1, p2]: self.total_interactions[player] += 1 self._update_match_lengths(repetition, p2, p1, interaction) self._update_wins(repetition, p1, p2, interaction) self._update_scores(repetition, p1, p2, interaction) self._update_normalised_scores(repetition, p1, p2, scores_per_turn) self._update_cooperation(p1, p2, cooperations) self._update_state_distribution(p1, p2, state_counter) self._update_good_partner_matrix(p1, p2, cooperations) if progress_bar: self.progress_bar = tqdm.tqdm(total=11 + 2 * self.nplayers, desc="Finishing") self._summarise_normalised_scores() self._summarise_normalised_cooperation() self.ranking = self._build_ranking() self.normalised_state_distribution = self._build_normalised_state_distribution() self.ranked_names = self._build_ranked_names() self.payoff_matrix = self._build_payoff_matrix() self.payoff_stddevs = self._build_payoff_stddevs() self.payoff_diffs_means = self._build_payoff_diffs_means() self.vengeful_cooperation = self._build_vengeful_cooperation() self.cooperating_rating = self._build_cooperating_rating() self.good_partner_rating = self._build_good_partner_rating() self.eigenjesus_rating = self._build_eigenjesus_rating() self.eigenmoses_rating = self._build_eigenmoses_rating() if progress_bar: self.progress_bar.close()
def _build_score_related_metrics(self, progress_bar=False, keep_interactions=False): """ Read the data and carry out all relevant calculations. Parameters ---------- progress_bar : bool Whether or not to display a progress bar keep_interactions : bool Whether or not to lad the interactions in to memory """ match_chunks = self.read_match_chunks(progress_bar) for match in match_chunks: p1, p2 = int(match[0][0]), int(match[0][1]) for repetition, record in enumerate(match): interaction = record[4:] if keep_interactions: try: self.interactions[(p1, p2)].append(interaction) except KeyError: self.interactions[(p1, p2)] = [interaction] scores_per_turn = iu.compute_final_score_per_turn( interaction, game=self.game) cooperations = iu.compute_cooperations(interaction) state_counter = iu.compute_state_distribution(interaction) self._update_match_lengths(repetition, p1, p2, interaction) self._update_payoffs(p1, p2, scores_per_turn) self._update_score_diffs(repetition, p1, p2, scores_per_turn) self._update_normalised_cooperation(p1, p2, interaction) if p1 != p2: # Anything that ignores self interactions for player in [p1, p2]: self.total_interactions[player] += 1 self._update_match_lengths(repetition, p2, p1, interaction) self._update_wins(repetition, p1, p2, interaction) self._update_scores(repetition, p1, p2, interaction) self._update_normalised_scores(repetition, p1, p2, scores_per_turn) self._update_cooperation(p1, p2, cooperations) initial_coops = iu.compute_cooperations(interaction[:1]) self._update_initial_cooperation_count( p1, p2, initial_coops) self._update_state_distribution(p1, p2, state_counter) self._update_good_partner_matrix(p1, p2, cooperations) if progress_bar: self.progress_bar = tqdm.tqdm(total=12 + 2 * self.nplayers, desc="Finishing") self._summarise_normalised_scores() self._summarise_normalised_cooperation() self.ranking = self._build_ranking() self.normalised_state_distribution = self._build_normalised_state_distribution( ) self.ranked_names = self._build_ranked_names() self.payoff_matrix = self._build_payoff_matrix() self.payoff_stddevs = self._build_payoff_stddevs() self.payoff_diffs_means = self._build_payoff_diffs_means() self.vengeful_cooperation = self._build_vengeful_cooperation() self.cooperating_rating = self._build_cooperating_rating() self.initial_cooperation_rate = self._build_initial_cooperation_rate() self.good_partner_rating = self._build_good_partner_rating() self.eigenjesus_rating = self._build_eigenjesus_rating() self.eigenmoses_rating = self._build_eigenmoses_rating() if progress_bar: self.progress_bar.close()