<s> from __future__ import print_function <EOL> __author__ = '<STR_LIT>' <EOL> from scipy import argmax , array <EOL> from random import sample , choice , shuffle <EOL> from pybrain . utilities import fListToString , Named <EOL> class Coevolution ( Named ) : <EOL> """<STR_LIT>""" <EOL> populationSize = <NUM_LIT:50> <EOL> selectionProportion = <NUM_LIT:0.5> <EOL> elitism = False <EOL> parentChildAverage = <NUM_LIT:1.> <EOL> tournamentSize = None <EOL> hallOfFameEvaluation = <NUM_LIT:0.> <EOL> useSharedSampling = False <EOL> absEvaluator = None <EOL> absEvalProportion = <NUM_LIT:0> <EOL> maxGenerations = None <EOL> maxEvaluations = None <EOL> verbose = False <EOL> def __init__ ( self , relEvaluator , seeds , ** args ) : <EOL> """<STR_LIT>""" <EOL> self . setArgs ( ** args ) <EOL> self . relEvaluator = relEvaluator <EOL> if self . tournamentSize == None : <EOL> self . tournamentSize = self . populationSize <EOL> self . steps = <NUM_LIT:0> <EOL> self . generation = <NUM_LIT:0> <EOL> self . hallOfFame = [ ] <EOL> self . hallOfFitnesses = [ ] <EOL> self . allResults = { } <EOL> self . allOpponents = { } <EOL> self . oldPops = [ ] <EOL> self . _initPopulation ( seeds ) <EOL> def learn ( self , maxSteps = None ) : <EOL> """<STR_LIT>""" <EOL> if maxSteps != None : <EOL> maxSteps += self . steps <EOL> while True : <EOL> if maxSteps != None and self . steps + self . _stepsPerGeneration ( ) > maxSteps : <EOL> break <EOL> if self . maxEvaluations != None and self . steps + self . _stepsPerGeneration ( ) > self . maxEvaluations : <EOL> break <EOL> if self . maxGenerations != None and self . generation >= self . maxGenerations : <EOL> break <EOL> self . _oneGeneration ( ) <EOL> return self . hallOfFame [ - <NUM_LIT:1> ] <EOL> def _oneGeneration ( self ) : <EOL> self . oldPops . append ( self . pop ) <EOL> self . generation += <NUM_LIT:1> <EOL> fitnesses = self . _evaluatePopulation ( ) <EOL> besti = argmax ( array ( fitnesses ) ) <EOL> best = self . pop [ besti ] <EOL> bestFits = sorted ( fitnesses ) [ : : - <NUM_LIT:1> ] [ : self . _numSelected ( ) ] <EOL> self . hallOfFame . append ( best ) <EOL> self . hallOfFitnesses . append ( bestFits ) <EOL> if self . verbose : <EOL> print ( ( '<STR_LIT>' , self . generation ) ) <EOL> print ( ( '<STR_LIT>' , fListToString ( sorted ( fitnesses ) , <NUM_LIT:4> ) ) ) <EOL> if len ( best . params ) < <NUM_LIT:20> : <EOL> print ( ( '<STR_LIT>' , fListToString ( best . params , <NUM_LIT:4> ) ) ) <EOL> self . pop = self . _selectAndReproduce ( self . pop , fitnesses ) <EOL> def _averageWithParents ( self , pop , childportion ) : <EOL> for i , p in enumerate ( pop [ : ] ) : <EOL> if p . parent != None : <EOL> tmp = p . copy ( ) <EOL> tmp . parent = p . parent <EOL> tmp . _setParameters ( p . params * childportion + p . parent . params * ( <NUM_LIT:1> - childportion ) ) <EOL> pop [ i ] = tmp <EOL> def _evaluatePopulation ( self ) : <EOL> hoFtournSize = min ( self . generation , int ( self . tournamentSize * self . hallOfFameEvaluation ) ) <EOL> tournSize = self . tournamentSize - hoFtournSize <EOL> if self . useSharedSampling : <EOL> opponents = self . _sharedSampling ( tournSize , self . pop , self . oldPops [ - <NUM_LIT:1> ] ) <EOL> else : <EOL> opponents = self . pop <EOL> if len ( opponents ) < tournSize : <EOL> tournSize = len ( opponents ) <EOL> self . _doTournament ( self . pop , opponents , tournSize ) <EOL> if hoFtournSize > <NUM_LIT:0> : <EOL> hoF = list ( set ( self . hallOfFame ) ) <EOL> self . _doTournament ( self . pop , hoF , hoFtournSize ) <EOL> fitnesses = [ ] <EOL> for p in self . pop : <EOL> fit = <NUM_LIT:0> <EOL> for opp in opponents : <EOL> fit += self . _beats ( p , opp ) <EOL> if hoFtournSize > <NUM_LIT:0> : <EOL> for opp in hoF : <EOL> fit += self . _beats ( p , opp ) <EOL> if self . absEvalProportion > <NUM_LIT:0> and self . absEvaluator != None : <EOL> fit = ( <NUM_LIT:1> - self . absEvalProportion ) * fit + self . absEvalProportion * self . absEvaluator ( p ) <EOL> fitnesses . append ( fit ) <EOL> return fitnesses <EOL> def _initPopulation ( self , seeds ) : <EOL> if self . parentChildAverage < <NUM_LIT:1> : <EOL> for s in seeds : <EOL> s . parent = None <EOL> self . pop = self . _extendPopulation ( seeds , self . populationSize ) <EOL> def _extendPopulation ( self , seeds , size ) : <EOL> """<STR_LIT>""" <EOL> res = seeds [ : ] <EOL> for dummy in range ( size - len ( seeds ) ) : <EOL> chosen = choice ( seeds ) <EOL> tmp = chosen . copy ( ) <EOL> tmp . mutate ( ) <EOL> if self . parentChildAverage < <NUM_LIT:1> : <EOL> tmp . parent = chosen <EOL> res . append ( tmp ) <EOL> return res <EOL> def _selectAndReproduce ( self , pop , fits ) : <EOL> """<STR_LIT>""" <EOL> s = list ( zip ( fits , pop ) ) <EOL> shuffle ( s ) <EOL> s . sort ( key = lambda x : - x [ <NUM_LIT:0> ] ) <EOL> selected = [ x [ <NUM_LIT:1> ] for x in s [ : self . _numSelected ( ) ] ] <EOL> if self . elitism : <EOL> newpop = self . _extendPopulation ( selected , self . populationSize ) <EOL> if self . parentChildAverage < <NUM_LIT:1> : <EOL> self . _averageWithParents ( newpop , self . parentChildAverage ) <EOL> else : <EOL> newpop = self . _extendPopulation ( selected , self . populationSize <EOL> + self . _numSelected ( ) ) [ self . _numSelected ( ) : ] <EOL> if self . parentChildAverage < <NUM_LIT:1> : <EOL> self . _averageWithParents ( newpop [ self . _numSelected ( ) : ] , self . parentChildAverage ) <EOL> return newpop <EOL> def _beats ( self , h , p ) : <EOL> """<STR_LIT>""" <EOL> if ( h , p ) not in self . allResults : <EOL> return <NUM_LIT:0> <EOL> else : <EOL> hpgames , hscore = self . allResults [ ( h , p ) ] [ <NUM_LIT:1> : <NUM_LIT:3> ] <EOL> phgames , pscore = self . allResults [ ( p , h ) ] [ <NUM_LIT:1> : <NUM_LIT:3> ] <EOL> return ( hscore - pscore ) / float ( hpgames + phgames ) <EOL> def _doTournament ( self , pop1 , pop2 , tournamentSize = None ) : <EOL> """<STR_LIT>""" <EOL> for p in pop1 : <EOL> pop3 = pop2 [ : ] <EOL> while p in pop3 : <EOL> pop3 . remove ( p ) <EOL> if tournamentSize != None and tournamentSize < len ( pop3 ) : <EOL> opps = sample ( pop3 , tournamentSize ) <EOL> else : <EOL> opps = pop3 <EOL> for opp in opps : <EOL> self . _relEval ( p , opp ) <EOL> self . _relEval ( opp , p ) <EOL> def _globalScore ( self , p ) : <EOL> """<STR_LIT>""" <EOL> if p not in self . allOpponents : <EOL> return <NUM_LIT:0.> <EOL> scoresum , played = <NUM_LIT:0.> , <NUM_LIT:0> <EOL> for opp in self . allOpponents [ p ] : <EOL> scoresum += self . allResults [ ( p , opp ) ] [ <NUM_LIT:2> ] <EOL> played += self . allResults [ ( p , opp ) ] [ <NUM_LIT:1> ] <EOL> scoresum -= self . allResults [ ( opp , p ) ] [ <NUM_LIT:2> ] <EOL> played += self . allResults [ ( opp , p ) ] [ <NUM_LIT:1> ] <EOL> played += <NUM_LIT> <EOL> return scoresum / played <EOL> def _sharedSampling ( self , numSelect , selectFrom , relativeTo ) : <EOL> """<STR_LIT>""" <EOL> if numSelect < <NUM_LIT:1> : <EOL> return [ ] <EOL> tmp = { } <EOL> for p in selectFrom : <EOL> beaten = [ ] <EOL> for opp in relativeTo : <EOL> if self . _beats ( p , opp ) > <NUM_LIT:0> : <EOL> beaten . append ( opp ) <EOL> tmp [ p ] = beaten <EOL> beatlist = [ ( len ( p_beaten [ <NUM_LIT:1> ] ) , self . _globalScore ( p_beaten [ <NUM_LIT:0> ] ) , p_beaten [ <NUM_LIT:0> ] ) for p_beaten in list ( tmp . items ( ) ) ] <EOL> shuffle ( beatlist ) <EOL> beatlist . sort ( key = lambda x : x [ : <NUM_LIT:2> ] ) <EOL> best = beatlist [ - <NUM_LIT:1> ] [ <NUM_LIT:2> ] <EOL> unBeaten = list ( set ( relativeTo ) . difference ( tmp [ best ] ) ) <EOL> otherSelect = selectFrom [ : ] <EOL> otherSelect . remove ( best ) <EOL> return [ best ] + self . _sharedSampling ( numSelect - <NUM_LIT:1> , otherSelect , unBeaten ) <EOL> def _relEval ( self , p , opp ) : <EOL> """<STR_LIT>""" <EOL> if p not in self . allOpponents : <EOL> self . allOpponents [ p ] = [ ] <EOL> self . allOpponents [ p ] . append ( opp ) <EOL> if ( p , opp ) not in self . allResults : <EOL> self . allResults [ ( p , opp ) ] = [ <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0.> , [ ] ] <EOL> res = self . relEvaluator ( p , opp ) <EOL> if res > <NUM_LIT:0> : <EOL> self . allResults [ ( p , opp ) ] [ <NUM_LIT:0> ] += <NUM_LIT:1> <EOL> self . allResults [ ( p , opp ) ] [ <NUM_LIT:1> ] += <NUM_LIT:1> <EOL> self . allResults [ ( p , opp ) ] [ <NUM_LIT:2> ] += res <EOL> self . allResults [ ( p , opp ) ] [ <NUM_LIT:3> ] . append ( res ) <EOL> self . steps += <NUM_LIT:1> <EOL> def __str__ ( self ) : <EOL> s = '<STR_LIT>' <EOL> s += str ( self . _numSelected ( ) ) <EOL> if self . elitism : <EOL> s += '<STR_LIT:+>' + str ( self . populationSize - self . _numSelected ( ) ) <EOL> else : <EOL> s += '<STR_LIT:U+002C>' + str ( self . populationSize ) <EOL> s += '<STR_LIT:)>' <EOL> if self . parentChildAverage < <NUM_LIT:1> : <EOL> s += '<STR_LIT>' + str ( self . parentChildAverage ) <EOL> return s <EOL> def _numSelected ( self ) : <EOL> return int ( self . populationSize * self . selectionProportion ) <EOL> def _stepsPerGeneration ( self ) : <EOL> res = self . populationSize * self . tournamentSize * <NUM_LIT:2> <EOL> return res <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> x = Coevolution ( None , [ None ] , populationSize = <NUM_LIT:1> ) <EOL> x . allResults [ ( <NUM_LIT:1> , <NUM_LIT:2> ) ] = [ <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:1> , [ ] ] <EOL> x . allResults [ ( <NUM_LIT:2> , <NUM_LIT:1> ) ] = [ - <NUM_LIT:1> , <NUM_LIT:1> , - <NUM_LIT:1> , [ ] ] <EOL> x . allResults [ ( <NUM_LIT:2> , <NUM_LIT:5> ) ] = [ <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:2> , [ ] ] <EOL> x . allResults [ ( <NUM_LIT:5> , <NUM_LIT:2> ) ] = [ - <NUM_LIT:1> , <NUM_LIT:1> , - <NUM_LIT:1> , [ ] ] <EOL> x . allResults [ ( <NUM_LIT:2> , <NUM_LIT:3> ) ] = [ <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:3> , [ ] ] <EOL> x . allResults [ ( <NUM_LIT:3> , <NUM_LIT:2> ) ] = [ - <NUM_LIT:1> , <NUM_LIT:1> , - <NUM_LIT:1> , [ ] ] <EOL> x . allResults [ ( <NUM_LIT:4> , <NUM_LIT:3> ) ] = [ <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:4> , [ ] ] <EOL> x . allResults [ ( <NUM_LIT:3> , <NUM_LIT:4> ) ] = [ - <NUM_LIT:1> , <NUM_LIT:1> , - <NUM_LIT:1> , [ ] ] <EOL> x . allOpponents [ <NUM_LIT:1> ] = [ <NUM_LIT:2> ] <EOL> x . allOpponents [ <NUM_LIT:2> ] = [ <NUM_LIT:1> , <NUM_LIT:5> ] <EOL> x . allOpponents [ <NUM_LIT:3> ] = [ <NUM_LIT:2> , <NUM_LIT:4> ] <EOL> x . allOpponents [ <NUM_LIT:4> ] = [ <NUM_LIT:3> ] <EOL> x . allOpponents [ <NUM_LIT:5> ] = [ <NUM_LIT:2> ] <EOL> print ( ( x . _sharedSampling ( <NUM_LIT:4> , [ <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:3> , <NUM_LIT:4> , <NUM_LIT:5> ] , [ <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:3> , <NUM_LIT:4> , <NUM_LIT:6> , <NUM_LIT:7> , <NUM_LIT:8> , <NUM_LIT:9> ] ) ) ) <EOL> print ( ( '<STR_LIT>' , [ <NUM_LIT:4> , <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:5> ] ) ) </s>
