diff --git a/pyevolve/Interaction.py b/pyevolve/Interaction.py index d08b5e4..e578f61 100644 --- a/pyevolve/Interaction.py +++ b/pyevolve/Interaction.py @@ -17,69 +17,70 @@ import logging try: - import pylab + import pylab except: - logging.debug("cannot import Matplotlib ! Plots will not be available !") - print "Warning: cannot import Matplotlib ! Plots will not be available !" + logging.debug("cannot import Matplotlib ! Plots will not be available !") + print "Warning: cannot import Matplotlib ! Plots will not be available !" try: - import numpy + import numpy except: - logging.debug("cannot import Numpy ! Some functions will not be available !") - print "Warning: cannot import Numpy ! Some functions will not be available !" + logging.debug("cannot import Numpy ! Some functions will not be available !") + print "Warning: cannot import Numpy ! Some functions will not be available !" def getPopScores(population, fitness=False): - """ Returns a list of population scores + """ Returns a list of population scores - Example: - >>> lst = Interaction.getPopScores(population) + Example: + >>> lst = Interaction.getPopScores(population) - :param population: population object (:class:`GPopulation.GPopulation`) - :param fitness: if is True, the fitness score will be used, otherwise, the raw. - :rtype: list of population scores + :param population: population object (:class:`GPopulation.GPopulation`) + :param fitness: if is True, the fitness score will be used, otherwise, the raw. + :rtype: list of population scores + + """ + score_list = [] + for individual in population: + score_list.append(individual.fitness if fitness else individual.score) + return score_list - """ - score_list = [] - for individual in population: - score_list.append(individual.fitness if fitness else individual.score) - return score_list def plotPopScore(population, fitness=False): - """ Plot the population score distribution + """ Plot the population score distribution - Example: - >>> Interaction.plotPopScore(population) + Example: + >>> Interaction.plotPopScore(population) - :param population: population object (:class:`GPopulation.GPopulation`) - :param fitness: if is True, the fitness score will be used, otherwise, the raw. - :rtype: None + :param population: population object (:class:`GPopulation.GPopulation`) + :param fitness: if is True, the fitness score will be used, otherwise, the raw. + :rtype: None - """ - score_list = getPopScores(population, fitness) - pylab.plot(score_list, 'o') - pylab.title("Plot of population score distribution") - pylab.xlabel('Individual') - pylab.ylabel('Score') - pylab.grid(True) - pylab.show() + """ + score_list = getPopScores(population, fitness) + pylab.plot(score_list, 'o') + pylab.title("Plot of population score distribution") + pylab.xlabel('Individual') + pylab.ylabel('Score') + pylab.grid(True) + pylab.show() -def plotHistPopScore(population, fitness=False): - """ Population score distribution histogram - - Example: - >>> Interaction.plotHistPopScore(population) - - :param population: population object (:class:`GPopulation.GPopulation`) - :param fitness: if is True, the fitness score will be used, otherwise, the raw. - :rtype: None - - """ - score_list = getPopScores(population, fitness) - n, bins, patches = pylab.hist(score_list, 50, facecolor='green', alpha=0.75, normed=1) - pylab.plot(bins, pylab.normpdf(bins, numpy.mean(score_list), numpy.std(score_list)), 'r--') - pylab.xlabel('Score') - pylab.ylabel('Frequency') - pylab.grid(True) - pylab.title("Plot of population score distribution") - pylab.show() +def plotHistPopScore(population, fitness=False): + """ Population score distribution histogram + + Example: + >>> Interaction.plotHistPopScore(population) + + :param population: population object (:class:`GPopulation.GPopulation`) + :param fitness: if is True, the fitness score will be used, otherwise, the raw. + :rtype: None + + """ + score_list = getPopScores(population, fitness) + n, bins, patches = pylab.hist(score_list, 50, facecolor='green', alpha=0.75, normed=1) + pylab.plot(bins, pylab.normpdf(bins, numpy.mean(score_list), numpy.std(score_list)), 'r--') + pylab.xlabel('Score') + pylab.ylabel('Frequency') + pylab.grid(True) + pylab.title("Plot of population score distribution") + pylab.show() diff --git a/pyevolve/Migration.py b/pyevolve/Migration.py index 28c4940..25b762d 100644 --- a/pyevolve/Migration.py +++ b/pyevolve/Migration.py @@ -18,323 +18,330 @@ import logging try: - from mpi4py import MPI - HAS_MPI4PY = True + from mpi4py import MPI + HAS_MPI4PY = True except ImportError: - HAS_MPI4PY = False + HAS_MPI4PY = False + class MigrationScheme(object): - """ This is the base class for all migration schemes """ - - selector = None - """ This is the function slot for the selection method - if you want to change the default selector, you must do this: :: - - migration_scheme.selector.set(Selectors.GRouletteWheel) """ - - def __init__(self): - self.selector = FunctionSlot("Selector") - self.GAEngine = None - self.nMigrationRate = Consts.CDefGenMigrationRate - self.nIndividuals = Consts.CDefMigrationNIndividuals - self.nReplacement = Consts.CDefGenMigrationReplacement - self.networkCompression = 9 - - def isReady(self): - """ Returns true if is time to migrate """ - return True if self.GAEngine.getCurrentGeneration() % self.nMigrationRate == 0 else False - - def getCompressionLevel(self): - """ Get the zlib compression level of network data - - The values are in the interval described on the :func:`Network.pickleAndCompress` - """ - return self.networkCompression - - def setCompressionLevel(self, level): - """ Set the zlib compression level of network data - - The values are in the interval described on the :func:`Network.pickleAndCompress` - - :param level: the zlib compression level - """ - self.networkCompression = level - - def getNumReplacement(self): - """ Return the number of individuals that will be - replaced in the migration process """ - return self.nReplacement - - def setNumReplacement(self, num_individuals): - """ Return the number of individuals that will be - replaced in the migration process - - :param num_individuals: the number of individuals to be replaced - """ - self.nReplacement = num_individuals - - def getNumIndividuals(self): - """ Return the number of individuals that will migrate - - :rtype: the number of individuals to be replaced - """ - return self.nIndividuals - - def setNumIndividuals(self, num_individuals): - """ Set the number of individuals that will migrate - - :param num_individuals: the number of individuals - """ - self.nIndividuals = num_individuals - - def setMigrationRate(self, generations): - """ Sets the generation frequency supposed to migrate - and receive individuals. - - :param generations: the number of generations - """ - self.nMigrationRate = generations - - def getMigrationRate(self): - """ Return the the generation frequency supposed to migrate - and receive individuals - - :rtype: the number of generations - """ - return self.nMigrationRate - - def setGAEngine(self, ga_engine): - """ Sets the GA Engine handler """ - self.GAEngine = ga_engine - - def start(self): - """ Initializes the migration scheme """ - pass - - def stop(self): - """ Stops the migration engine """ - pass - - def select(self): - """ Pickes an individual from population using specific selection method - - :rtype: an individual object - """ - if self.selector.isEmpty(): - return self.GAEngine.select(popID=self.GAEngine.currentGeneration) - else: - for it in self.selector.applyFunctions(self.GAEngine.internalPop, - popID=self.GAEngine.currentGeneration): - return it - - def selectPool(self, num_individuals): - """ Select num_individuals number of individuals and return a pool - - :param num_individuals: the number of individuals to select - :rtype: list with individuals - """ - pool = [self.select() for i in xrange(num_individuals)] - return pool - - def exchange(self): - """ Exchange individuals """ - pass + """ This is the base class for all migration schemes """ + + selector = None + """ This is the function slot for the selection method + if you want to change the default selector, you must do this: :: + + migration_scheme.selector.set(Selectors.GRouletteWheel) """ + + def __init__(self): + self.selector = FunctionSlot("Selector") + self.GAEngine = None + self.nMigrationRate = Consts.CDefGenMigrationRate + self.nIndividuals = Consts.CDefMigrationNIndividuals + self.nReplacement = Consts.CDefGenMigrationReplacement + self.networkCompression = 9 + + def isReady(self): + """ Returns true if is time to migrate """ + return self.GAEngine.getCurrentGeneration() % self.nMigrationRate == 0 + + def getCompressionLevel(self): + """ Get the zlib compression level of network data + + The values are in the interval described on the :func:`Network.pickleAndCompress` + """ + return self.networkCompression + + def setCompressionLevel(self, level): + """ Set the zlib compression level of network data + + The values are in the interval described on the :func:`Network.pickleAndCompress` + + :param level: the zlib compression level + """ + self.networkCompression = level + + def getNumReplacement(self): + """ Return the number of individuals that will be + replaced in the migration process """ + return self.nReplacement + + def setNumReplacement(self, num_individuals): + """ Return the number of individuals that will be + replaced in the migration process + + :param num_individuals: the number of individuals to be replaced + """ + self.nReplacement = num_individuals + + def getNumIndividuals(self): + """ Return the number of individuals that will migrate + + :rtype: the number of individuals to be replaced + """ + return self.nIndividuals + + def setNumIndividuals(self, num_individuals): + """ Set the number of individuals that will migrate + + :param num_individuals: the number of individuals + """ + self.nIndividuals = num_individuals + + def setMigrationRate(self, generations): + """ Sets the generation frequency supposed to migrate + and receive individuals. + + :param generations: the number of generations + """ + self.nMigrationRate = generations + + def getMigrationRate(self): + """ Return the the generation frequency supposed to migrate + and receive individuals + + :rtype: the number of generations + """ + return self.nMigrationRate + + def setGAEngine(self, ga_engine): + """ Sets the GA Engine handler """ + self.GAEngine = ga_engine + + def start(self): + """ Initializes the migration scheme """ + pass + + def stop(self): + """ Stops the migration engine """ + pass + + def select(self): + """ Pickes an individual from population using specific selection method + + :rtype: an individual object + """ + if self.selector.isEmpty(): + return self.GAEngine.select(popID=self.GAEngine.currentGeneration) + else: + for it in self.selector.applyFunctions(self.GAEngine.internalPop, + popID=self.GAEngine.currentGeneration): + return it + + def selectPool(self, num_individuals): + """ Select num_individuals number of individuals and return a pool + + :param num_individuals: the number of individuals to select + :rtype: list with individuals + """ + pool = [self.select() for i in xrange(num_individuals)] + return pool + + def exchange(self): + """ Exchange individuals """ + pass class WANMigration(MigrationScheme): - """ This is the Simple Migration class for distributed GA - - Example: - >>> mig = WANMigration("192.168.0.1", "10000", "group1") - - :param host: the source hostname - :param port: the source port number - :param group_name: the group name - """ - - selector = None - """ This is the function slot for the selection method - if you want to change the default selector, you must do this: :: - - migration_scheme.selector.set(Selectors.GRouletteWheel) """ - - def __init__(self, host, port, group_name): - super(WANMigration, self).__init__() - self.setMyself(host, port) - self.setGroupName(group_name) - self.topologyGraph = None - self.serverThread = Network.UDPThreadServer(host, port) - self.clientThread = Network.UDPThreadUnicastClient(self.myself[0], rand_randint(30000, 65534)) - - def setMyself(self, host, port): - """ Which interface you will use to send/receive data - - :param host: your hostname - :param port: your port - """ - self.myself = (host, port) - - def getGroupName(self): - """ Gets the group name - - .. note:: all islands of evolution which are supposed to exchange - individuals, must have the same group name. - """ - return self.groupName - - def setGroupName(self, name): - """ Sets the group name - - :param name: the group name - - .. note:: all islands of evolution which are supposed to exchange - individuals, must have the same group name. - """ - self.groupName = name - - def setTopology(self, graph): - """ Sets the topology of the migrations - - :param graph: the :class:`Util.Graph` instance - """ - self.topologyGraph = graph - - def start(self): - """ Start capture of packets and initialize the migration scheme """ - self.serverThread.start() - - if self.topologyGraph is None: - Util.raiseException("You must add a topology graph to the migration scheme !") - - # targets = [ (ip, port), (ip, port), ...] - targets = self.topologyGraph.getNeighbors(self.myself) - self.clientThread.setMultipleTargetHost(targets) - self.clientThread.start() - - def stop(self): - """ Stops the migration engine """ - self.serverThread.shutdown() - self.clientThread.shutdown() - server_timeout = self.serverThread.timeout - client_timeout = self.clientThread.timeout - - self.serverThread.join(server_timeout+3) - self.clientThread.join(client_timeout+3) - - if self.serverThread.isAlive(): - logging.warning("warning: server thread not joined !") - - if self.clientThread.isAlive(): - logging.warning("warning: client thread not joined !") - - - def exchange(self): - """ This is the main method, is where the individuals - are exchanged """ - - if not self.isReady(): return - - # Client section -------------------------------------- - # How many will migrate ? - pool = self.selectPool(self.getNumIndividuals()) - - for individual in pool: - # (code, group name, individual) - networkObject = (Consts.CDefNetworkIndividual, self.getGroupName(), individual) - networkData = Network.pickleAndCompress(networkObject, self.getCompressionLevel()) - # Send the individuals to the topology - self.clientThread.addData(networkData) - - # Server section -------------------------------------- - pool = [] - while self.serverThread.isReady(): - # (IP source, data) - networkData = self.serverThread.popPool() - networkObject = Network.unpickleAndDecompress(networkData[1]) - # (code, group name, individual) - pool.append(networkObject) - - # No individuals received - if len(pool) <= 0: return - - population = self.GAEngine.getPopulation() - - for i in xrange(self.getNumReplacement()): - if len(pool) <= 0: break - choice = rand_choice(pool) - pool.remove(choice) - - # replace the worst - population[len(population)-1-i] = choice[2] + """ This is the Simple Migration class for distributed GA + + Example: + >>> mig = WANMigration("192.168.0.1", "10000", "group1") + + :param host: the source hostname + :param port: the source port number + :param group_name: the group name + """ + + selector = None + """ This is the function slot for the selection method + if you want to change the default selector, you must do this: :: + + migration_scheme.selector.set(Selectors.GRouletteWheel) """ + + def __init__(self, host, port, group_name): + super(WANMigration, self).__init__() + self.setMyself(host, port) + self.setGroupName(group_name) + self.topologyGraph = None + self.serverThread = Network.UDPThreadServer(host, port) + self.clientThread = Network.UDPThreadUnicastClient(self.myself[0], rand_randint(30000, 65534)) + + def setMyself(self, host, port): + """ Which interface you will use to send/receive data + + :param host: your hostname + :param port: your port + """ + self.myself = (host, port) + + def getGroupName(self): + """ Gets the group name + + .. note:: all islands of evolution which are supposed to exchange + individuals, must have the same group name. + """ + return self.groupName + + def setGroupName(self, name): + """ Sets the group name + + :param name: the group name + + .. note:: all islands of evolution which are supposed to exchange + individuals, must have the same group name. + """ + self.groupName = name + + def setTopology(self, graph): + """ Sets the topology of the migrations + + :param graph: the :class:`Util.Graph` instance + """ + self.topologyGraph = graph + + def start(self): + """ Start capture of packets and initialize the migration scheme """ + self.serverThread.start() + + if self.topologyGraph is None: + Util.raiseException("You must add a topology graph to the migration scheme !") + + # targets = [ (ip, port), (ip, port), ...] + targets = self.topologyGraph.getNeighbors(self.myself) + self.clientThread.setMultipleTargetHost(targets) + self.clientThread.start() + + def stop(self): + """ Stops the migration engine """ + self.serverThread.shutdown() + self.clientThread.shutdown() + server_timeout = self.serverThread.timeout + client_timeout = self.clientThread.timeout + + self.serverThread.join(server_timeout+3) + self.clientThread.join(client_timeout+3) + + if self.serverThread.isAlive(): + logging.warning("warning: server thread not joined !") + + if self.clientThread.isAlive(): + logging.warning("warning: client thread not joined !") + + def exchange(self): + """ This is the main method, is where the individuals + are exchanged """ + + if not self.isReady(): + return + + # Client section -------------------------------------- + # How many will migrate ? + pool = self.selectPool(self.getNumIndividuals()) + + for individual in pool: + # (code, group name, individual) + networkObject = (Consts.CDefNetworkIndividual, self.getGroupName(), individual) + networkData = Network.pickleAndCompress(networkObject, self.getCompressionLevel()) + # Send the individuals to the topology + self.clientThread.addData(networkData) + + # Server section -------------------------------------- + pool = [] + while self.serverThread.isReady(): + # (IP source, data) + networkData = self.serverThread.popPool() + networkObject = Network.unpickleAndDecompress(networkData[1]) + # (code, group name, individual) + pool.append(networkObject) + + # No individuals received + if len(pool) <= 0: + return + + population = self.GAEngine.getPopulation() + + for i in xrange(self.getNumReplacement()): + if len(pool) <= 0: + break + choice = rand_choice(pool) + pool.remove(choice) + + # replace the worst + population[len(population)-1-i] = choice[2] class MPIMigration(MigrationScheme): - """ This is the MPIMigration """ + """ This is the MPIMigration """ + + def __init__(self): + # Delayed ImportError of mpi4py + if not HAS_MPI4PY: + raise ImportError("No module named mpi4py, you must install mpi4py to use MPIMIgration !") - def __init__(self): - # Delayed ImportError of mpi4py - if not HAS_MPI4PY: - raise ImportError, "No module named mpi4py, you must install mpi4py to use MPIMIgration !" + super(MPIMigration, self).__init__() - super(MPIMigration, self).__init__() + self.comm = MPI.COMM_WORLD + self.pid = self.comm.rank - self.comm = MPI.COMM_WORLD - self.pid = self.comm.rank + if self.pid == 0: + self.source = self.comm.size - 1 + else: + self.source = self.comm.rank - 1 - if self.pid == 0: - self.source = self.comm.size - 1 - else: - self.source = self.comm.rank - 1 - - self.dest = (self.comm.rank +1) % (self.comm.size) + self.dest = (self.comm.rank + 1) % (self.comm.size) - self.all_stars = None + self.all_stars = None - def isReady(self): - """ Returns true if is time to migrate """ + def isReady(self): + """ Returns true if is time to migrate """ - if self.GAEngine.getCurrentGeneration() == 0: - return False + if self.GAEngine.getCurrentGeneration() == 0: + return False - if self.GAEngine.getCurrentGeneration() % self.nMigrationRate == 0: - return True - else: - return False + if self.GAEngine.getCurrentGeneration() % self.nMigrationRate == 0: + return True + else: + return False - def gather_bests(self): - ''' - Collect all the best individuals from the various populations. The - result is stored in process 0 - ''' - best_guy = self.selector(self.GAEngine.internalPop, - popID=self.GAEngine.currentGeneration) + def gather_bests(self): + """ Collect all the best individuals from the various populations. The + result is stored in process 0""" + best_guy = self.selector( + self.GAEngine.internalPop, + popID=self.GAEngine.currentGeneration + ) - self.all_stars = self.comm.gather(sendobj = best_guy, root = 0) + self.all_stars = self.comm.gather(sendobj=best_guy, root=0) - def exchange(self): - """ This is the main method, is where the individuals - are exchanged """ + def exchange(self): + """ This is the main method, is where the individuals + are exchanged""" - if not self.isReady(): return + if not self.isReady(): + return - pool_to_send = self.selectPool(self.getNumIndividuals()) - pool_received = self.comm.sendrecv(sendobj=pool_to_send, - dest=self.dest, - sendtag=0, - recvobj=None, - source=self.source, - recvtag=0) + pool_to_send = self.selectPool(self.getNumIndividuals()) + pool_received = self.comm.sendrecv( + sendobj=pool_to_send, + dest=self.dest, + sendtag=0, + recvobj=None, + source=self.source, + recvtag=0 + ) - population = self.GAEngine.getPopulation() + population = self.GAEngine.getPopulation() - pool = pool_received - for i in xrange(self.getNumReplacement()): - if len(pool) <= 0: break + pool = pool_received + for i in xrange(self.getNumReplacement()): + if len(pool) <= 0: + break - choice = rand_choice(pool) - pool.remove(choice) + choice = rand_choice(pool) + pool.remove(choice) - # replace the worst - population[len(population)-1-i] = choice + # replace the worst + population[len(population)-1-i] = choice - self.gather_bests() + self.gather_bests() diff --git a/pyevolve/Mutators.py b/pyevolve/Mutators.py index 8c275ac..7e08aec 100644 --- a/pyevolve/Mutators.py +++ b/pyevolve/Mutators.py @@ -13,928 +13,988 @@ import Consts import GTree + ############################# ## 1D Binary String ## ############################# def G1DBinaryStringMutatorSwap(genome, **args): - """ The 1D Binary String Swap Mutator """ - - if args["pmut"] <= 0.0: return 0 - stringLength = len(genome) - mutations = args["pmut"] * (stringLength) - - if mutations < 1.0: - mutations = 0 - for it in xrange(stringLength): - if Util.randomFlipCoin(args["pmut"]): - Util.listSwapElement(genome, it, rand_randint(0, stringLength-1)) - mutations+=1 - - else: - for it in xrange(int(round(mutations))): - Util.listSwapElement(genome, rand_randint(0, stringLength-1), - rand_randint(0, stringLength-1)) - - return int(mutations) + """ The 1D Binary String Swap Mutator """ + + if args["pmut"] <= 0.0: + return 0 + stringLength = len(genome) + mutations = args["pmut"] * (stringLength) + + if mutations < 1.0: + mutations = 0 + for it in xrange(stringLength): + if Util.randomFlipCoin(args["pmut"]): + Util.listSwapElement(genome, it, rand_randint(0, stringLength-1)) + mutations += 1 + + else: + for it in xrange(int(round(mutations))): + Util.listSwapElement(genome, rand_randint(0, stringLength-1), + rand_randint(0, stringLength-1)) + + return int(mutations) + def G1DBinaryStringMutatorFlip(genome, **args): - """ The classical flip mutator for binary strings """ - if args["pmut"] <= 0.0: return 0 - stringLength = len(genome) - mutations = args["pmut"] * (stringLength) - - if mutations < 1.0: - mutations = 0 - for it in xrange(stringLength): - if Util.randomFlipCoin(args["pmut"]): - if genome[it] == 0: genome[it] = 1 - else: genome[it] = 0 - mutations+=1 - - else: - for it in xrange(int(round(mutations))): - which = rand_randint(0, stringLength-1) - if genome[which] == 0: genome[which] = 1 - else: genome[which] = 0 - - return int(mutations) + """ The classical flip mutator for binary strings """ + if args["pmut"] <= 0.0: + return 0 + stringLength = len(genome) + mutations = args["pmut"] * stringLength + + if mutations < 1.0: + mutations = 0 + for it in xrange(stringLength): + if Util.randomFlipCoin(args["pmut"]): + genome[it] = 1 if genome[it] == 0 else 0 + mutations += 1 + + else: + for it in xrange(int(round(mutations))): + which = rand_randint(0, stringLength-1) + if genome[which] == 0: + genome[which] = 1 + else: + genome[which] = 0 + + return int(mutations) + #################### ## 1D List ## #################### def G1DListMutatorSwap(genome, **args): - """ The mutator of G1DList, Swap Mutator - - .. note:: this mutator is :term:`Data Type Independent` - - """ - if args["pmut"] <= 0.0: return 0 - listSize = len(genome) - 1 - mutations = args["pmut"] * (listSize+1) - - if mutations < 1.0: - mutations = 0 - for it in xrange(listSize+1): - if Util.randomFlipCoin(args["pmut"]): - Util.listSwapElement(genome, it, rand_randint(0, listSize)) - mutations+=1 - else: - for it in xrange(int(round(mutations))): - Util.listSwapElement(genome, rand_randint(0, listSize), rand_randint(0, listSize)) - - return int(mutations) + """ The mutator of G1DList, Swap Mutator + + .. note:: this mutator is :term:`Data Type Independent` + + """ + if args["pmut"] <= 0.0: + return 0 + listSize = len(genome) - 1 + mutations = args["pmut"] * (listSize+1) + + if mutations < 1.0: + mutations = 0 + for it in xrange(listSize+1): + if Util.randomFlipCoin(args["pmut"]): + Util.listSwapElement(genome, it, rand_randint(0, listSize)) + mutations += 1 + else: + for it in xrange(int(round(mutations))): + Util.listSwapElement(genome, rand_randint(0, listSize), rand_randint(0, listSize)) + + return int(mutations) + def G1DListMutatorSIM(genome, **args): - """ The mutator of G1DList, Simple Inversion Mutation - - .. note:: this mutator is :term:`Data Type Independent` + """ The mutator of G1DList, Simple Inversion Mutation + + .. note:: this mutator is :term:`Data Type Independent` + + """ + mutations = 0 + if args["pmut"] <= 0.0: + return 0 - """ - mutations = 0 - if args["pmut"] <= 0.0: return 0 + cuts = [rand_randint(0, len(genome)), rand_randint(0, len(genome))] - cuts = [rand_randint(0, len(genome)), rand_randint(0, len(genome))] + if cuts[0] > cuts[1]: + Util.listSwapElement(cuts, 0, 1) - if cuts[0] > cuts[1]: - Util.listSwapElement(cuts, 0, 1) + if (cuts[1]-cuts[0]) <= 0: + cuts[1] = rand_randint(cuts[0], len(genome)) - if (cuts[1]-cuts[0]) <= 0: - cuts[1] = rand_randint(cuts[0], len(genome)) + if Util.randomFlipCoin(args["pmut"]): + part = genome[cuts[0]:cuts[1]] + if len(part) == 0: + return 0 + part.reverse() + genome[cuts[0]:cuts[1]] = part + mutations += 1 + + return mutations - if Util.randomFlipCoin(args["pmut"]): - part = genome[cuts[0]:cuts[1]] - if len(part) == 0: return 0 - part.reverse() - genome[cuts[0]:cuts[1]] = part - mutations += 1 - - return mutations def G1DListMutatorIntegerRange(genome, **args): - """ Simple integer range mutator for G1DList + """ Simple integer range mutator for G1DList - Accepts the *rangemin* and *rangemax* genome parameters, both optional. + Accepts the *rangemin* and *rangemax* genome parameters, both optional. - """ - if args["pmut"] <= 0.0: return 0 - listSize = len(genome) - mutations = args["pmut"] * listSize + """ + if args["pmut"] <= 0.0: + return 0 + listSize = len(genome) + mutations = args["pmut"] * listSize - if mutations < 1.0: - mutations = 0 - for it in xrange(listSize): - if Util.randomFlipCoin(args["pmut"]): - genome[it] = rand_randint(genome.getParam("rangemin", Consts.CDefRangeMin), - genome.getParam("rangemax", Consts.CDefRangeMax)) - mutations += 1 - - else: - for it in xrange(int(round(mutations))): - which_gene = rand_randint(0, listSize-1) - genome[which_gene] = rand_randint(genome.getParam("rangemin", Consts.CDefRangeMin), - genome.getParam("rangemax", Consts.CDefRangeMax)) + if mutations < 1.0: + mutations = 0 + for it in xrange(listSize): + if Util.randomFlipCoin(args["pmut"]): + genome[it] = rand_randint( + genome.getParam("rangemin", Consts.CDefRangeMin), + genome.getParam("rangemax", Consts.CDefRangeMax) + ) + mutations += 1 - return int(mutations) + else: + for it in xrange(int(round(mutations))): + which_gene = rand_randint(0, listSize-1) + genome[which_gene] = rand_randint( + genome.getParam("rangemin", Consts.CDefRangeMin), + genome.getParam("rangemax", Consts.CDefRangeMax) + ) + + return int(mutations) def G1DListMutatorRealRange(genome, **args): - """ Simple real range mutator for G1DList + """ Simple real range mutator for G1DList - Accepts the *rangemin* and *rangemax* genome parameters, both optional. + Accepts the *rangemin* and *rangemax* genome parameters, both optional. - """ - if args["pmut"] <= 0.0: return 0 - listSize = len(genome) - mutations = args["pmut"] * (listSize) + """ + if args["pmut"] <= 0.0: + return 0 + listSize = len(genome) + mutations = args["pmut"] * (listSize) - if mutations < 1.0: - mutations = 0 - for it in xrange(listSize): - if Util.randomFlipCoin(args["pmut"]): - genome[it] = rand_uniform(genome.getParam("rangemin", Consts.CDefRangeMin), - genome.getParam("rangemax", Consts.CDefRangeMax)) - mutations += 1 - - else: - for it in xrange(int(round(mutations))): - which_gene = rand_randint(0, listSize-1) - genome[which_gene] = rand_uniform(genome.getParam("rangemin", Consts.CDefRangeMin), - genome.getParam("rangemax", Consts.CDefRangeMax)) + if mutations < 1.0: + mutations = 0 + for it in xrange(listSize): + if Util.randomFlipCoin(args["pmut"]): + genome[it] = rand_uniform( + genome.getParam("rangemin", Consts.CDefRangeMin), + genome.getParam("rangemax", Consts.CDefRangeMax) + ) + mutations += 1 + + else: + for it in xrange(int(round(mutations))): + which_gene = rand_randint(0, listSize-1) + genome[which_gene] = rand_uniform( + genome.getParam("rangemin", Consts.CDefRangeMin), + genome.getParam("rangemax", Consts.CDefRangeMax) + ) + + return int(mutations) - return int(mutations) def G1DListMutatorIntegerGaussianGradient(genome, **args): - """ A gaussian mutator for G1DList of Integers - - Accepts the *rangemin* and *rangemax* genome parameters, both optional. The - random distribution is set with mu=1.0 and std=0.0333 - - Same as IntegerGaussian, except that this uses relative gradient rather than - absolute gaussian. A value is randomly generated about gauss(mu=1, sigma=.0333) - and multiplied by the gene to drift it up or down (depending on what side of - 1 the random value falls on) and cast to integer - - """ - if args["pmut"] <= 0.0: return 0 - listSize = len(genome) - mutations = args["pmut"] * (listSize) - - mu = Consts.CDefGaussianGradientMU - sigma = Consts.CDefGaussianGradientSIGMA - - if mutations < 1.0: - mutations = 0 - for it in xrange(listSize): - if Util.randomFlipCoin(args["pmut"]): - final_value = int(genome[it] * abs(rand_gauss(mu, sigma))) + """ A gaussian mutator for G1DList of Integers + + Accepts the *rangemin* and *rangemax* genome parameters, both optional. The + random distribution is set with mu=1.0 and std=0.0333 + + Same as IntegerGaussian, except that this uses relative gradient rather than + absolute gaussian. A value is randomly generated about gauss(mu=1, sigma=.0333) + and multiplied by the gene to drift it up or down (depending on what side of + 1 the random value falls on) and cast to integer + + """ + if args["pmut"] <= 0.0: + return 0 + listSize = len(genome) + mutations = args["pmut"] * listSize + + mu = Consts.CDefGaussianGradientMU + sigma = Consts.CDefGaussianGradientSIGMA + + if mutations < 1.0: + mutations = 0 + for it in xrange(listSize): + if Util.randomFlipCoin(args["pmut"]): + final_value = int(genome[it] * abs(rand_gauss(mu, sigma))) + + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + + genome[it] = final_value + mutations += 1 + else: + for it in xrange(int(round(mutations))): + which_gene = rand_randint(0, listSize-1) + final_value = int(genome[which_gene] * abs(rand_gauss(mu, sigma))) final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - genome[it] = final_value - mutations += 1 - else: - for it in xrange(int(round(mutations))): - which_gene = rand_randint(0, listSize-1) - final_value = int(genome[which_gene] * abs(rand_gauss(mu, sigma))) - - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + genome[which_gene] = final_value - genome[which_gene] = final_value + return int(mutations) - return int(mutations) def G1DListMutatorIntegerGaussian(genome, **args): - """ A gaussian mutator for G1DList of Integers - - Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also - accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively - represents the mean and the std. dev. of the random distribution. - - """ - if args["pmut"] <= 0.0: return 0 - listSize = len(genome) - mutations = args["pmut"] * (listSize) - - mu = genome.getParam("gauss_mu") - sigma = genome.getParam("gauss_sigma") - - if mu is None: - mu = Consts.CDefG1DListMutIntMU - - if sigma is None: - sigma = Consts.CDefG1DListMutIntSIGMA - - if mutations < 1.0: - mutations = 0 - for it in xrange(listSize): - if Util.randomFlipCoin(args["pmut"]): - final_value = genome[it] + int(rand_gauss(mu, sigma)) + """ A gaussian mutator for G1DList of Integers + + Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also + accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively + represents the mean and the std. dev. of the random distribution. + + """ + if args["pmut"] <= 0.0: + return 0 + listSize = len(genome) + mutations = args["pmut"] * (listSize) + + mu = genome.getParam("gauss_mu") + sigma = genome.getParam("gauss_sigma") + + if mu is None: + mu = Consts.CDefG1DListMutIntMU + + if sigma is None: + sigma = Consts.CDefG1DListMutIntSIGMA + + if mutations < 1.0: + mutations = 0 + for it in xrange(listSize): + if Util.randomFlipCoin(args["pmut"]): + final_value = genome[it] + int(rand_gauss(mu, sigma)) + + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + + genome[it] = final_value + mutations += 1 + else: + for it in xrange(int(round(mutations))): + which_gene = rand_randint(0, listSize-1) + final_value = genome[which_gene] + int(rand_gauss(mu, sigma)) final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - genome[it] = final_value - mutations += 1 - else: - for it in xrange(int(round(mutations))): - which_gene = rand_randint(0, listSize-1) - final_value = genome[which_gene] + int(rand_gauss(mu, sigma)) + genome[which_gene] = final_value - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + return int(mutations) - genome[which_gene] = final_value - return int(mutations) +def G1DListMutatorRealGaussian(genome, **args): + """ The mutator of G1DList, Gaussian Mutator + Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also + accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively + represents the mean and the std. dev. of the random distribution. -def G1DListMutatorRealGaussian(genome, **args): - """ The mutator of G1DList, Gaussian Mutator + """ + if args["pmut"] <= 0.0: + return 0 + listSize = len(genome) + mutations = args["pmut"] * (listSize) + + mu = genome.getParam("gauss_mu") + sigma = genome.getParam("gauss_sigma") - Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also - accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively - represents the mean and the std. dev. of the random distribution. + if mu is None: + mu = Consts.CDefG1DListMutRealMU - """ - if args["pmut"] <= 0.0: return 0 - listSize = len(genome) - mutations = args["pmut"] * (listSize) + if sigma is None: + sigma = Consts.CDefG1DListMutRealSIGMA - mu = genome.getParam("gauss_mu") - sigma = genome.getParam("gauss_sigma") + if mutations < 1.0: + mutations = 0 + for it in xrange(listSize): + if Util.randomFlipCoin(args["pmut"]): + final_value = genome[it] + rand_gauss(mu, sigma) - if mu is None: - mu = Consts.CDefG1DListMutRealMU - - if sigma is None: - sigma = Consts.CDefG1DListMutRealSIGMA + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - if mutations < 1.0: - mutations = 0 - for it in xrange(listSize): - if Util.randomFlipCoin(args["pmut"]): - final_value = genome[it] + rand_gauss(mu, sigma) + genome[it] = final_value + mutations += 1 + else: + for it in xrange(int(round(mutations))): + which_gene = rand_randint(0, listSize-1) + final_value = genome[which_gene] + rand_gauss(mu, sigma) final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - genome[it] = final_value - mutations += 1 - else: - for it in xrange(int(round(mutations))): - which_gene = rand_randint(0, listSize-1) - final_value = genome[which_gene] + rand_gauss(mu, sigma) - - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + genome[which_gene] = final_value - genome[which_gene] = final_value + return int(mutations) - return int(mutations) def G1DListMutatorRealGaussianGradient(genome, **args): - """ The mutator of G1DList, Gaussian Gradient Mutator - - Accepts the *rangemin* and *rangemax* genome parameters, both optional. The - random distribution is set with mu=1.0 and std=0.0333 - - The difference between this routine and the normal Gaussian Real is that the - other function generates a gaussian value and adds it to the value. If the - mu is 0, and the std is 1, a typical value could be 1.8 or -0.5. These small - values are fine if your range is 0-10, but if your range is much larger, like - 0-100,000, a relative gradient makes sense. - - This routine generates a gaussian value with mu=1.0 and std=0.0333 and then - the gene is multiplied by this value. This will cause the gene to drift - no matter how large it is. - - """ - if args["pmut"] <= 0.0: return 0 - listSize = len(genome) - mutations = args["pmut"] * (listSize) - - mu = Consts.CDefGaussianGradientMU - sigma = Consts.CDefGaussianGradientSIGMA - - if mutations < 1.0: - mutations = 0 - for it in xrange(listSize): - if Util.randomFlipCoin(args["pmut"]): - final_value = genome[it] * abs(rand_gauss(mu, sigma)) + """ The mutator of G1DList, Gaussian Gradient Mutator + + Accepts the *rangemin* and *rangemax* genome parameters, both optional. The + random distribution is set with mu=1.0 and std=0.0333 + + The difference between this routine and the normal Gaussian Real is that the + other function generates a gaussian value and adds it to the value. If the + mu is 0, and the std is 1, a typical value could be 1.8 or -0.5. These small + values are fine if your range is 0-10, but if your range is much larger, like + 0-100,000, a relative gradient makes sense. + + This routine generates a gaussian value with mu=1.0 and std=0.0333 and then + the gene is multiplied by this value. This will cause the gene to drift + no matter how large it is. + + """ + if args["pmut"] <= 0.0: + return 0 + listSize = len(genome) + mutations = args["pmut"] * listSize + + mu = Consts.CDefGaussianGradientMU + sigma = Consts.CDefGaussianGradientSIGMA + + if mutations < 1.0: + mutations = 0 + for it in xrange(listSize): + if Util.randomFlipCoin(args["pmut"]): + final_value = genome[it] * abs(rand_gauss(mu, sigma)) + + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + + genome[it] = final_value + mutations += 1 + else: + for it in xrange(int(round(mutations))): + which_gene = rand_randint(0, listSize-1) + final_value = genome[which_gene] * abs(rand_gauss(mu, sigma)) final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - genome[it] = final_value - mutations += 1 - else: - for it in xrange(int(round(mutations))): - which_gene = rand_randint(0, listSize-1) - final_value = genome[which_gene] * abs(rand_gauss(mu, sigma)) - - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + genome[which_gene] = final_value - genome[which_gene] = final_value + return int(mutations) - return int(mutations) def G1DListMutatorIntegerBinary(genome, **args): - """ The mutator of G1DList, the binary mutator + """ The mutator of G1DList, the binary mutator - This mutator will random change the 0 and 1 elements of the 1D List. + This mutator will random change the 0 and 1 elements of the 1D List. - """ - if args["pmut"] <= 0.0: return 0 - listSize = len(genome) - mutations = args["pmut"] * (listSize) + """ + if args["pmut"] <= 0.0: + return 0 + listSize = len(genome) + mutations = args["pmut"] * (listSize) - if mutations < 1.0: - mutations = 0 - for it in xrange(listSize): - if Util.randomFlipCoin(args["pmut"]): - if genome[it] == 0: genome[it] = 1 - elif genome[it] == 1: genome[it] = 0 + if mutations < 1.0: + mutations = 0 + for it in xrange(listSize): + if Util.randomFlipCoin(args["pmut"]): + if genome[it] == 0: + genome[it] = 1 + elif genome[it] == 1: + genome[it] = 0 - mutations += 1 - else: - for it in xrange(int(round(mutations))): - which_gene = rand_randint(0, listSize-1) - if genome[which_gene] == 0: genome[which_gene] = 1 - elif genome[which_gene] == 1: genome[which_gene] = 0 + mutations += 1 + else: + for it in xrange(int(round(mutations))): + which_gene = rand_randint(0, listSize-1) + if genome[which_gene] == 0: + genome[which_gene] = 1 + elif genome[which_gene] == 1: + genome[which_gene] = 0 + + return int(mutations) - return int(mutations) 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) - 1 - mutations = args["pmut"] * (listSize+1) - - allele = genome.getParam("allele", None) - if allele is None: - Util.raiseException("to use the G1DListMutatorAllele, you must specify the 'allele' parameter", TypeError) - - if mutations < 1.0: - mutations = 0 - for it in xrange(listSize+1): - if Util.randomFlipCoin(args["pmut"]): - new_val = allele[it].getRandomAllele() - genome[it] = new_val - mutations+=1 - else: - for it in xrange(int(round(mutations))): - which_gene = rand_randint(0, listSize) - new_val = allele[which_gene].getRandomAllele() - genome[which_gene] = new_val - - return int(mutations) + """ 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) - 1 + mutations = args["pmut"] * (listSize+1) + + allele = genome.getParam("allele", None) + if allele is None: + Util.raiseException("to use the G1DListMutatorAllele, you must specify the 'allele' parameter", TypeError) + + if mutations < 1.0: + mutations = 0 + for it in xrange(listSize+1): + if Util.randomFlipCoin(args["pmut"]): + new_val = allele[it].getRandomAllele() + genome[it] = new_val + mutations += 1 + else: + for it in xrange(int(round(mutations))): + which_gene = rand_randint(0, listSize) + new_val = allele[which_gene].getRandomAllele() + genome[which_gene] = new_val + + return int(mutations) + #################### ## 2D List ## #################### def G2DListMutatorSwap(genome, **args): - """ The mutator of G1DList, Swap Mutator - - .. note:: this mutator is :term:`Data Type Independent` - - """ - - if args["pmut"] <= 0.0: return 0 - height, width = genome.getSize() - elements = height * width - - mutations = args["pmut"] * elements - - if mutations < 1.0: - mutations = 0 - for i in xrange(height): - for j in xrange(width): - if Util.randomFlipCoin(args["pmut"]): - index_b = (rand_randint(0, height-1), rand_randint(0, width-1)) - Util.list2DSwapElement(genome.genomeList, (i,j), index_b) - mutations+=1 - else: - for it in xrange(int(round(mutations))): - index_a = (rand_randint(0, height-1), rand_randint(0, width-1)) - index_b = (rand_randint(0, height-1), rand_randint(0, width-1)) - Util.list2DSwapElement(genome.genomeList, index_a, index_b) + """ The mutator of G1DList, Swap Mutator - return int(mutations) + .. note:: this mutator is :term:`Data Type Independent` -def G2DListMutatorIntegerRange(genome, **args): - """ Simple integer range mutator for G2DList + """ - Accepts the *rangemin* and *rangemax* genome parameters, both optional. + if args["pmut"] <= 0.0: + return 0 + height, width = genome.getSize() + elements = height * width - """ - if args["pmut"] <= 0.0: return 0 - height, width = genome.getSize() - elements = height * width + mutations = args["pmut"] * elements - mutations = args["pmut"] * elements + if mutations < 1.0: + mutations = 0 + for i in xrange(height): + for j in xrange(width): + if Util.randomFlipCoin(args["pmut"]): + index_b = (rand_randint(0, height-1), rand_randint(0, width-1)) + Util.list2DSwapElement(genome.genomeList, (i, j), index_b) + mutations += 1 + else: + for it in xrange(int(round(mutations))): + index_a = (rand_randint(0, height-1), rand_randint(0, width-1)) + index_b = (rand_randint(0, height-1), rand_randint(0, width-1)) + Util.list2DSwapElement(genome.genomeList, index_a, index_b) - range_min = genome.getParam("rangemin", Consts.CDefRangeMin) - range_max = genome.getParam("rangemax", Consts.CDefRangeMax) + return int(mutations) - if mutations < 1.0: - mutations = 0 - for i in xrange(genome.getHeight()): - for j in xrange(genome.getWidth()): - if Util.randomFlipCoin(args["pmut"]): - random_int = rand_randint(range_min, range_max) - genome.setItem(i, j, random_int) - mutations += 1 - else: - for it in xrange(int(round(mutations))): - which_x = rand_randint(0, genome.getWidth()-1) - which_y = rand_randint(0, genome.getHeight()-1) - random_int = rand_randint(range_min, range_max) - genome.setItem(which_y, which_x, random_int) +def G2DListMutatorIntegerRange(genome, **args): + """ Simple integer range mutator for G2DList + + Accepts the *rangemin* and *rangemax* genome parameters, both optional. + + """ + if args["pmut"] <= 0.0: + return 0 + height, width = genome.getSize() + elements = height * width + + mutations = args["pmut"] * elements + + range_min = genome.getParam("rangemin", Consts.CDefRangeMin) + range_max = genome.getParam("rangemax", Consts.CDefRangeMax) + + if mutations < 1.0: + mutations = 0 + for i in xrange(genome.getHeight()): + for j in xrange(genome.getWidth()): + if Util.randomFlipCoin(args["pmut"]): + random_int = rand_randint(range_min, range_max) + genome.setItem(i, j, random_int) + mutations += 1 + + else: + for it in xrange(int(round(mutations))): + which_x = rand_randint(0, genome.getWidth()-1) + which_y = rand_randint(0, genome.getHeight()-1) + random_int = rand_randint(range_min, range_max) + genome.setItem(which_y, which_x, random_int) - return int(mutations) + return int(mutations) def G2DListMutatorIntegerGaussianGradient(genome, **args): - """ A gaussian mutator for G2DList of Integers + """ A gaussian mutator for G2DList of Integers - Accepts the *rangemin* and *rangemax* genome parameters, both optional. - - This routine generates a gaussian value with mu=1.0 and std=0.0333 and then - the gene is multiplied by this value. This will cause the gene to drift - no matter how large it is. + Accepts the *rangemin* and *rangemax* genome parameters, both optional. - """ - if args["pmut"] <= 0.0: return 0 - height, width = genome.getSize() - elements = height * width + This routine generates a gaussian value with mu=1.0 and std=0.0333 and then + the gene is multiplied by this value. This will cause the gene to drift + no matter how large it is. - mutations = args["pmut"] * elements + """ + if args["pmut"] <= 0.0: + return 0 + height, width = genome.getSize() + elements = height * width - mu = Consts.CDefGaussianGradientMU - sigma = Consts.CDefGaussianGradientSIGMA + mutations = args["pmut"] * elements - if mutations < 1.0: - mutations = 0 - - for i in xrange(genome.getHeight()): - for j in xrange(genome.getWidth()): - if Util.randomFlipCoin(args["pmut"]): - final_value = int(genome[i][j] * abs(rand_gauss(mu, sigma))) + mu = Consts.CDefGaussianGradientMU + sigma = Consts.CDefGaussianGradientSIGMA + + if mutations < 1.0: + mutations = 0 - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + for i in xrange(genome.getHeight()): + for j in xrange(genome.getWidth()): + if Util.randomFlipCoin(args["pmut"]): + final_value = int(genome[i][j] * abs(rand_gauss(mu, sigma))) - genome.setItem(i, j, final_value) - mutations += 1 - else: + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - for it in xrange(int(round(mutations))): - which_x = rand_randint(0, genome.getWidth()-1) - which_y = rand_randint(0, genome.getHeight()-1) + genome.setItem(i, j, final_value) + mutations += 1 + else: - final_value = int(genome[which_y][which_x] * abs(rand_gauss(mu, sigma))) + for it in xrange(int(round(mutations))): + which_x = rand_randint(0, genome.getWidth()-1) + which_y = rand_randint(0, genome.getHeight()-1) - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + final_value = int(genome[which_y][which_x] * abs(rand_gauss(mu, sigma))) - genome.setItem(which_y, which_x, final_value) + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + + genome.setItem(which_y, which_x, final_value) + + return int(mutations) - return int(mutations) def G2DListMutatorIntegerGaussian(genome, **args): - """ A gaussian mutator for G2DList of Integers + """ A gaussian mutator for G2DList of Integers - Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also - accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively - represents the mean and the std. dev. of the random distribution. + Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also + accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively + represents the mean and the std. dev. of the random distribution. - """ - if args["pmut"] <= 0.0: return 0 - height, width = genome.getSize() - elements = height * width + """ + if args["pmut"] <= 0.0: + return 0 + height, width = genome.getSize() + elements = height * width - mutations = args["pmut"] * elements + mutations = args["pmut"] * elements - mu = genome.getParam("gauss_mu") - sigma = genome.getParam("gauss_sigma") + mu = genome.getParam("gauss_mu") + sigma = genome.getParam("gauss_sigma") - if mu is None: - mu = Consts.CDefG2DListMutIntMU - - if sigma is None: - sigma = Consts.CDefG2DListMutIntSIGMA + if mu is None: + mu = Consts.CDefG2DListMutIntMU - if mutations < 1.0: - mutations = 0 - - for i in xrange(genome.getHeight()): - for j in xrange(genome.getWidth()): - if Util.randomFlipCoin(args["pmut"]): - final_value = genome[i][j] + int(rand_gauss(mu, sigma)) + if sigma is None: + sigma = Consts.CDefG2DListMutIntSIGMA - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + if mutations < 1.0: + mutations = 0 - genome.setItem(i, j, final_value) - mutations += 1 - else: + for i in xrange(genome.getHeight()): + for j in xrange(genome.getWidth()): + if Util.randomFlipCoin(args["pmut"]): + final_value = genome[i][j] + int(rand_gauss(mu, sigma)) - for it in xrange(int(round(mutations))): - which_x = rand_randint(0, genome.getWidth()-1) - which_y = rand_randint(0, genome.getHeight()-1) + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - final_value = genome[which_y][which_x] + int(rand_gauss(mu, sigma)) + genome.setItem(i, j, final_value) + mutations += 1 + else: - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + for it in xrange(int(round(mutations))): + which_x = rand_randint(0, genome.getWidth()-1) + which_y = rand_randint(0, genome.getHeight()-1) - genome.setItem(which_y, which_x, final_value) + final_value = genome[which_y][which_x] + int(rand_gauss(mu, sigma)) - return int(mutations) + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + + genome.setItem(which_y, which_x, final_value) + + return int(mutations) def G2DListMutatorAllele(genome, **args): - """ The mutator of G2DList, Allele Mutator + """ The mutator of G2DList, Allele Mutator - To use this mutator, you must specify the *allele* genome parameter with the - :class:`GAllele.GAlleles` instance. + To use this mutator, you must specify the *allele* genome parameter with the + :class:`GAllele.GAlleles` instance. - .. warning:: the :class:`GAllele.GAlleles` instance must have the homogeneous flag enabled + .. warning:: the :class:`GAllele.GAlleles` instance must have the homogeneous flag enabled - """ - if args["pmut"] <= 0.0: return 0 - listSize = genome.getHeight()*genome.getWidth() - 1 - mutations = args["pmut"] * (listSize+1) + """ + if args["pmut"] <= 0.0: + return 0 + listSize = genome.getHeight()*genome.getWidth() - 1 + mutations = args["pmut"] * (listSize+1) - allele = genome.getParam("allele", None) - if allele is None: - Util.raiseException("to use the G2DListMutatorAllele, you must specify the 'allele' parameter", TypeError) + allele = genome.getParam("allele", None) + if allele is None: + Util.raiseException("to use the G2DListMutatorAllele, you must specify the 'allele' parameter", TypeError) - if allele.homogeneous == False: - Util.raiseException("to use the G2DListMutatorAllele, the 'allele' must be homogeneous") + if not allele.homogeneous: + Util.raiseException("to use the G2DListMutatorAllele, the 'allele' must be homogeneous") - if mutations < 1.0: - mutations = 0 + if mutations < 1.0: + mutations = 0 - for i in xrange(genome.getHeight()): - for j in xrange(genome.getWidth()): - if Util.randomFlipCoin(args["pmut"]): - new_val = allele[0].getRandomAllele() - genome.setItem(i, j, new_val) - mutations+=1 - else: - for it in xrange(int(round(mutations))): - which_x = rand_randint(0, genome.getHeight()-1) - which_y = rand_randint(0, genome.getWidth()-1) + for i in xrange(genome.getHeight()): + for j in xrange(genome.getWidth()): + if Util.randomFlipCoin(args["pmut"]): + new_val = allele[0].getRandomAllele() + genome.setItem(i, j, new_val) + mutations += 1 + else: + for it in xrange(int(round(mutations))): + which_x = rand_randint(0, genome.getHeight()-1) + which_y = rand_randint(0, genome.getWidth()-1) - new_val = allele[0].getRandomAllele() - genome.setItem(which_x, which_y, new_val) + new_val = allele[0].getRandomAllele() + genome.setItem(which_x, which_y, new_val) - return int(mutations) + return int(mutations) def G2DListMutatorRealGaussian(genome, **args): - """ A gaussian mutator for G2DList of Real + """ A gaussian mutator for G2DList of Real - Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also - accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively - represents the mean and the std. dev. of the random distribution. + Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also + accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively + represents the mean and the std. dev. of the random distribution. - """ - if args["pmut"] <= 0.0: return 0 - height, width = genome.getSize() - elements = height * width + """ + if args["pmut"] <= 0.0: + return 0 + height, width = genome.getSize() + elements = height * width - mutations = args["pmut"] * elements + mutations = args["pmut"] * elements - mu = genome.getParam("gauss_mu") - sigma = genome.getParam("gauss_sigma") + mu = genome.getParam("gauss_mu") + sigma = genome.getParam("gauss_sigma") - if mu is None: - mu = Consts.CDefG2DListMutRealMU - - if sigma is None: - sigma = Consts.CDefG2DListMutRealSIGMA + if mu is None: + mu = Consts.CDefG2DListMutRealMU - if mutations < 1.0: - mutations = 0 - - for i in xrange(genome.getHeight()): - for j in xrange(genome.getWidth()): - if Util.randomFlipCoin(args["pmut"]): - final_value = genome[i][j] + rand_gauss(mu, sigma) + if sigma is None: + sigma = Consts.CDefG2DListMutRealSIGMA + + if mutations < 1.0: + mutations = 0 + + for i in xrange(genome.getHeight()): + for j in xrange(genome.getWidth()): + if Util.randomFlipCoin(args["pmut"]): + final_value = genome[i][j] + rand_gauss(mu, sigma) + + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + genome.setItem(i, j, final_value) + mutations += 1 + else: - genome.setItem(i, j, final_value) - mutations += 1 - else: + for it in xrange(int(round(mutations))): + which_x = rand_randint(0, genome.getWidth()-1) + which_y = rand_randint(0, genome.getHeight()-1) - for it in xrange(int(round(mutations))): - which_x = rand_randint(0, genome.getWidth()-1) - which_y = rand_randint(0, genome.getHeight()-1) + final_value = genome[which_y][which_x] + rand_gauss(mu, sigma) - final_value = genome[which_y][which_x] + rand_gauss(mu, sigma) + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + genome.setItem(which_y, which_x, final_value) - genome.setItem(which_y, which_x, final_value) + return int(mutations) - return int(mutations) def G2DListMutatorRealGaussianGradient(genome, **args): - """ A gaussian gradient mutator for G2DList of Real + """ A gaussian gradient mutator for G2DList of Real - Accepts the *rangemin* and *rangemax* genome parameters, both optional. - - The difference is that this multiplies the gene by gauss(1.0, 0.0333), allowing - for a smooth gradient drift about the value. + Accepts the *rangemin* and *rangemax* genome parameters, both optional. - """ - if args["pmut"] <= 0.0: return 0 - height, width = genome.getSize() - elements = height * width + The difference is that this multiplies the gene by gauss(1.0, 0.0333), allowing + for a smooth gradient drift about the value. - mutations = args["pmut"] * elements + """ + if args["pmut"] <= 0.0: + return 0 + height, width = genome.getSize() + elements = height * width - mu = Consts.CDefGaussianGradientMU - sigma = Consts.CDefGaussianGradientSIGMA + mutations = args["pmut"] * elements - if mutations < 1.0: - mutations = 0 - - for i in xrange(genome.getHeight()): - for j in xrange(genome.getWidth()): - if Util.randomFlipCoin(args["pmut"]): - final_value = genome[i][j] * abs(rand_gauss(mu, sigma)) + mu = Consts.CDefGaussianGradientMU + sigma = Consts.CDefGaussianGradientSIGMA + + if mutations < 1.0: + mutations = 0 + + for i in xrange(genome.getHeight()): + for j in xrange(genome.getWidth()): + if Util.randomFlipCoin(args["pmut"]): + final_value = genome[i][j] * abs(rand_gauss(mu, sigma)) - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - genome.setItem(i, j, final_value) - mutations += 1 - else: + genome.setItem(i, j, final_value) + mutations += 1 + else: - for it in xrange(int(round(mutations))): - which_x = rand_randint(0, genome.getWidth()-1) - which_y = rand_randint(0, genome.getHeight()-1) + for it in xrange(int(round(mutations))): + which_x = rand_randint(0, genome.getWidth()-1) + which_y = rand_randint(0, genome.getHeight()-1) - final_value = genome[which_y][which_x] * abs(rand_gauss(mu, sigma)) + final_value = genome[which_y][which_x] * abs(rand_gauss(mu, sigma)) - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + + genome.setItem(which_y, which_x, final_value) - genome.setItem(which_y, which_x, final_value) + return int(mutations) - return int(mutations) ############################# ## 2D Binary String ## ############################# def G2DBinaryStringMutatorSwap(genome, **args): - """ The mutator of G2DBinaryString, Swap Mutator - - .. versionadded:: 0.6 - The *G2DBinaryStringMutatorSwap* function - """ - - if args["pmut"] <= 0.0: return 0 - height, width = genome.getSize() - elements = height * width - - mutations = args["pmut"] * elements - - if mutations < 1.0: - mutations = 0 - for i in xrange(height): - for j in xrange(width): - if Util.randomFlipCoin(args["pmut"]): - index_b = (rand_randint(0, height-1), rand_randint(0, width-1)) - Util.list2DSwapElement(genome.genomeString, (i,j), index_b) - mutations+=1 - else: - for it in xrange(int(round(mutations))): - index_a = (rand_randint(0, height-1), rand_randint(0, width-1)) - index_b = (rand_randint(0, height-1), rand_randint(0, width-1)) - Util.list2DSwapElement(genome.genomeString, index_a, index_b) + """ The mutator of G2DBinaryString, Swap Mutator - return int(mutations) + .. versionadded:: 0.6 + The *G2DBinaryStringMutatorSwap* function + """ + if args["pmut"] <= 0.0: + return 0 + height, width = genome.getSize() + elements = height * width -def G2DBinaryStringMutatorFlip(genome, **args): - """ A flip mutator for G2DBinaryString - - .. versionadded:: 0.6 - The *G2DBinaryStringMutatorFlip* function - """ - if args["pmut"] <= 0.0: return 0 - height, width = genome.getSize() - elements = height * width - - mutations = args["pmut"] * elements - - if mutations < 1.0: - mutations = 0 - - for i in xrange(genome.getHeight()): - for j in xrange(genome.getWidth()): - if Util.randomFlipCoin(args["pmut"]): - if genome[i][j] == 0: genome.setItem(i, j, 1) - else: genome.setItem(i, j, 0) - mutations += 1 - else: + mutations = args["pmut"] * elements + + if mutations < 1.0: + mutations = 0 + for i in xrange(height): + for j in xrange(width): + if Util.randomFlipCoin(args["pmut"]): + index_b = (rand_randint(0, height-1), rand_randint(0, width-1)) + Util.list2DSwapElement(genome.genomeString, (i, j), index_b) + mutations += 1 + else: + for it in xrange(int(round(mutations))): + index_a = (rand_randint(0, height-1), rand_randint(0, width-1)) + index_b = (rand_randint(0, height-1), rand_randint(0, width-1)) + Util.list2DSwapElement(genome.genomeString, index_a, index_b) + + return int(mutations) - for it in xrange(int(round(mutations))): - which_x = rand_randint(0, genome.getWidth()-1) - which_y = rand_randint(0, genome.getHeight()-1) - if genome[i][j] == 0: genome.setItem(which_y, which_x, 1) - else: genome.setItem(which_y, which_x, 0) +def G2DBinaryStringMutatorFlip(genome, **args): + """ A flip mutator for G2DBinaryString + + .. versionadded:: 0.6 + The *G2DBinaryStringMutatorFlip* function + """ + if args["pmut"] <= 0.0: + return 0 + height, width = genome.getSize() + elements = height * width + + mutations = args["pmut"] * elements + + if mutations < 1.0: + mutations = 0 + + for i in xrange(genome.getHeight()): + for j in xrange(genome.getWidth()): + if Util.randomFlipCoin(args["pmut"]): + if genome[i][j] == 0: + genome.setItem(i, j, 1) + else: + genome.setItem(i, j, 0) + mutations += 1 + else: + + for it in xrange(int(round(mutations))): + which_x = rand_randint(0, genome.getWidth()-1) + which_y = rand_randint(0, genome.getHeight()-1) + + if genome[i][j] == 0: + genome.setItem(which_y, which_x, 1) + else: + genome.setItem(which_y, which_x, 0) + + return int(mutations) - return int(mutations) ################# ## Tree ## ################# + def GTreeMutatorSwap(genome, **args): - """ The mutator of GTree, Swap Mutator - - .. versionadded:: 0.6 - The *GTreeMutatorSwap* function - """ - if args["pmut"] <= 0.0: return 0 - elements = len(genome) - mutations = args["pmut"] * elements - - if mutations < 1.0: - mutations = 0 - for i in xrange(len(genome)): - if Util.randomFlipCoin(args["pmut"]): - mutations += 1 + """ The mutator of GTree, Swap Mutator + + .. versionadded:: 0.6 + The *GTreeMutatorSwap* function + """ + if args["pmut"] <= 0.0: + return 0 + elements = len(genome) + mutations = args["pmut"] * elements + + if mutations < 1.0: + mutations = 0 + for i in xrange(len(genome)): + if Util.randomFlipCoin(args["pmut"]): + mutations += 1 + nodeOne = genome.getRandomNode() + nodeTwo = genome.getRandomNode() + nodeOne.swapNodeData(nodeTwo) + else: + for it in xrange(int(round(mutations))): nodeOne = genome.getRandomNode() nodeTwo = genome.getRandomNode() nodeOne.swapNodeData(nodeTwo) - else: - for it in xrange(int(round(mutations))): - nodeOne = genome.getRandomNode() - nodeTwo = genome.getRandomNode() - nodeOne.swapNodeData(nodeTwo) - return int(mutations) + return int(mutations) def GTreeMutatorIntegerRange(genome, **args): - """ The mutator of GTree, Integer Range Mutator - - Accepts the *rangemin* and *rangemax* genome parameters, both optional. - - .. versionadded:: 0.6 - The *GTreeMutatorIntegerRange* function - """ - if args["pmut"] <= 0.0: return 0 - elements = len(genome) - mutations = args["pmut"] * elements - - range_min = genome.getParam("rangemin", Consts.CDefRangeMin) - range_max = genome.getParam("rangemax", Consts.CDefRangeMax) - - if mutations < 1.0: - mutations = 0 - for i in xrange(len(genome)): - if Util.randomFlipCoin(args["pmut"]): - mutations += 1 + """ The mutator of GTree, Integer Range Mutator + + Accepts the *rangemin* and *rangemax* genome parameters, both optional. + + .. versionadded:: 0.6 + The *GTreeMutatorIntegerRange* function + """ + if args["pmut"] <= 0.0: + return 0 + elements = len(genome) + mutations = args["pmut"] * elements + + range_min = genome.getParam("rangemin", Consts.CDefRangeMin) + range_max = genome.getParam("rangemax", Consts.CDefRangeMax) + + if mutations < 1.0: + mutations = 0 + for i in xrange(len(genome)): + if Util.randomFlipCoin(args["pmut"]): + mutations += 1 + rand_node = genome.getRandomNode() + random_int = rand_randint(range_min, range_max) + rand_node.setData(random_int) + + else: + for it in xrange(int(round(mutations))): rand_node = genome.getRandomNode() random_int = rand_randint(range_min, range_max) rand_node.setData(random_int) - else: - for it in xrange(int(round(mutations))): - rand_node = genome.getRandomNode() - random_int = rand_randint(range_min, range_max) - rand_node.setData(random_int) - - return int(mutations) + return int(mutations) def GTreeMutatorRealRange(genome, **args): - """ The mutator of GTree, Real Range Mutator - - Accepts the *rangemin* and *rangemax* genome parameters, both optional. - - .. versionadded:: 0.6 - The *GTreeMutatorRealRange* function - """ - if args["pmut"] <= 0.0: return 0 - elements = len(genome) - mutations = args["pmut"] * elements - - range_min = genome.getParam("rangemin", Consts.CDefRangeMin) - range_max = genome.getParam("rangemax", Consts.CDefRangeMax) - - if mutations < 1.0: - mutations = 0 - for i in xrange(len(genome)): - if Util.randomFlipCoin(args["pmut"]): - mutations += 1 + """ The mutator of GTree, Real Range Mutator + + Accepts the *rangemin* and *rangemax* genome parameters, both optional. + + .. versionadded:: 0.6 + The *GTreeMutatorRealRange* function + """ + if args["pmut"] <= 0.0: + return 0 + elements = len(genome) + mutations = args["pmut"] * elements + + range_min = genome.getParam("rangemin", Consts.CDefRangeMin) + range_max = genome.getParam("rangemax", Consts.CDefRangeMax) + + if mutations < 1.0: + mutations = 0 + for i in xrange(len(genome)): + if Util.randomFlipCoin(args["pmut"]): + mutations += 1 + rand_node = genome.getRandomNode() + random_real = rand_uniform(range_min, range_max) + rand_node.setData(random_real) + + else: + for it in xrange(int(round(mutations))): rand_node = genome.getRandomNode() random_real = rand_uniform(range_min, range_max) rand_node.setData(random_real) - else: - for it in xrange(int(round(mutations))): - rand_node = genome.getRandomNode() - random_real = rand_uniform(range_min, range_max) - rand_node.setData(random_real) - - return int(mutations) + return int(mutations) def GTreeMutatorIntegerGaussian(genome, **args): - """ A gaussian mutator for GTree of Integers + """ A gaussian mutator for GTree of Integers - Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also - accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively - represents the mean and the std. dev. of the random distribution. + Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also + accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively + represents the mean and the std. dev. of the random distribution. - """ - if args["pmut"] <= 0.0: return 0 - elements = len(genome) - mutations = args["pmut"] * elements + """ + if args["pmut"] <= 0.0: + return 0 + elements = len(genome) + mutations = args["pmut"] * elements - mu = genome.getParam("gauss_mu", Consts.CDefG1DListMutIntMU) - sigma = genome.getParam("gauss_sigma", Consts.CDefG1DListMutIntSIGMA) + mu = genome.getParam("gauss_mu", Consts.CDefG1DListMutIntMU) + sigma = genome.getParam("gauss_sigma", Consts.CDefG1DListMutIntSIGMA) - if mutations < 1.0: - mutations = 0 - for i in xrange(len(genome)): - if Util.randomFlipCoin(args["pmut"]): - mutations += 1 + if mutations < 1.0: + mutations = 0 + for i in xrange(len(genome)): + if Util.randomFlipCoin(args["pmut"]): + mutations += 1 + rand_node = genome.getRandomNode() + final_value = rand_node.getData() + int(rand_gauss(mu, sigma)) + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + rand_node.setData(final_value) + else: + for it in xrange(int(round(mutations))): rand_node = genome.getRandomNode() final_value = rand_node.getData() + int(rand_gauss(mu, sigma)) final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) rand_node.setData(final_value) - else: - for it in xrange(int(round(mutations))): - rand_node = genome.getRandomNode() - final_value = rand_node.getData() + int(rand_gauss(mu, sigma)) - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - rand_node.setData(final_value) - return int(mutations) + return int(mutations) def GTreeMutatorRealGaussian(genome, **args): - """ A gaussian mutator for GTree of Real numbers + """ A gaussian mutator for GTree of Real numbers - Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also - accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively - represents the mean and the std. dev. of the random distribution. + Accepts the *rangemin* and *rangemax* genome parameters, both optional. Also + accepts the parameter *gauss_mu* and the *gauss_sigma* which respectively + represents the mean and the std. dev. of the random distribution. - """ - if args["pmut"] <= 0.0: return 0 - elements = len(genome) - mutations = args["pmut"] * elements + """ + if args["pmut"] <= 0.0: + return 0 + elements = len(genome) + mutations = args["pmut"] * elements - mu = genome.getParam("gauss_mu", Consts.CDefG1DListMutRealMU) - sigma = genome.getParam("gauss_sigma", Consts.CDefG1DListMutRealSIGMA) + mu = genome.getParam("gauss_mu", Consts.CDefG1DListMutRealMU) + sigma = genome.getParam("gauss_sigma", Consts.CDefG1DListMutRealSIGMA) - if mutations < 1.0: - mutations = 0 - for i in xrange(len(genome)): - if Util.randomFlipCoin(args["pmut"]): - mutations += 1 + if mutations < 1.0: + mutations = 0 + for i in xrange(len(genome)): + if Util.randomFlipCoin(args["pmut"]): + mutations += 1 + rand_node = genome.getRandomNode() + final_value = rand_node.getData() + rand_gauss(mu, sigma) + final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) + final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) + rand_node.setData(final_value) + else: + for it in xrange(int(round(mutations))): rand_node = genome.getRandomNode() final_value = rand_node.getData() + rand_gauss(mu, sigma) final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) rand_node.setData(final_value) - else: - for it in xrange(int(round(mutations))): - rand_node = genome.getRandomNode() - final_value = rand_node.getData() + rand_gauss(mu, sigma) - final_value = min(final_value, genome.getParam("rangemax", Consts.CDefRangeMax)) - final_value = max(final_value, genome.getParam("rangemin", Consts.CDefRangeMin)) - rand_node.setData(final_value) - - return int(mutations) + return int(mutations) ################### @@ -942,111 +1002,113 @@ def GTreeMutatorRealGaussian(genome, **args): ################### def GTreeGPMutatorOperation(genome, **args): - """ The mutator of GTreeGP, Operation Mutator - - .. versionadded:: 0.6 - The *GTreeGPMutatorOperation* function - """ + """ The mutator of GTreeGP, Operation Mutator - if args["pmut"] <= 0.0: return 0 - elements = len(genome) - mutations = args["pmut"] * elements - ga_engine = args["ga_engine"] + .. versionadded:: 0.6 + The *GTreeGPMutatorOperation* function + """ + if args["pmut"] <= 0.0: + return 0 + elements = len(genome) + mutations = args["pmut"] * elements + ga_engine = args["ga_engine"] - gp_terminals = ga_engine.getParam("gp_terminals") - assert gp_terminals is not None + gp_terminals = ga_engine.getParam("gp_terminals") + assert gp_terminals is not None - gp_function_set = ga_engine.getParam("gp_function_set") - assert gp_function_set is not None + gp_function_set = ga_engine.getParam("gp_function_set") + assert gp_function_set is not None - if mutations < 1.0: - mutations = 0 - for i in xrange(len(genome)): - if Util.randomFlipCoin(args["pmut"]): - mutations += 1 + if mutations < 1.0: + mutations = 0 + for i in xrange(len(genome)): + if Util.randomFlipCoin(args["pmut"]): + mutations += 1 + rand_node = genome.getRandomNode() + assert rand_node is not None + if rand_node.getType() == Consts.nodeType["TERMINAL"]: + term_operator = rand_choice(gp_terminals) + else: + op_len = gp_function_set[rand_node.getData()] + fun_candidates = [] + for o, l in gp_function_set.items(): + if l == op_len: + fun_candidates.append(o) + + if len(fun_candidates) <= 0: + continue + + term_operator = rand_choice(fun_candidates) + rand_node.setData(term_operator) + else: + for it in xrange(int(round(mutations))): rand_node = genome.getRandomNode() assert rand_node is not None if rand_node.getType() == Consts.nodeType["TERMINAL"]: - term_operator = rand_choice(gp_terminals) + term_operator = rand_choice(gp_terminals) else: - op_len = gp_function_set[rand_node.getData()] - fun_candidates = [] - for o, l in gp_function_set.items(): - if l==op_len: - fun_candidates.append(o) + op_len = gp_function_set[rand_node.getData()] + fun_candidates = [] + for o, l in gp_function_set.items(): + if l == op_len: + fun_candidates.append(o) - if len(fun_candidates) <= 0: - continue + if len(fun_candidates) <= 0: + continue - term_operator = rand_choice(fun_candidates) + term_operator = rand_choice(fun_candidates) rand_node.setData(term_operator) - else: - for it in xrange(int(round(mutations))): - rand_node = genome.getRandomNode() - assert rand_node is not None - if rand_node.getType() == Consts.nodeType["TERMINAL"]: - term_operator = rand_choice(gp_terminals) - else: - op_len = gp_function_set[rand_node.getData()] - fun_candidates = [] - for o, l in gp_function_set.items(): - if l==op_len: - fun_candidates.append(o) - - if len(fun_candidates) <= 0: - continue - - term_operator = rand_choice(fun_candidates) - rand_node.setData(term_operator) - - return int(mutations) + + return int(mutations) def GTreeGPMutatorSubtree(genome, **args): - """ The mutator of GTreeGP, Subtree Mutator - - This mutator will recreate random subtree of the tree using the grow algorithm. - - .. versionadded:: 0.6 - The *GTreeGPMutatorSubtree* function - """ - - if args["pmut"] <= 0.0: return 0 - ga_engine = args["ga_engine"] - max_depth = genome.getParam("max_depth", None) - mutations = 0 - - if max_depth is None: - Util.raiseException("You must specify the max_depth genome parameter !", ValueError) - - if max_depth < 0: - Util.raiseException("The max_depth must be >= 1, if you want to use GTreeGPMutatorSubtree crossover !", ValueError) - - branch_list = genome.nodes_branch - elements = len(branch_list) - - for i in xrange(elements): - - node = branch_list[i] - assert node is not None - - if Util.randomFlipCoin(args["pmut"]): - depth = genome.getNodeDepth(node) - mutations += 1 - - root_subtree = GTree.buildGTreeGPGrow(ga_engine, 0, max_depth-depth) - node_parent = node.getParent() - - if node_parent is None: - genome.setRoot(root_subtree) - genome.processNodes() - return mutations - else: - root_subtree.setParent(node_parent) - node_parent.replaceChild(node, root_subtree) - genome.processNodes() - - return int(mutations) + """ The mutator of GTreeGP, Subtree Mutator + + This mutator will recreate random subtree of the tree using the grow algorithm. + + .. versionadded:: 0.6 + The *GTreeGPMutatorSubtree* function + """ + + if args["pmut"] <= 0.0: + return 0 + ga_engine = args["ga_engine"] + max_depth = genome.getParam("max_depth", None) + mutations = 0 + + if max_depth is None: + Util.raiseException("You must specify the max_depth genome parameter !", ValueError) + if max_depth < 0: + Util.raiseException( + "The max_depth must be >= 1, if you want to use GTreeGPMutatorSubtree crossover !", + ValueError + ) + + branch_list = genome.nodes_branch + elements = len(branch_list) + + for i in xrange(elements): + + node = branch_list[i] + assert node is not None + + if Util.randomFlipCoin(args["pmut"]): + depth = genome.getNodeDepth(node) + mutations += 1 + + root_subtree = GTree.buildGTreeGPGrow(ga_engine, 0, max_depth-depth) + node_parent = node.getParent() + + if node_parent is None: + genome.setRoot(root_subtree) + genome.processNodes() + return mutations + else: + root_subtree.setParent(node_parent) + node_parent.replaceChild(node, root_subtree) + genome.processNodes() + return int(mutations)