Skip to content

Commit

Permalink
Merge pull request #679 from Axelrod-Python/673
Browse files Browse the repository at this point in the history
Fix noise in spatial tournaments
  • Loading branch information
meatballs committed Aug 4, 2016
2 parents 4aa2ab1 + d90333b commit 33a595d
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 51 deletions.
5 changes: 3 additions & 2 deletions axelrod/match_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,13 @@ class SpatialMatches(RoundRobinMatches):
A list of tuples containing the existing edges
"""

def __init__(self, players, turns, game, repetitions, edges):
def __init__(self, players, turns, game, repetitions, edges, noise=0):

if not graph_is_connected(edges, players):
raise ValueError("The graph edges do not include all players.")
self.edges = edges
super(SpatialMatches, self).__init__(players, turns, game, repetitions)
super(SpatialMatches, self).__init__(players, turns, game, repetitions,
noise)

def build_match_chunks(self):
for edge in self.edges:
Expand Down
26 changes: 17 additions & 9 deletions axelrod/tests/unit/test_match_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,19 +217,27 @@ def setUpClass(cls):
cls.players = [s() for s in test_strategies]

@given(repetitions=integers(min_value=1, max_value=test_repetitions),
turns=integers(min_value=1, max_value=test_turns))
@example(repetitions=test_repetitions, turns=test_turns)
def test_build_match_chunks(self, repetitions, turns):
turns=integers(min_value=1, max_value=test_turns),
noise=floats(min_value=0, max_value=1))
@example(repetitions=test_repetitions, turns=test_turns, noise=0)
def test_build_match_chunks(self, repetitions, turns, noise):
edges = [(0, 1), (1, 2), (3, 4)]
sp = axelrod.SpatialMatches(
self.players, turns, test_game, repetitions, edges)
self.players, turns, test_game, repetitions, edges, noise)
chunks = list(sp.build_match_chunks())
match_definitions = [tuple(list(index_pair) + [repetitions])
for (index_pair, match_params, repetitions) in chunks]
expected_match_definitions = [(edge[0], edge[1], repetitions)
for edge in edges]

self.assertEqual(sorted(match_definitions), sorted(expected_match_definitions))
match_definitions = set()

cache = None
expected_params = (turns, test_game, cache, noise)
for index_pair, match_params, repetitions in chunks:
match_definitions.add(tuple(list(index_pair) + [repetitions]))
self.assertEqual(match_params, expected_params)

expected_match_definitions = set((edge[0], edge[1], repetitions)
for edge in edges)

self.assertEqual(match_definitions, expected_match_definitions)

def test_len(self):
edges = [(0, 1), (1, 2), (3, 4)]
Expand Down
122 changes: 83 additions & 39 deletions axelrod/tests/unit/test_tournament.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,45 +594,82 @@ def test_init(self):
self.assertTrue(tournament._with_morality)
self.assertIsInstance(tournament._logger, logging.Logger)
self.assertEqual(tournament.noise, 0.2)
self.assertEqual(tournament.match_generator.noise, 0.2)
anonymous_tournament = axelrod.Tournament(players=self.players)
self.assertEqual(anonymous_tournament.name, 'axelrod')

@given(strategies=strategy_lists(strategies=deterministic_strategies,
min_size=2, max_size=2),
turns=integers(min_value=1, max_value=20))

def test_complete_tournament(self, strategies, turns):
"""
A test to check that a spatial tournament on the complete multigraph
gives the same results as the round robin.
"""

players = [s() for s in strategies]
# edges
edges=[]
for i in range(0, len(players)) :
for j in range(i, len(players)) :
edges.append((i, j))
# create a round robin tournament
tournament = axelrod.Tournament(players, turns=turns)
results = tournament.play()
# create a complete spatial tournament
spatial_tournament = axelrod.SpatialTournament(players, turns=turns,
edges=edges)
spatial_results = spatial_tournament.play()
self.assertEqual(results.ranked_names, spatial_results.ranked_names)
self.assertEqual(results.nplayers, spatial_results.nplayers)
self.assertEqual(results.nrepetitions, spatial_results.nrepetitions)
self.assertEqual(results.payoff_diffs_means, spatial_results.payoff_diffs_means)
self.assertEqual(results.payoff_matrix, spatial_results.payoff_matrix)
self.assertEqual(results.payoff_stddevs, spatial_results.payoff_stddevs)
self.assertEqual(results.payoffs, spatial_results.payoffs)
self.assertEqual(results.cooperating_rating, spatial_results.cooperating_rating)
self.assertEqual(results.cooperation, spatial_results.cooperation)
self.assertEqual(results.normalised_cooperation, spatial_results.normalised_cooperation)
self.assertEqual(results.normalised_scores, spatial_results.normalised_scores)
self.assertEqual(results.good_partner_matrix, spatial_results.good_partner_matrix)
self.assertEqual(results.good_partner_rating, spatial_results.good_partner_rating)
@given(strategies=strategy_lists(strategies=deterministic_strategies,
min_size=2, max_size=2),
turns=integers(min_value=1, max_value=20),
repetitions=integers(min_value=1, max_value=5),
noise=floats(min_value=0, max_value=1),
seed=integers(min_value=0, max_value=4294967295))
@settings(max_examples=50, timeout=0)
def test_complete_tournament(self, strategies, turns, repetitions,
noise, seed):
"""
A test to check that a spatial tournament on the complete multigraph
gives the same results as the round robin.
"""

players = [s() for s in strategies]
# edges
edges = []
for i in range(0, len(players)):
for j in range(i, len(players)):
edges.append((i, j))

# create a round robin tournament
tournament = axelrod.Tournament(players, repetitions=repetitions,
turns=turns, noise=noise)
# create a complete spatial tournament
spatial_tournament = axelrod.SpatialTournament(players,
repetitions=repetitions,
turns=turns,
noise=noise,
edges=edges)

axelrod.seed(seed)
results = tournament.play(progress_bar=False)
axelrod.seed(seed)
spatial_results = spatial_tournament.play(progress_bar=False)

self.assertEqual(results.ranked_names, spatial_results.ranked_names)
self.assertEqual(results.nplayers, spatial_results.nplayers)
self.assertEqual(results.nrepetitions, spatial_results.nrepetitions)
self.assertEqual(results.payoff_diffs_means,
spatial_results.payoff_diffs_means)
self.assertEqual(results.payoff_matrix, spatial_results.payoff_matrix)
self.assertEqual(results.payoff_stddevs, spatial_results.payoff_stddevs)
self.assertEqual(results.payoffs, spatial_results.payoffs)
self.assertEqual(results.cooperating_rating,
spatial_results.cooperating_rating)
self.assertEqual(results.cooperation, spatial_results.cooperation)
self.assertEqual(results.normalised_cooperation,
spatial_results.normalised_cooperation)
self.assertEqual(results.normalised_scores,
spatial_results.normalised_scores)
self.assertEqual(results.good_partner_matrix,
spatial_results.good_partner_matrix)
self.assertEqual(results.good_partner_rating,
spatial_results.good_partner_rating)

def test_particular_tournament(self):
"""A test for a tournament that has caused failures during some bug
fixing"""
players = [axelrod.Cooperator(), axelrod.Defector(),
axelrod.TitForTat(), axelrod.Grudger()]
edges = [(0, 2), (0, 3), (1, 2), (1, 3)]
tournament = axelrod.SpatialTournament(players, edges=edges)
results = tournament.play(progress_bar=False)
expected_ranked_names = ['Cooperator', 'Tit For Tat',
'Grudger', 'Defector']
self.assertEqual(results.ranked_names, expected_ranked_names)

# Check that this tournament runs with noise
tournament = axelrod.SpatialTournament(players, edges=edges, noise=.5)
results = tournament.play(progress_bar=False)
self.assertIsInstance(results, axelrod.ResultSetFromFile)


class TestProbEndingSpatialTournament(unittest.TestCase):
Expand Down Expand Up @@ -671,8 +708,11 @@ def test_init(self):
@given(strategies=strategy_lists(strategies=deterministic_strategies,
min_size=2, max_size=2),
prob_end=floats(min_value=.1, max_value=.9),
reps=integers(min_value=1, max_value=3),
seed=integers(min_value=0, max_value=4294967295))
def test_complete_tournament(self, strategies, prob_end, seed):
@settings(max_examples=50, timeout=0)
def test_complete_tournament(self, strategies, prob_end,
seed, reps):
"""
A test to check that a spatial tournament on the complete graph
gives the same results as the round robin.
Expand All @@ -683,12 +723,14 @@ def test_complete_tournament(self, strategies, prob_end, seed):
for j in range(i, len(players))]
# create a prob end round robin tournament
axelrod.seed(seed)
tournament = axelrod.ProbEndTournament(players, prob_end=prob_end)
tournament = axelrod.ProbEndTournament(players, prob_end=prob_end,
repetitions=reps)
results = tournament.play(progress_bar=False)
# create a complete spatial tournament
axelrod.seed(seed)
spatial_tournament = axelrod.ProbEndSpatialTournament(players,
prob_end=prob_end,
repetitions=reps,
edges=edges)
spatial_results = spatial_tournament.play(progress_bar=False)
self.assertEqual(results.match_lengths, spatial_results.match_lengths)
Expand All @@ -700,8 +742,10 @@ def test_complete_tournament(self, strategies, prob_end, seed):


@given(tournament=spatial_tournaments(strategies=axelrod.basic_strategies,
max_turns=1),
max_turns=1, max_noise=0,
max_repetitions=3),
seed=integers(min_value=0, max_value=4294967295))
@settings(max_examples=50, timeout=0)
def test_one_turn_tournament(self, tournament, seed):
"""
Tests that gives same result as the corresponding spatial round robin
Expand Down
2 changes: 1 addition & 1 deletion axelrod/tournament.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def __init__(self, players, edges, match_generator=SpatialMatches,

self.edges = edges
self.match_generator = SpatialMatches(
players, turns, self.game, repetitions, edges)
players, turns, self.game, repetitions, edges, noise)


class ProbEndSpatialTournament(ProbEndTournament):
Expand Down

0 comments on commit 33a595d

Please sign in to comment.