ps=80    # population size
G=120     # number of generations to go through
parents=SAGA_Population(Individual,ps,f11,searchspace); parents.objname='CEC05 f11'
offspring=SAGA_Population(Individual,ps,f11,searchspace); offspring.objname='CEC05 f11'

parents.ncase=1   # let this be case 1, plots and pickles will contain the number
offspring.ncase=1

rec=Recorder(parents) # creating this Recorder instance to collect survey data on parent population
rec.snames.append('sa_improverate') # appending a scalar property's name to the survey list
rec.snames.append('sa_toleraterate')
rec.snames.append('ga_improverate')
rec.snames.append('sa_bestcontributions')
rec.snames.append('ga_bestcontributions')
rec.reinitialize_data_dictionaries()
rec.set_goalvalue(97.) # note down whether/when this goal was reached

#-------------------------------------------------------------------------------
#--- part 2: initialisation ----------------------------------------------------
#-------------------------------------------------------------------------------

seed(1)  # seeding numpy's random number generator so we get reproducibly the same random numbers
parents.new_random_genes()
parents.eval_all()
parents.sort()
parents.update_no()

rec.save_status()

sa_T=parents[-1].score-parents[0].score # starting temperature
offspring = SAGA_Population(Individual, ps, f11, searchspace)
offspring.objname = 'CEC05 f11'

parents.ncase = 1  # let this be case 1, plots and pickles will contain the number
offspring.ncase = 1

rec = Recorder(
    parents
)  # creating this Recorder instance to collect survey data on parent population
rec.snames.append(
    'sa_improverate')  # appending a scalar property's name to the survey list
rec.snames.append('sa_toleraterate')
rec.snames.append('ga_improverate')
rec.snames.append('sa_bestcontributions')
rec.snames.append('ga_bestcontributions')
rec.reinitialize_data_dictionaries()
rec.set_goalvalue(97.)  # note down whether/when this goal was reached

#-------------------------------------------------------------------------------
#--- part 2: initialisation ----------------------------------------------------
#-------------------------------------------------------------------------------

seed(
    1
)  # seeding numpy's random number generator so we get reproducibly the same random numbers
parents.new_random_genes()
parents.eval_all()
parents.sort()
parents.update_no()

rec.save_status()
Exemple #3
0
class SAGA:
    """
    a concoction of simulated annealing plugged into a GA framework
    """
    def __init__(self, F0pop, F1pop, userec=False):
        self.F0 = F0pop  # parent population, nomenclature like in your biology book
        self.F1 = F1pop  # offspring population, nomenclature like in your biology book
        self.sa_T = 1.  # temperature
        self.saga_ratio = 0.5  # fraction of offspring created by SA and not GA
        self.sa_mstep = 0.05  # mutation step size parameter
        self.sa_mprob = 0.6  # mutation probability
        self.ga_selp = 3.  # selection pressure
        self.AE = 0.08  # annealing exponent --> exp(-AE) is multiplier for reducing temperature
        self.elite_size = 2
        self.reduce_mstep = False
        if userec:
            self.rec = Recorder(F0pop)
            self.rec.snames.append(
                'sa_improverate'
            )  # appending a scalar property's name to the survey list
            self.rec.snames.append('sa_toleraterate')
            self.rec.snames.append('ga_improverate')
            self.rec.reinitialize_data_dictionaries()
            self.userec = True
        else:
            self.rec = None
            self.userec = False

    def initialize_temperature(self):
        # assumption: parent population already evaluated and sorted
        self.sa_T = np.fabs(self.F0[-1].score - self.F0[0].score)

    def create_offspring(self):
        self.F1.advance_generation()
        self.F0.reset_event_counters()
        for i, dude in enumerate(self.F1):
            oldguy = self.F0[i]
            if i < self.elite_size:
                dude.copy_DNA_of(oldguy, copyscore=True)
                dude.ancestcode = 0.18  # blue-purple for conserved dudes
            elif rand() < self.saga_ratio:
                self.F0.sa_events += 1
                dude.copy_DNA_of(oldguy)
                dude.mutate(self.sa_mprob, sd=self.sa_mstep)
                dude.evaluate()
                if dude.isbetter(oldguy):
                    self.F0.sa_improved += 1
                    dude.ancestcode = 0.49  # turquoise for improvement through mutation
                elif rand() < exp(
                        -np.fabs(dude.score - oldguy.score) / self.sa_T
                ):  # use of fabs makes it neutral to whatever self.F0.whatisfit
                    self.F0.sa_tolerated += 1
                    dude.ancestcode = 0.25  # yellow/beige for tolerated dude
                else:
                    dude.ancestcode = 0.18  # blue-purple for conserved dudes
                    dude.copy_DNA_of(oldguy,
                                     copyscore=True)  # preferring parent DNA
            else:
                self.F0.ga_events += 1
                pa, pb = parentselect_exp(self.F0.psize, self.ga_selp, size=2)
                dude.CO_from(self.F0[pa], self.F0[pb])
                dude.evaluate()
                dude.ancestcode = 0.39  # white for CO dude
                # possible changes: accept CO dude only after SA criterion else take better parent (and mutate?)
                if dude.isbetter(self.F0[pa]) and dude.isbetter(self.F0[pb]):
                    self.F0.ga_improved += 1
        self.F0.calculate_event_rates()
        self.F0.neval += self.F0.psize - self.elite_size  # manually updating counter of calls to the objective function
        # sorry about the line above, I see this is really just a messy workaround
        # there are actually two reasons:
        # a) we evaluated dudes of F1 and we act up as if it happened with F0, but it is even messier
        # b) so far Population.neval is automatically updated only when using a Population method like
        # Population.eval_all() or eval_bunch(), but here we directly had to use the Individual's method evaluate()

    def advance_generation(self):
        for pdude, odude in zip(self.F0, self.F1):
            pdude.copy_DNA_of(odude,
                              copyscore=True,
                              copyancestcode=True,
                              copyparents=True)
        self.F0.advance_generation()

    def do_step(self):
        self.create_offspring()
        self.advance_generation()
        self.F0.mark_oldno()
        self.F0.sort()
        self.F0.update_no()
        if self.userec: self.rec.save_status()

    def run(self, generations):
        for i in range(generations):
            self.do_step()
            self.sa_T *= exp(-self.AE)
            if self.reduce_mstep:
                self.sa_mstep *= exp(-self.AE)

    def simple_run(self, generations, Tstart=None):
        self.F0.new_random_genes()
        self.F0.zeroth_generation()
        if Tstart is not None: self.sa_T = Tstart
        else: self.initialize_temperature()
        if self.userec: self.rec.save_status()
        self.run(generations)
Exemple #4
0
class SAGA:
    """
    a concoction of simulated annealing plugged into a GA framework
    """

    def __init__(self, F0pop, F1pop, userec=False):
        self.F0 = F0pop  # parent population, nomenclature like in your biology book
        self.F1 = F1pop  # offspring population, nomenclature like in your biology book
        self.sa_T = 1.0  # temperature
        self.saga_ratio = 0.5  # fraction of offspring created by SA and not GA
        self.sa_mstep = 0.05  # mutation step size parameter
        self.sa_mprob = 0.6  # mutation probability
        self.ga_selp = 3.0  # selection pressure
        self.AE = 0.08  # annealing exponent --> exp(-AE) is multiplier for reducing temperature
        self.elite_size = 2
        self.reduce_mstep = False
        if userec:
            self.rec = Recorder(F0pop)
            self.rec.snames.append("sa_improverate")  # appending a scalar property's name to the survey list
            self.rec.snames.append("sa_toleraterate")
            self.rec.snames.append("ga_improverate")
            self.rec.reinitialize_data_dictionaries()
            self.userec = True
        else:
            self.rec = None
            self.userec = False

    def initialize_temperature(self):
        # assumption: parent population already evaluated and sorted
        self.sa_T = np.fabs(self.F0[-1].score - self.F0[0].score)

    def create_offspring(self):
        self.F1.advance_generation()
        self.F0.reset_event_counters()
        for i, dude in enumerate(self.F1):
            oldguy = self.F0[i]
            if i < self.elite_size:
                dude.copy_DNA_of(oldguy, copyscore=True)
                dude.ancestcode = 0.18  # blue-purple for conserved dudes
            elif rand() < self.saga_ratio:
                self.F0.sa_events += 1
                dude.copy_DNA_of(oldguy)
                dude.mutate(self.sa_mprob, sd=self.sa_mstep)
                dude.evaluate()
                if dude.isbetter(oldguy):
                    self.F0.sa_improved += 1
                    dude.ancestcode = 0.49  # turquoise for improvement through mutation
                elif rand() < exp(
                    -np.fabs(dude.score - oldguy.score) / self.sa_T
                ):  # use of fabs makes it neutral to whatever self.F0.whatisfit
                    self.F0.sa_tolerated += 1
                    dude.ancestcode = 0.25  # yellow/beige for tolerated dude
                else:
                    dude.ancestcode = 0.18  # blue-purple for conserved dudes
                    dude.copy_DNA_of(oldguy, copyscore=True)  # preferring parent DNA
            else:
                self.F0.ga_events += 1
                pa, pb = parentselect_exp(self.F0.psize, self.ga_selp, size=2)
                dude.CO_from(self.F0[pa], self.F0[pb])
                dude.evaluate()
                dude.ancestcode = 0.39  # white for CO dude
                # possible changes: accept CO dude only after SA criterion else take better parent (and mutate?)
                if dude.isbetter(self.F0[pa]) and dude.isbetter(self.F0[pb]):
                    self.F0.ga_improved += 1
        self.F0.calculate_event_rates()
        self.F0.neval += self.F0.psize - self.elite_size  # manually updating counter of calls to the objective function
        # sorry about the line above, I see this is really just a messy workaround
        # there are actually two reasons:
        # a) we evaluated dudes of F1 and we act up as if it happened with F0, but it is even messier
        # b) so far Population.neval is automatically updated only when using a Population method like
        # Population.eval_all() or eval_bunch(), but here we directly had to use the Individual's method evaluate()

    def advance_generation(self):
        for pdude, odude in zip(self.F0, self.F1):
            pdude.copy_DNA_of(odude, copyscore=True, copyancestcode=True, copyparents=True)
        self.F0.advance_generation()

    def do_step(self):
        self.create_offspring()
        self.advance_generation()
        self.F0.mark_oldno()
        self.F0.sort()
        self.F0.update_no()
        if self.userec:
            self.rec.save_status()

    def run(self, generations):
        for i in range(generations):
            self.do_step()
            self.sa_T *= exp(-self.AE)
            if self.reduce_mstep:
                self.sa_mstep *= exp(-self.AE)

    def simple_run(self, generations, Tstart=None):
        self.F0.new_random_genes()
        self.F0.zeroth_generation()
        if Tstart is not None:
            self.sa_T = Tstart
        else:
            self.initialize_temperature()
        if self.userec:
            self.rec.save_status()
        self.run(generations)