Axelrod-Python / axelrod-fortran

Python wrapper library around TourExec Fortran for Axelrod's second tournament.
Other
4 stars 0 forks source link

Possible strange behaviour with self interactions? #65

Closed drvinceknight closed 7 years ago

drvinceknight commented 7 years ago

Looking at k42r (which is marked as not Stochastic) does not play against itself in a symmetric way:

>>> players = (axlf.Player("k42r"), axlf.Player("k42r"))
>>> match = axl.Match(players, turns=200)
>>> results = match.play()
>>> results[25:30]
[(C, C), (C, D), (D, D), (D, D), (D, D)]

So on turn 27 ((C, D)) the second k42r defects: which obviously it should not because the histories up until then are the same (have checked: this is not a stochastic effect).

I think this requires carefully walking through the strategy but points towards perhaps a problem with self interactions?

meatballs commented 7 years ago

My suspicion is that this is caused by the fact that the state of all the internal variables within K42R is maintained between calls to that function (and this is true of all the fortran strategies).

For a self-interaction, therefore, the state is 'shared' between the two players and that will affect how they respond.

drvinceknight commented 7 years ago

Yeah I was thinking that... Is there going to be a way to "fix" that? Perhaps for a self interaction create a copy or something?

I wonder how/if they handled this in the original code...

meatballs commented 7 years ago

I can't think of a way to fix this off the top of my head. I'll ponder on it....

meatballs commented 7 years ago

K42R definitely has internal variables that 'clock up' certain conditions. Those will be double counting for self-interactions.

meatballs commented 7 years ago

An idea: We could compile two identical copies of libstrategies.so and then somehow ensure that one of those is used for player1 instances and the other for player2

drvinceknight commented 7 years ago

An idea: We could compile two identical copies of libstrategies.so and then somehow ensure that one of those is used for player1 instances and the other for player2

Sounds like the way to go to me.

We could either do some work to make it all happen seemlessly, getting it all to work in axelrod.Tournament would be ideal (perhaps even using an axelrod_fortran.Player.play method that checks things...). OR we raise a warning when the players are duplicated so that at least it's not silent and then for the purpose of our analysis for the paper we can do self interactions separately and just collate everything.

drvinceknight commented 7 years ago

Perhaps adding an argument to axelrod_fortran.Player.__init__ with a path to the source file would do the trick? (So that we can compile two different ones and then get the self interactions ourselves)

This might be exactly what you were suggesting?

meatballs commented 7 years ago

I don't think so.

The player would need to know (from the match) whether it is player 1 or player 2 so it can decide which copy to use for the strategy function.

drvinceknight commented 7 years ago

Ok but if we just run the tournament in the first instance with everything as is and ignore self interactions and then susequently just run a self interactions tournament (using a list of "copied" players)?

drvinceknight commented 7 years ago

In a different conversation @meatballs said:

the quickest and easietst way is to shift strategies into the player class, pass in a file name to its init (with a default) and take it from there

I'll give this a go which will then require a bit of TLC on the analysis/data collection end but nothing too onerous.