def writePopulationDot(ga_engine, filename, format="jpeg", start=0, end=0): """ Writes to a graphical file using pydot, the population of trees Example: >>> GTreeGP.writePopulationDot(ga_engine, "pop.jpg", "jpeg", 0, 10) This example will draw the first ten individuals of the population into the file called "pop.jpg". :param ga_engine: the GA Engine :param filename: the filename, ie. population.jpg :param start: the start index of individuals :param end: the end index of individuals """ if not HAVE_PYDOT: utils.raiseException("You must install Pydot to use this feature !") pop = ga_engine.get_population() graph = pydot.Dot(graph_type="digraph") if not isinstance(pop[0], GTreeGP): utils.raiseException("The population must have individuals of the GTreeGP chromosome !") n = 0 end_index = len(pop) if end == 0 else end for i in xrange(start, end_index): ind = pop[i] subg = pydot.Cluster( "cluster_%d" % i, label="\"Ind. #%d - Score Raw/Fit.: %.4f/%.4f\"" % (i, ind.getRawScore(), ind.getFitnessScore()) ) n = ind.writeDotGraph(subg, n) graph.add_subgraph(subg) graph.write(filename, prog='dot', format=format)
def compare(self, other): """ This method will compare the currently tree with another one :param other: the other GTreeGP to compare """ if not isinstance(other, GTreeGP): utils.raiseException( "The other tree used to compare is not a GTreeGP class", TypeError) stack_self = [] stack_other = [] stack_self.append(self.getRoot()) stack_other.append(other.getRoot()) while len(stack_self) > 0: if (len(stack_self) <= 0) or (len(stack_other) <= 0): return -1 tmp_self, tmp_other = stack_self.pop(), stack_other.pop() if tmp_self.compare(tmp_other) != 0: return -1 stack_self.extend(tmp_self.getChilds()) stack_other.extend(tmp_other.getChilds()) return 0
def RawScoreCriteria(ga_engine): """ Terminate the evolution using the **bestrawscore** and **rounddecimal** parameter obtained from the individual Example: >>> genome.setParams(bestrawscore=0.00, rounddecimal=2) (...) >>> ga_engine.terminationCriteria.set(GSimpleGA.RawScoreCriteria) """ ind = ga_engine.bestIndividual() bestRawScore = ind.getParam("bestrawscore") roundDecimal = ind.getParam("rounddecimal") if bestRawScore is None: utils.raiseException("you must specify the bestrawscore parameter", ValueError) if ga_engine.getMinimax() == constants.minimaxType["maximize"]: if roundDecimal is not None: return round(bestRawScore, roundDecimal) <= round( ind.score, roundDecimal) else: return bestRawScore <= ind.score else: if roundDecimal is not None: return round(bestRawScore, roundDecimal) >= round( ind.score, roundDecimal) else: return bestRawScore >= ind.score
def G1DBinaryStringXSinglePoint(genome, **args): """ The crossover of 1D Binary String, Single Point .. warning:: You can't use this crossover method for binary strings with length of 1. """ sister = None brother = None gMom = args["mom"] gDad = args["dad"] if len(gMom) == 1: utils.raiseException("The Binary String have one element, can't use the Single Point Crossover method !", TypeError) cut = prng.randint(1, len(gMom)) if args["count"] >= 1: sister = gMom.clone() sister.resetStats() sister[cut:] = gDad[cut:] if args["count"] == 2: brother = gDad.clone() brother.resetStats() brother[cut:] = gMom[cut:] return (sister, brother)
def RawScoreCriteria(ga_engine): """ Terminate the evolution using the **bestrawscore** and **rounddecimal** parameter obtained from the individual Example: >>> genome.setParams(bestrawscore=0.00, rounddecimal=2) (...) >>> ga_engine.terminationCriteria.set(GSimpleGA.RawScoreCriteria) """ ind = ga_engine.bestIndividual() bestRawScore = ind.getParam("bestrawscore") roundDecimal = ind.getParam("rounddecimal") if bestRawScore is None: utils.raiseException("you must specify the bestrawscore parameter", ValueError) if ga_engine.getMinimax() == constants.minimaxType["maximize"]: if roundDecimal is not None: return round(bestRawScore, roundDecimal) <= round(ind.score, roundDecimal) else: return bestRawScore <= ind.score else: if roundDecimal is not None: return round(bestRawScore, roundDecimal) >= round(ind.score, roundDecimal) else: return bestRawScore >= ind.score
def G1DListMutatorAllele(genome, **args): """ The mutator of G1DList, Allele Mutator To use this mutator, you must specify the *allele* genome parameter with the :class:`GAllele.GAlleles` instance. """ if args["pmut"] <= 0.0: return 0 listSize = len(genome) mutations = args["pmut"] * listSize allele = genome.getParam("allele", None) if allele is None: utils.raiseException( "to use the G1DListMutatorAllele, you must specify the 'allele' parameter", TypeError) if mutations < 1.0: mutations = 0 for it in xrange(listSize): if utils.randomFlipCoin(args["pmut"]): new_val = allele[it].getRandomAllele() genome[it] = new_val mutations += 1 else: for it in xrange(int(round(mutations))): which_gene = prng.randint(0, listSize) new_val = allele[which_gene].getRandomAllele() genome[which_gene] = new_val return int(mutations)
def G1DBinaryStringXTwoPoint(genome, **args): """ The 1D Binary String crossover, Two Point .. warning:: You can't use this crossover method for binary strings with length of 1. """ sister = None brother = None gMom = args["mom"] gDad = args["dad"] if len(gMom) == 1: utils.raiseException("The Binary String have one element, can't use the Two Point Crossover method !", TypeError) cuts = [prng.randint(1, len(gMom)), prng.randint(1, len(gMom))] if cuts[0] > cuts[1]: utils.listSwapElement(cuts, 0, 1) if args["count"] >= 1: sister = gMom.clone() sister.resetStats() sister[cuts[0]:cuts[1]] = gDad[cuts[0]:cuts[1]] if args["count"] == 2: brother = gDad.clone() brother.resetStats() brother[cuts[0]:cuts[1]] = gMom[cuts[0]:cuts[1]] return (sister, brother)
def LinearScaling(pop): """ Linear Scaling scheme .. warning :: Linear Scaling is only for positive raw scores """ log.debug("Running linear scaling.") pop.statistics() c = constants.CDefScaleLinearMultiplier a = b = delta = 0.0 pop_rawAve = pop.stats["rawAve"] pop_rawMax = pop.stats["rawMax"] pop_rawMin = pop.stats["rawMin"] if pop_rawAve == pop_rawMax: a = 1.0 b = 0.0 elif pop_rawMin > (c * pop_rawAve - pop_rawMax / c - 1.0): delta = pop_rawMax - pop_rawAve a = (c - 1.0) * pop_rawAve / delta b = pop_rawAve * (pop_rawMax - (c * pop_rawAve)) / delta else: delta = pop_rawAve - pop_rawMin a = pop_rawAve / delta b = -pop_rawMin * pop_rawAve / delta for i in xrange(len(pop)): f = pop[i].score if f < 0.0: utils.raiseException("Score %r is negative, linear scaling not supported !" % (f,), ValueError) f = f * a + b if f < 0: f = 0.0 pop[i].fitness = f
def GTreeGPInitializator(genome, **args): """This initializator accepts the follow parameters: *max_depth* The max depth of the tree *method* The method, accepts "grow", "full" or "ramped" .. versionadded:: 0.6 The *GTreeGPInitializator* function. """ max_depth = genome.getParam("max_depth", 5) method = genome.getParam("method", "grow") ga_engine = args["ga_engine"] if method == "grow": root = tree.buildGTreeGPGrow(ga_engine, 0, max_depth) elif method == "full": root = tree.buildGTreeGPFull(ga_engine, 0, max_depth) elif method == "ramped": if utils.randomFlipCoin(0.5): root = tree.buildGTreeGPFull(ga_engine, 0, max_depth) else: root = tree.buildGTreeGPGrow(ga_engine, 0, max_depth) else: utils.raiseException("Unknown tree initialization method [%s] !" % method) genome.setRoot(root) genome.processNodes() assert genome.getHeight() <= max_depth
def G1DListMutatorAllele(genome, **args): """ The mutator of G1DList, Allele Mutator To use this mutator, you must specify the *allele* genome parameter with the :class:`GAllele.GAlleles` instance. """ if args["pmut"] <= 0.0: return 0 listSize = len(genome) mutations = args["pmut"] * listSize allele = genome.getParam("allele", None) if allele is None: utils.raiseException("to use the G1DListMutatorAllele, you must specify the 'allele' parameter", TypeError) if mutations < 1.0: mutations = 0 for it in xrange(listSize): if utils.randomFlipCoin(args["pmut"]): new_val = allele[it].getRandomAllele() genome[it] = new_val mutations += 1 else: for it in xrange(int(round(mutations))): which_gene = prng.randint(0, listSize) new_val = allele[which_gene].getRandomAllele() genome[which_gene] = new_val return int(mutations)
def G1DBinaryStringXSinglePoint(genome, **args): """ The crossover of 1D Binary String, Single Point .. warning:: You can't use this crossover method for binary strings with length of 1. """ sister = None brother = None gMom = args["mom"] gDad = args["dad"] if len(gMom) == 1: utils.raiseException( "The Binary String have one element, can't use the Single Point Crossover method !", TypeError) cut = prng.randint(1, len(gMom)) if args["count"] >= 1: sister = gMom.clone() sister.resetStats() sister[cut:] = gDad[cut:] if args["count"] == 2: brother = gDad.clone() brother.resetStats() brother[cut:] = gMom[cut:] return (sister, brother)
def G1DBinaryStringXTwoPoint(genome, **args): """ The 1D Binary String crossover, Two Point .. warning:: You can't use this crossover method for binary strings with length of 1. """ sister = None brother = None gMom = args["mom"] gDad = args["dad"] if len(gMom) == 1: utils.raiseException( "The Binary String have one element, can't use the Two Point Crossover method !", TypeError) cuts = [prng.randint(1, len(gMom)), prng.randint(1, len(gMom))] if cuts[0] > cuts[1]: utils.listSwapElement(cuts, 0, 1) if args["count"] >= 1: sister = gMom.clone() sister.resetStats() sister[cuts[0]:cuts[1]] = gDad[cuts[0]:cuts[1]] if args["count"] == 2: brother = gDad.clone() brother.resetStats() brother[cuts[0]:cuts[1]] = gMom[cuts[0]:cuts[1]] return (sister, brother)
def compare(self, other): """ This method will compare the currently tree with another one :param other: the other GTreeGP to compare """ if not isinstance(other, GTreeGP): utils.raiseException("The other tree used to compare is not a GTreeGP class", TypeError) stack_self = [] stack_other = [] stack_self.append(self.getRoot()) stack_other.append(other.getRoot()) while len(stack_self) > 0: if (len(stack_self) <= 0) or (len(stack_other) <= 0): return -1 tmp_self, tmp_other = stack_self.pop(), stack_other.pop() if tmp_self.compare(tmp_other) != 0: return -1 stack_self.extend(tmp_self.getChilds()) stack_other.extend(tmp_other.getChilds()) return 0
def setRoot(self, root): """ Sets the root of the tree :param root: the tree root node """ if not isinstance(root, GTreeNodeBase): utils.raiseException("The root must be a node", TypeError) self.root_node = root
def insert(self, ga_engine): """ Insert the stats :param ga_engine: the GA Engine """ utils.raiseException("This method is not implemented on the ABC", NotImplementedError)
def setElitism(self, flag): """ Sets the elitism option, True or False :param flag: True or False """ if type(flag) != BooleanType: utils.raiseException("Elitism option must be True or False", TypeError) self.elitism = flag
def setMinimax(self, mtype): """ Sets the minimize/maximize mode, use constants.minimaxType :param mtype: the minimax mode, from constants.minimaxType """ if mtype not in constants.minimaxType.values(): utils.raiseException("Minimax must be maximize or minimize", TypeError) self.minimax = mtype
def setMutationRate(self, rate): """ Sets the mutation rate, between 0.0 and 1.0 :param rate: the rate, between 0.0 and 1.0 """ if (rate > 1.0) or (rate < 0.0): utils.raiseException("Mutation rate must be >= 0.0 and <= 1.0", ValueError) self.pMutation = rate
def removeSampleMaps(self): for variable in self.variables(): try: os.remove(self.validationSampleMapFilename(variable)) os.remove(self.modelSampleMapFilename(variable)) except AssertionError, exception: raise except Exception, exception: utils.raiseException(u"error removing sample map", exception)
def __init__(self, genome, interactiveMode=True): """ Initializator of GSimpleGA """ #if seed is not None: random.seed(seed) # used to be like this if type(interactiveMode) != BooleanType: utils.raiseException( "Interactive Mode option must be True or False", TypeError) if not isinstance(genome, GenomeBase): utils.raiseException("The genome must be a GenomeBase subclass", TypeError) self.internalPop = GPopulation(genome) self.nGenerations = constants.CDefGAGenerations self.pMutation = constants.CDefGAMutationRate self.pCrossover = constants.CDefGACrossoverRate self.nElitismReplacement = constants.CDefGAElitismReplacement self.setPopulationSize(constants.CDefGAPopulationSize) self.minimax = constants.minimaxType["maximize"] self.elitism = True # NEW self.new_population = None # Adapters self.dbAdapter = None self.migrationAdapter = None self.time_init = None self.max_time = None self.interactiveMode = interactiveMode self.interactiveGen = -1 self.GPMode = False self.selector = FunctionSlot("Selector") self.stepCallback = FunctionSlot("Generation Step Callback") self.terminationCriteria = FunctionSlot("Termination Criteria") self.selector.set(constants.CDefGASelector) self.allSlots = (self.selector, self.stepCallback, self.terminationCriteria) self.internalParams = {} self.currentGeneration = 0 # GP Testing for classes in constants.CDefGPGenomes: if isinstance(self.internalPop.oneSelfGenome, classes): self.setGPMode(True) break log.debug("A GA Engine was created, nGenerations=%d", self.nGenerations) # New self.path = None
def run(self): """ Method called when you call *.start()* of the thread """ if self.data is None: utils.raiseException('You must set the data with setData method', ValueError) with self.sentBytesLock: self.sentBytes = self.send() self.close()
def setGenerations(self, num_gens): """ Sets the number of generations to evolve :param num_gens: the number of generations """ if num_gens < 1: utils.raiseException("Number of generations must be >= 1", ValueError) self.nGenerations = num_gens
def __typeCheck(self, func): """ Used internally to check if a function passed to the function slot is callable. Otherwise raises a TypeError exception. :param func: the function object """ if not callable(func): utils.raiseException("The function must be a method or function", TypeError)
def setCrossoverRate(self, rate): """ Sets the crossover rate, between 0.0 and 1.0 :param rate: the rate, between 0.0 and 1.0 """ if (rate > 1.0) or (rate < 0.0): utils.raiseException("Crossover rate must be >= 0.0 and <= 1.0", ValueError) self.pCrossover = rate
def setPopulationSize(self, size): """ Sets the population size, calls setPopulationSize() of GPopulation :param size: the population size .. note:: the population size must be >= 2 """ if size < 2: utils.raiseException("population size must be >= 2", ValueError) self.internalPop.setPopulationSize(size)
def setElitismReplacement(self, numreplace): """ Set the number of best individuals to copy to the next generation on the elitism :param numreplace: the number of individuals .. versionadded:: 0.6 The *setElitismReplacement* method. """ if numreplace < 1: utils.raiseException("Replacement number must be >= 1", ValueError) self.nElitismReplacement = numreplace
def setInteractiveMode(self, flag=True): """ Enable/disable the interactive mode :param flag: True or False .. versionadded: 0.6 The *setInteractiveMode* method. """ if type(flag) != BooleanType: utils.raiseException( "Interactive Mode option must be True or False", TypeError) self.interactiveMode = flag
def setInteractiveGeneration(self, generation): """ Sets the generation in which the GA must enter in the Interactive Mode :param generation: the generation number, use "-1" to disable .. versionadded::0.6 The *setInteractiveGeneration* method. """ if generation < -1: utils.raiseException("Generation must be >= -1", ValueError) self.interactiveGen = generation
def __init__(self, **kwargs): self._id = kwargs.get('_id') self.label = kwargs.get('label') self.identifier = kwargs.get('identifier') or raiseException( "Identifier not found ") self.link = kwargs.get('link') or raiseException( "link not found in kwargs") self.status = kwargs.get('status') self.createdAt = kwargs.get('createdAt') self.tags = kwargs.get('tags') or []
def __init__(self, genome, interactiveMode=True): """ Initializator of GSimpleGA """ #if seed is not None: random.seed(seed) # used to be like this if type(interactiveMode) != BooleanType: utils.raiseException("Interactive Mode option must be True or False", TypeError) if not isinstance(genome, GenomeBase): utils.raiseException("The genome must be a GenomeBase subclass", TypeError) self.internalPop = GPopulation(genome) self.nGenerations = constants.CDefGAGenerations self.pMutation = constants.CDefGAMutationRate self.pCrossover = constants.CDefGACrossoverRate self.nElitismReplacement = constants.CDefGAElitismReplacement self.setPopulationSize(constants.CDefGAPopulationSize) self.minimax = constants.minimaxType["maximize"] self.elitism = True # NEW self.new_population = None # Adapters self.dbAdapter = None self.migrationAdapter = None self.time_init = None self.max_time = None self.interactiveMode = interactiveMode self.interactiveGen = -1 self.GPMode = False self.selector = FunctionSlot("Selector") self.stepCallback = FunctionSlot("Generation Step Callback") self.terminationCriteria = FunctionSlot("Termination Criteria") self.selector.set(constants.CDefGASelector) self.allSlots = (self.selector, self.stepCallback, self.terminationCriteria) self.internalParams = {} self.currentGeneration = 0 # GP Testing for classes in constants.CDefGPGenomes: if isinstance(self.internalPop.oneSelfGenome, classes): self.setGPMode(True) break log.debug("A GA Engine was created, nGenerations=%d", self.nGenerations) # New self.path = None
def setInteractiveMode(self, flag=True): """ Enable/disable the interactive mode :param flag: True or False .. versionadded: 0.6 The *setInteractiveMode* method. """ if type(flag) != BooleanType: utils.raiseException("Interactive Mode option must be True or False", TypeError) self.interactiveMode = flag
def addChild(self, child): """ Adds a child to the node :param child: the node to be added """ if type(child) == list: self.childs.extend(child) else: if not isinstance(child, GTreeNodeBase): utils.raiseException("The child must be a node", TypeError) self.childs.append(child)
def start(self): """ Start capture of packets and initialize the migration scheme """ self.serverThread.start() if self.topologyGraph is None: utils.raiseException("You must add a topology graph to the migration scheme !") targets = self.topologyGraph.getNeighbors(self.myself) self.clientThread.setMultipleTargetHost(targets) self.clientThread.start()
def start(self): """ Start capture of packets and initialize the migration scheme """ self.serverThread.start() if self.topologyGraph is None: utils.raiseException( "You must add a topology graph to the migration scheme !") targets = self.topologyGraph.getNeighbors(self.myself) self.clientThread.setMultipleTargetHost(targets) self.clientThread.start()
def add(self, begin, end): """ This function adds a new range :param begin: the begin of range :param end: the end of the range """ if begin > end: utils.raiseException('Wrong value, the end of the range (%s) is greater than the begin (%s) !' % (end, begin), ValueError) self.beginEnd.append((begin, end)) self.__processMinMax()
def setDBAdapter(self, dbadapter=None): """ Sets the DB Adapter of the GA Engine :param dbadapter: one of the :mod:`DBAdapters` classes instance .. warning:: the use the of a DB Adapter can reduce the speed performance of the Genetic Algorithm. """ if (dbadapter is not None) and (not isinstance(dbadapter, DBBaseAdapter)): utils.raiseException("The DB Adapter must be a DBBaseAdapter subclass", TypeError) self.dbAdapter = dbadapter
def writeDotImage(self, filename): """ Writes a image representation of the individual :param filename: the output file image """ if not HAVE_PYDOT: utils.raiseException("You must install Pydot to use this feature !") graph = pydot.Dot() self.writeDotGraph(graph) graph.write_jpeg(filename, prog='dot')
def setRandomApply(self, flag=True): """ Sets the random function application, in this mode, the function will randomly choose one slot to apply :param flag: True or False """ if type(flag) != BooleanType: utils.raiseException("Random option must be True or False", TypeError) self.rand_apply = flag
def __init__(self, **kwargs): self.id = kwargs.get('id') self.question = kwargs.get('question') or raiseException( 'Question not found') self.topic = kwargs.get('topic') or raiseException( 'question topic not found') self.status = kwargs.get('status') or raiseException( 'status of question not found') self.tags = kwargs.get('tags') or [] self.description = kwargs.get('description') self.createdAt = kwargs.get('createdAt')
def G1DListInitializatorAllele(genome, **args): """ Allele initialization function of G1DList To use this initializator, you must specify the *allele* genome parameter with the :class:`GAllele.GAlleles` instance. """ allele = genome.getParam("allele", None) if allele is None: utils.raiseException("to use the G1DListInitializatorAllele, you must specify the 'allele' parameter") genome.genomeList = [allele[i].getRandomAllele() for i in xrange(genome.getListSize())]
def unpickleAndDecompress(obj_dump, decompress=True): """ Decompress a zlib compressed string and unpickle the data :param obj: the object to be decompressend and unpickled """ if decompress: if not ZLIB_SUPPORT: utils.raiseException('zlib not found !', ImportError) obj_decompress = zlib.decompress(obj_dump) else: obj_decompress = obj_dump return cPickle.loads(obj_decompress)
def writeDotImage(self, filename): """ Writes a image representation of the individual :param filename: the output file image """ if not HAVE_PYDOT: utils.raiseException( "You must install Pydot to use this feature !") graph = pydot.Dot() self.writeDotGraph(graph) graph.write_jpeg(filename, prog='dot')
def writeDotRaw(self, filename): """ Writes the raw dot file (text-file used by dot/neato) with the representation of the individual :param filename: the output file, ex: individual.dot """ if not HAVE_PYDOT: utils.raiseException( "You must install Pydot to use this feature !") graph = pydot.Dot(graph_type="digraph") self.writeDotGraph(graph) graph.write(filename, prog='dot', format="raw")
def getSentBytes(self): """ Returns the number of sent bytes. The use of this method makes sense when you already have sent the data :rtype: sent bytes """ sent = None with self.sentBytesLock: if self.sentBytes is None: utils.raiseException('Bytes sent is None') else: sent = self.sentBytes return sent