Skip to content

Commit 134d944

Browse files
author
Tomasz bla Fortuna
committed
Importing code into GIT
0 parents  commit 134d944

File tree

129 files changed

+26222
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+26222
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.pyc

BUGS

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
Bugs?
3+
4+
Plenty of bugs to pick over, from design right
5+
through to coding
6+

CHANGELOG

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
Changelog for pygene
2+
3+
December 12, 2005
4+
5+
- version 0.2.1
6+
7+
- renamed Organism class to MendelOrganism, to indicate
8+
that it is based on a 'double-helix' eukaryotic model
9+
- created Organism class, which uses only single helix
10+
(single genes, not gene pairs)
11+
12+
December 11, 2005
13+
14+
- version 0.2
15+
- added genetic programming!!
16+
- with working example
17+
- changed mutation behaviour
18+
- previously, child organisms were mutated in-place
19+
- now, .mutate() on organisms returns a mutated copy
20+
- changed crossover behaviour
21+
- previously, crossover mating only returned one child
22+
- now, crossover mating returns 2 children, so no
23+
genetic material is lost
24+
25+
26+
December 9, 2005
27+
28+
- version 0.1.1
29+
- added more primitive Gene subclasses
30+
- replaced typeless 'gene names' list in Organisms
31+
with a .genome dict
32+
- added XML dump capability for genes, organisms and
33+
populations
34+
- added 'incest' feature, where high-fitness parents
35+
can stay in the population and mate with their
36+
children
37+
- added option for spontaneous appearance of new
38+
random organisms
39+
- simplified the creation of random organisms
40+
41+
December 6, 2005
42+
43+
- version 0.1
44+
45+
- first release
46+

COPYING

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
pygene is written by David McNab <[email protected]>
3+
and is released under the GNU General Public License version 2, the
4+
text of which is available from the GNU Website: http://www.gnu.org
5+
6+
Enquiries regarding commercial licenses are welcome, we
7+
can agree on a package to suit your project and markets
8+

CREDITS

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
pygene was written by David McNab <[email protected]>
3+

INSTALL

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
INSTALL file for pygene
3+
4+
Prerequisites:
5+
- python 2.3 or later
6+
7+
This is a python distutils-compliant package.
8+
9+
To install it, become root and type:
10+
11+
python setup.py install
12+
13+
If you want to run the gui version of the
14+
travelling salesman problem, you'll need to
15+
install fltk (fltk.sf.net) and pyfltk (pyfltk.sf.net)
16+

README

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
Overview:
3+
--------
4+
5+
pygene is my attempt at a genetic algorithms
6+
and genetic programming library
7+
for python that is easy to use and understand
8+
9+
This is your chance to play God.
10+
11+
You design the genome of a species.
12+
13+
You implement a fitness calculation procedure
14+
for members of that species.
15+
16+
You create a population of that species,
17+
then sit back as members of the species indulge
18+
their promiscuous desires.
19+
20+
A given organism's chance of getting laid is proportional
21+
tno its fitness.
22+
23+
Watch as your population evolves closer and closer
24+
to perfection, or converges to something reasonably close
25+
to it.
26+
27+
Documentation:
28+
-------------
29+
30+
To get your nice HTML doco, type:
31+
32+
./makedoc.py
33+
34+
35+
Examples:
36+
--------
37+
38+
There are some examples in the toplevel directory, including:
39+
- Travelling Salesman Problem (console and graphical versions)
40+
- simple converger
41+
- string guesser
42+
- function deriver (genetic programming)
43+

demo_converge.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#! /usr/bin/env python
2+
3+
"""
4+
Very simple demo in which organisms try to minimise
5+
the output value of a function
6+
"""
7+
8+
from pygene.gene import FloatGene, FloatGeneMax
9+
from pygene.organism import Organism, MendelOrganism
10+
from pygene.population import Population
11+
12+
class CvGene(FloatGeneMax):
13+
"""
14+
Gene which represents the numbers used in our organism
15+
"""
16+
# genes get randomly generated within this range
17+
randMin = -100.0
18+
randMax = 100.0
19+
20+
# probability of mutation
21+
mutProb = 0.1
22+
23+
# degree of mutation
24+
mutAmt = 0.1
25+
26+
27+
class Converger(MendelOrganism):
28+
"""
29+
Implements the organism which tries
30+
to converge a function
31+
"""
32+
genome = {'x':CvGene, 'y':CvGene}
33+
34+
def fitness(self):
35+
"""
36+
Implements the 'fitness function' for this species.
37+
Organisms try to evolve to minimise this function's value
38+
"""
39+
return self['x'] ** 2 + self['y'] ** 2
40+
41+
def __repr__(self):
42+
return "<Converger fitness=%f x=%s y=%s>" % (
43+
self.fitness(), self['x'], self['y'])
44+
45+
46+
# create an empty population
47+
48+
pop = Population(species=Converger, init=2, childCount=50, childCull=20)
49+
50+
51+
# now a func to run the population
52+
53+
def main():
54+
try:
55+
while True:
56+
# execute a generation
57+
pop.gen()
58+
59+
# get the fittest member
60+
best = pop.best()
61+
62+
# and dump it out
63+
print best
64+
65+
except KeyboardInterrupt:
66+
pass
67+
68+
69+
if __name__ == '__main__':
70+
main()
71+

demo_fractal.py

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
#! /usr/bin/env python
2+
3+
"""
4+
experiment in using fractals to fit a set of values
5+
6+
may or may not work
7+
"""
8+
9+
import math
10+
11+
from pygene.gene import FloatGene, ComplexGene
12+
from pygene.gene import IntGene, OrBitGene, rndPair
13+
from pygene.organism import Organism
14+
from pygene.population import Population
15+
16+
# data set to model
17+
18+
targetData = [432, 444, 520, 419, 450, 540, 625]
19+
targetDataLen = len(targetData)
20+
21+
# gene classes for fractals
22+
23+
class OrgGene(ComplexGene):
24+
"""
25+
gene to use for initial value
26+
"""
27+
mutProb = 0.03
28+
mutAmt = 0.5
29+
30+
randMin = -2.0
31+
randMax = 2.0
32+
33+
class DeltaGene(ComplexGene):
34+
"""
35+
gene to use for motion
36+
"""
37+
mutProb = 0.03
38+
mutAmt = 1.0
39+
40+
rndMin = -0.4
41+
rndMax = 0.4
42+
43+
44+
class IterationsGene(IntGene):
45+
"""
46+
gene that controls number of mandelbrot iterations
47+
"""
48+
mutProb = 0.001
49+
randMin = 2
50+
randMax = 10
51+
52+
# utility func - standard deviation
53+
54+
def sdev(dataset):
55+
56+
n = float(len(dataset))
57+
mean = sum(dataset) / n
58+
devs = [(x - mean) ** 2 for x in dataset]
59+
sd = math.sqrt(sum(devs) / n)
60+
return mean, sd
61+
62+
# organism class
63+
64+
class FracOrganism(Organism):
65+
"""
66+
organism class
67+
"""
68+
genome = {
69+
'init':OrgGene,
70+
'delta':DeltaGene,
71+
'iterations':IterationsGene,
72+
)
73+
74+
maxIterations = 100
75+
76+
def fitness(self):
77+
"""
78+
fitness is the standard deviation of the ratio of
79+
each generated value to each target value
80+
"""
81+
guessData = self.getDataSet()
82+
badness = 0.0
83+
ratios = [100000.0 * guessData[i] / targetData[i] \
84+
for i in xrange(targetDataLen)]
85+
try:
86+
sd, mean = sdev(ratios)
87+
var = sd / mean
88+
badness = var, sd, mean
89+
except:
90+
#raise
91+
badness = 10000.0, None, None
92+
return badness
93+
94+
def getDataSet(self):
95+
"""
96+
computes the data set resulting from genes
97+
"""
98+
guessData = []
99+
org = self['init']
100+
delta = self['delta']
101+
niterations = self['iterations']
102+
for i in xrange(targetDataLen):
103+
#guessData.append(self.mand(org, niterations))
104+
guessData.append(self.mand(org))
105+
org += delta
106+
return guessData
107+
108+
def mand_old(self, org, niterations):
109+
"""
110+
performs the mandelbrot calculation on point org for
111+
niterations generations,
112+
returns final magnitude
113+
"""
114+
c = complex(0,0)
115+
116+
for i in xrange(niterations):
117+
c = c * c + org
118+
119+
return abs(c)
120+
121+
def mand(self, org):
122+
"""
123+
returns the number of iterations needed for abs(org)
124+
to exceed 1.0
125+
"""
126+
i = 0
127+
c = complex(0,0)
128+
while i < self.maxIterations:
129+
if abs(c) > 1.0:
130+
break
131+
c = c * c + org
132+
i += 1
133+
return i
134+
135+
def newOrganism(self=None):
136+
137+
return FracOrganism(
138+
init=OrgGene,
139+
delta=DeltaGene,
140+
iterations=IterationsGene,
141+
)
142+
143+
class FracPopulation(Population):
144+
145+
species = FracOrganism
146+
initPopulation = 100
147+
148+
# cull to this many children after each generation
149+
childCull = 6
150+
151+
# number of children to create after each generation
152+
childCount = 30
153+
154+
# enable addition of random new organisms
155+
newOrganism = newOrganism
156+
numNewOrganisms = 5
157+
158+
# keep best 5 parents
159+
incest = 5
160+
161+
162+
# create an initial random population
163+
164+
pop = FracPopulation()
165+
166+
167+
# now a func to run the population
168+
def main():
169+
try:
170+
while True:
171+
# execute a generation
172+
pop.gen()
173+
174+
# and dump it out
175+
#print [("%.2f %.2f" % (o['x1'], o['x2'])) for o in pop.organisms]
176+
best = pop.organisms[0]
177+
print "fitness=%s" % (best.fitness(),)
178+
179+
except KeyboardInterrupt:
180+
pass
181+
182+
183+
if __name__ == '__main__':
184+
main()
185+
186+

0 commit comments

Comments
 (0)