from ..constants import BAD_FITNESS class Individual: only_positive_fitness = True def __init__(self): self.genotype = None # used for stats. This is raw fitness value, None = not evaluated or invalid genotype self.rawfitness: float = None # used in selection and can be modified e.g. by diversity or niching techniques self.fitness: float = None def copyFrom(self, individual): # "copying constructor" self.genotype = individual.genotype self.rawfitness = individual.rawfitness self.fitness = individual.fitness return self def copy(self): new_copy = Individual() new_copy.genotype = self.genotype new_copy.rawfitness = self.rawfitness new_copy.fitness = self.fitness return new_copy def set_and_evaluate(self, genotype, evaluate): self.genotype = genotype fitness = evaluate(genotype) if fitness is not BAD_FITNESS: # BAD_FITNESS indicates that the genotype was not valid or some other problem occurred during evaluation if self.only_positive_fitness: if fitness < 0: fitness = 0 self.fitness = self.rawfitness = fitness def __str__(self): try: return "%g\t%g\t'%s'" % (self.rawfitness, self.fitness, self.genotype) except: return "%g\t'%s'" % (self.rawfitness, self.genotype) def __gt__(self, other): return self.rawfitness > other.rawfitness