[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Python Genetic Algorithm

Max

1/27/2008 11:10:00 PM

Hi all. I'm just getting introduced to Python (mostly through Dive
Into Python), and I've decided to use it for a project where I have to
write my own Genetic Algorithm. Even if you don't know about GAs, you
might be able to help with an issue I'm having. I'm just starting the
project off, so I'm still in the conceptual phase, and I'm stuck on
how I'm going to be able to implement something.

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.

Thanks,
Max Martin
14 Answers

Wildemar Wildenburger

1/27/2008 11:36:00 PM

0

Max wrote:
> 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 not sure I'm following you here. So a "chromosome" is bit of
functionality, right? So basically it is a function. So my advice would
be to write these functions and store it to the "indivuals"-list like so:

class Population(object):
def __init__(self, *individuals):
self.individuals = list(individuals)

Then you can say:
p = Population(indiv1, indiv2, indiv3)
for individual in p.individual:
individual(whatever_your_problem)

(Don't know if this is the way GA's are supposed to work)

You can also create callable classes (that is, classes that implement
the __call__ method), and use instances of these as the individuals. For
example you can create a Permutation class that returns a permutation
(defined in it's __init__()) when it's __call__ method is called. (Am I
making sense?)

This is just generic advice, maybe this helps and maybe it doesn't at
all. :)



> 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.
>
This isn't too bad, but for such things dictionaries are your Go-To
datatype. Just have a dictionary of xover-functions handy and call the
thusly:

crossover_function = Crossover.function[xover]


> Thanks,
> Max Martin
If that helps :)

regards
/W

Steven Clark

1/28/2008 12:02:00 AM

0

Why not make chromosome itself a class?

class BasicChromosome(object):
def __init__(self, data):
self.data = data

def crossover(self):
[stuff here]

You can subclass this as needed, altering the crossover method as necessary.

....perhaps I didn't understand your question.
-Steven

On Jan 27, 2008 6:35 PM, Wildemar Wildenburger
<lasses_weil@klapptsowieso.net> wrote:
> Max wrote:
> > 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 not sure I'm following you here. So a "chromosome" is bit of
> functionality, right? So basically it is a function. So my advice would
> be to write these functions and store it to the "indivuals"-list like so:
>
> class Population(object):
> def __init__(self, *individuals):
> self.individuals = list(individuals)
>
> Then you can say:
> p = Population(indiv1, indiv2, indiv3)
> for individual in p.individual:
> individual(whatever_your_problem)
>
> (Don't know if this is the way GA's are supposed to work)
>
> You can also create callable classes (that is, classes that implement
> the __call__ method), and use instances of these as the individuals. For
> example you can create a Permutation class that returns a permutation
> (defined in it's __init__()) when it's __call__ method is called. (Am I
> making sense?)
>
> This is just generic advice, maybe this helps and maybe it doesn't at
> all. :)
>
>
>
> > 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.
> >
> This isn't too bad, but for such things dictionaries are your Go-To
> datatype. Just have a dictionary of xover-functions handy and call the
> thusly:
>
> crossover_function = Crossover.function[xover]
>
>
> > Thanks,
> > Max Martin
> If that helps :)
>
> regards
> /W
>
> --
> http://mail.python.org/mailman/listinfo/p...
>

Max

1/28/2008 12:19:00 AM

0

On Jan 27, 6:35 pm, Wildemar Wildenburger
<lasses_w...@klapptsowieso.net> wrote:
> Max wrote:
> > 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 not sure I'm following you here. So a "chromosome" is bit of
> functionality, right? So basically it is a function. So my advice would
> be to write these functions and store it to the "indivuals"-list like so:
>
> class Population(object):
> def __init__(self, *individuals):
> self.individuals = list(individuals)
>
> Then you can say:
> p = Population(indiv1, indiv2, indiv3)
> for individual in p.individual:
> individual(whatever_your_problem)
>
> (Don't know if this is the way GA's are supposed to work)
>
> You can also create callable classes (that is, classes that implement
> the __call__ method), and use instances of these as the individuals. For
> example you can create a Permutation class that returns a permutation
> (defined in it's __init__()) when it's __call__ method is called. (Am I
> making sense?)
>
> This is just generic advice, maybe this helps and maybe it doesn't at
> all. :)
>
> > 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.
>
> This isn't too bad, but for such things dictionaries are your Go-To
> datatype. Just have a dictionary of xover-functions handy and call the
> thusly:
>
> crossover_function = Crossover.function[xover]
>
> > Thanks,
> > Max Martin
>
> If that helps :)
>
> regards
> /W

This is definitely useful information, but I don't think I explained
chromosomes very well.

A chromosome is a choice of representation. So let's say your problem
is diagnosis, so a representation of a solution will be a list of
diagnoses (e.g. Disease1 = yes, Disease2 = no, Disease3 = yes, etc.).
Your chromosome choice could be a bitstring, in which the previous
solution would = 101, or it could be a list of floats to represent the
probability that you have Disease x, etc. So a chromosome is like a
choice of representation. In the case of humans, the chromosome is,
well, chromosomes.

Max

1/28/2008 12:22:00 AM

0

On Jan 27, 7:01 pm, "Steven Clark" <steven.p.cl...@gmail.com> wrote:
> Why not make chromosome itself a class?
>
> class BasicChromosome(object):
> def __init__(self, data):
> self.data = data
>
> def crossover(self):
> [stuff here]
>
> You can subclass this as needed, altering the crossover method as necessary.
>
> ...perhaps I didn't understand your question.
> -Steven
>
> On Jan 27, 2008 6:35 PM, Wildemar Wildenburger
>
> <lasses_w...@klapptsowieso.net> wrote:
> > Max wrote:
> > > 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 not sure I'm following you here. So a "chromosome" is bit of
> > functionality, right? So basically it is a function. So my advice would
> > be to write these functions and store it to the "indivuals"-list like so:
>
> > class Population(object):
> > def __init__(self, *individuals):
> > self.individuals = list(individuals)
>
> > Then you can say:
> > p = Population(indiv1, indiv2, indiv3)
> > for individual in p.individual:
> > individual(whatever_your_problem)
>
> > (Don't know if this is the way GA's are supposed to work)
>
> > You can also create callable classes (that is, classes that implement
> > the __call__ method), and use instances of these as the individuals. For
> > example you can create a Permutation class that returns a permutation
> > (defined in it's __init__()) when it's __call__ method is called. (Am I
> > making sense?)
>
> > This is just generic advice, maybe this helps and maybe it doesn't at
> > all. :)
>
> > > 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.
>
> > This isn't too bad, but for such things dictionaries are your Go-To
> > datatype. Just have a dictionary of xover-functions handy and call the
> > thusly:
>
> > crossover_function = Crossover.function[xover]
>
> > > Thanks,
> > > Max Martin
> > If that helps :)
>
> > regards
> > /W
>
> > --
> >http://mail.python.org/mailman/listinfo/p...

This is sort of what I'm trying to do. The super class would be
Individual, and subclasses would be BitStringIndividual,
IntIndividual, PermutationIndividual...etc. I just am feeling lost as
to how I'm going to implement my Population class, because when a
Population is initially created, it's going to fill itself up with
individuals by creating them, so it's going to need to know which
class it's creating instances of (which will be input when creating
the population somehow; I'm just not sure how to implement this).

Steven D'Aprano

1/28/2008 12:26:00 AM

0

On Sun, 27 Jan 2008 15:09:52 -0800, Max wrote:

> Hi all. I'm just getting introduced to Python (mostly through Dive Into
> Python), and I've decided to use it for a project where I have to write
> my own Genetic Algorithm. Even if you don't know about GAs, you might be
> able to help with an issue I'm having. I'm just starting the project
> off, so I'm still in the conceptual phase, and I'm stuck on how I'm
> going to be able to implement something.
>
> 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.

Presumably all the individuals in the same population need to have the
same kind of chromosome (differing only in the specific genes).


> I envision the chromosomes as subclasses of an abstract
> Individual class, perhaps all in the same module.

How would that work? Shouldn't the different kinds of chromosomes
(strings, lists of ints, etc.) be subclasses of an abstract Chromosome
kind?

What you need to think of is the difference between Is-A and Has-A
relationships. An individual Has A chromosome, so you want a relationship
something like this:


class Individual(object):
def __init__(self):
self.chromosome = get_chromosome()


On the other hand, something like a string chromosome Is A chromosome,
and so is a list-of-ints Chromosome:

class Chromosome(object):
pass # abstract class

class StringChromosome(Chromosome):
pass # implement extra/different functionality

class ListIntsChromosome(Chromosome):
pass



> I'm just having
> trouble envisioning how this would be coded at the population level.

There are so many ways... here's one possibility that doesn't even use a
Population class.


chromosome = StringChromosome # the class, not an instance
default_genes = "GATACATATGGATTAGGGACCACTAC"
size = 100
population = []
for i in range(size):
genes = chromosome(default_genes)
genes.mutate()
population.append(Individual(genes))

I'm sure you can modify that to work on a class instance basis.


> 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.

Just pass the class itself. For example:

# Define a class.
class Parrot(object):
pass

x = "Parrot" # x is the NAME of the class
y = Parrot # y is the CLASS itself
z = Parrot() # z is an INSTANCE of the class

You can use the class as a object, exactly the same as you can use a dict
or a string or a float or any other object. y() will create a new Parrot
instance exactly the same way that Parrot() would.


Here's one possibility:

class Population(object):
def __init__(self, size=1000, chromosome_type=StringChromosome):
individuals = []
for i in xrange(size):
genes = chromosome_type() # create new set of genes
x = Individual(genes) # add them to a new individual
individuals.append(x) # and store it in the population
self.individuals = individuals



> 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.


The only time you need something like that is when you need to go from
user-input (a string) to a binary object (e.g. a class, a function...).
Suppose you read the crossover type from a text config file, or user
input:

import Crossover
xover = raw_input("Enter a crossover type: valid values are X, Y, Z: ")
crossover_function = getattr(Crossover, "%s_crossover" % xover)

Instead of passing the string xover around as a parameter, you use it
*once* to get the actual function object itself, and pass that around.

Another alternative is to define something like this in the Crossover
module, assuming you have three functions xcrossover etc.:

user_map = {"X": xcrossover, "Y": ycrossover, "Z": zcrossover}

Again, use it once to get the function object from the user input.



Hope this helps,



--
Steven

Max

1/28/2008 12:44:00 AM

0

On Jan 27, 7:25 pm, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:
> On Sun, 27 Jan 2008 15:09:52 -0800, Max wrote:
> > Hi all. I'm just getting introduced to Python (mostly through Dive Into
> > Python), and I've decided to use it for a project where I have to write
> > my own Genetic Algorithm. Even if you don't know about GAs, you might be
> > able to help with an issue I'm having. I'm just starting the project
> > off, so I'm still in the conceptual phase, and I'm stuck on how I'm
> > going to be able to implement something.
>
> > 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.
>
> Presumably all the individuals in the same population need to have the
> same kind of chromosome (differing only in the specific genes).
>
> > I envision the chromosomes as subclasses of an abstract
> > Individual class, perhaps all in the same module.
>
> How would that work? Shouldn't the different kinds of chromosomes
> (strings, lists of ints, etc.) be subclasses of an abstract Chromosome
> kind?
>
> What you need to think of is the difference between Is-A and Has-A
> relationships. An individual Has A chromosome, so you want a relationship
> something like this:
>
> class Individual(object):
> def __init__(self):
> self.chromosome = get_chromosome()
>
> On the other hand, something like a string chromosome Is A chromosome,
> and so is a list-of-ints Chromosome:
>
> class Chromosome(object):
> pass # abstract class
>
> class StringChromosome(Chromosome):
> pass # implement extra/different functionality
>
> class ListIntsChromosome(Chromosome):
> pass
>
> > I'm just having
> > trouble envisioning how this would be coded at the population level.
>
> There are so many ways... here's one possibility that doesn't even use a
> Population class.
>
> chromosome = StringChromosome # the class, not an instance
> default_genes = "GATACATATGGATTAGGGACCACTAC"
> size = 100
> population = []
> for i in range(size):
> genes = chromosome(default_genes)
> genes.mutate()
> population.append(Individual(genes))
>
> I'm sure you can modify that to work on a class instance basis.
>
> > 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.
>
> Just pass the class itself. For example:
>
> # Define a class.
> class Parrot(object):
> pass
>
> x = "Parrot" # x is the NAME of the class
> y = Parrot # y is the CLASS itself
> z = Parrot() # z is an INSTANCE of the class
>
> You can use the class as a object, exactly the same as you can use a dict
> or a string or a float or any other object. y() will create a new Parrot
> instance exactly the same way that Parrot() would.
>
> Here's one possibility:
>
> class Population(object):
> def __init__(self, size=1000, chromosome_type=StringChromosome):
> individuals = []
> for i in xrange(size):
> genes = chromosome_type() # create new set of genes
> x = Individual(genes) # add them to a new individual
> individuals.append(x) # and store it in the population
> self.individuals = individuals
>
> > 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.
>
> The only time you need something like that is when you need to go from
> user-input (a string) to a binary object (e.g. a class, a function...).
> Suppose you read the crossover type from a text config file, or user
> input:
>
> import Crossover
> xover = raw_input("Enter a crossover type: valid values are X, Y, Z: ")
> crossover_function = getattr(Crossover, "%s_crossover" % xover)
>
> Instead of passing the string xover around as a parameter, you use it
> *once* to get the actual function object itself, and pass that around.
>
> Another alternative is to define something like this in the Crossover
> module, assuming you have three functions xcrossover etc.:
>
> user_map = {"X": xcrossover, "Y": ycrossover, "Z": zcrossover}
>
> Again, use it once to get the function object from the user input.
>
> Hope this helps,
>
> --
> Steven

This is a lot of the information I was looking for. I especially
appreciate the sample code. I'll be able to hack something together
with this. Thanks.

Terry Reedy

1/28/2008 1:01:00 AM

0


"Max" <thelanguageofcities@gmail.com> wrote in message
news:caf75b0d-7ed3-421a-93f8-6f7d90a98923@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



Max

1/28/2008 1:28:00 AM

0

On Jan 27, 8:01 pm, "Terry Reedy" <tjre...@udel.edu> wrote:
> "Max" <thelanguageofcit...@gmail.com> wrote in message
>
> news:caf75b0d-7ed3-421a-93f8-6f7d90a98923@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

Yeah, I looked up some of those GAs, but talking with people about
code helps me a lot more than looking at other code. I know it's
strange for a programmer to prefer social interaction, but...just
something about how I'm wired.

This sounds a lot like what I was thinking of doing. In particular, I
was planning on having the problem's program itself (which would
create an instance of a GA to optimize something) specify the fitness
function and pass it upwards to the population (or maybe to the GA,
which contains a population).

Thanks for the help.

Steven D'Aprano

1/28/2008 1:29:00 AM

0

On Mon, 28 Jan 2008 00:35:51 +0100, Wildemar Wildenburger wrote:

> Max wrote:
>> 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 not sure I'm following you here. So a "chromosome" is bit of
> functionality, right? So basically it is a function. So my advice would
> be to write these functions and store it to the "indivuals"-list like
> so:

No, a chromosome is a bit of *data*: a noun, not a verb. Read these bits
again:

"Individuals HAVE what's called a chromosome - a SPECIFICATION of what it
contains. For example, common chromosomes are BIT STRINGS, ..."

Emphasis added. Sorry for the shouting.

Some background which may help you understand what the OP is asking for.

Genetic Algorithms simulate biological genetic process for problem
solving. The basic idea is this: suppose you can find a way to encode
possible solutions to a problem as a sequence in some sense. e.g. a
sequence of Yes/No decisions might be 011001. That's the "Chromosome" the
OP is talking about. Furthermore, suppose you can mutate such a solution:
011001 might become 011011. Then, so long as some relatively common
assumptions hold, you can zero in on a good solution by starting with a
bad solution and incrementally improving it:

* start with a lot of bad or mediocre solutions
* pick the best solution in the population
* make lots of copies
* mutate the copies slightly
* now pick the best solution of them

Repeat until done.

The analogy is with the process of evolution, only very much simplified.

Such GAs are capable of finding solutions which people have never thought
of. Sometimes those solutions are baroque and virtually unintelligible.
Sometimes they're amazingly simple.

In one famous case, a hardware GA actually found a working electrical
circuit which was not only smaller than any similar circuit that human
engineers had found, but according to a naive understanding of
electronics, it shouldn't have worked at all! It contained an open
circuit, but removing the open circuit stopped the rest from working.


--
Steven

Wildemar Wildenburger

1/28/2008 12:24:00 PM

0

Steven D'Aprano wrote:
>> I'm not sure I'm following you here. So a "chromosome" is bit of
>> functionality, right? So basically it is a function. So my advice would
>> be to write these functions and store it to the "indivuals"-list like
>> so:
>
> No, a chromosome is a bit of *data*: a noun, not a verb. Read these bits
> again:
>
> "Individuals HAVE what's called a chromosome - a SPECIFICATION of what it
> contains. For example, common chromosomes are BIT STRINGS, ..."
>
Oh, OK. I *sort of* got this. Sort of. My reasoning was that these
functions would return their associated "representation" upon being
called. Which makes not much sense, especially after your explanation.



> Some background which may help you understand what the OP is asking for.
>
> [snip little GA-intro]
>
Thanks Steven, that sure was useful. I think I now have a new toy
hammer. I'm sure I'll see myself looking for toy nails everywhere over
the next few weeks.

:)
/W