Python Genetic Algorithm

Terry Reedy tjreedy at udel.edu
Mon Jan 28 02:01:17 CET 2008


"Max" <thelanguageofcities at gmail.com> wrote in message 
news:caf75b0d-7ed3-421a-93f8-6f7d90a98923 at p69g2000hsa.googlegroups.com...
| In GAs, you operate on a Population of solutions. Each Individual from
| the Population is a potential solution to the problem you're
| optimizing, and Individuals have what's called a chromosome - a
| specification of what it contains. For example, common chromosomes are
| bit strings, lists of ints/floats, permutations...etc. I'm stuck on
| how to implement the different chromosomes. I have a Population class,
| which is going to contain a list of Individuals. Each individual will
| be of a certain chromosome. I envision the chromosomes as subclasses
| of an abstract Individual class, perhaps all in the same module. I'm
| just having trouble envisioning how this would be coded at the
| population level. Presumably, when a population is created, a
| parameter to its __init__ would be the chromosome type, but I don't
| know how to take that in Python and use it to specify a certain class.
|
| I'm doing something similar with my crossover methods, by specifying
| them as functions in a module called Crossover, importing that, and
| defining
|
| crossover_function = getattr(Crossover, "%s_crossover" % xover)
|
| Where xover is a parameter defining the type of crossover to be used.
| I'm hoping there's some similar trick to accomplish what I want to do
| with chromosomes - or maybe I'm going about this completely the wrong
| way, trying to get Python to do something it's not made for. Any help/
| feedback would be wonderful.

'Python genetic algorithm' returns 25000 hits with Google.
But here is what I would do without looking at them.

Start with the Individual base class and common methods, some virtual (not 
implemented).  An example of a virtual method would be the 
crossover(self,other) method, since its implementation depends on the 
concrete chromosome implementation.  Make subclasses with concrete 
chromosome types (initialized in .__init__).  For each, implement the 
methods that depend on that type.  In particular, the mutate(self, args) 
and crossover(self,other, args) methods.

For the Population class, give  __init__ an 'individual' parameter and 
store it as an attribute.  If you want, check that it 
'issubclass(Individual)'.  To add members to the population, call the 
stored subclass.  To operate on the population, write Population methods. 
There should not depend on the particular chromosome implementations.  To 
operate on the members within the Population methods, call their Individual 
methods.  b = a.mutate(args); c = a.crossover(b, args).

I see two ways to deal with scoring the fitness of individuals within a 
Population instance.  Once is to write a particular fitness function, pass 
it to the Population init to save as an attribute, and then call as needed. 
The other is to subclass an Individual subclass, give it that funtion 
fitness method, and pass that subsubclass to Population.  The difference is 
between having Population methods calling self.fitness(some_member) versus 
some_member.fitness().

I hope this is helpful for getting started.

Terry Jan Reedy






More information about the Python-list mailing list