Skip to content

Commit

Permalink
Added support for a new mutator similar to Gaussian but called Gaussi…
Browse files Browse the repository at this point in the history
…anGradient

The following four mutators are new:
G1DListMutatorRealGaussianGradient
G1DListMutatorIntegerGaussianGradient
G2DListMutatorRealGaussianGradient
G2DListMutatorIntegerGaussianGradient

The main difference between Gaussian and GaussianGradient is that
GaussianGradient uses a multiplicative modification rather than an additive.

GaussianGradient's mu and sigma are absolute, not relative. So if the default
values of mu=2 and std=10 (why not mu=0?) are used, the random gaussian number
is a flat number around 2. If we're working on a huge range, like say 0-100000,
this is a very small drift.

GaussianGradient uses mu=1.0 and std=0.1 to generate a number around 1.0. This
is then *multiplied* by the gene to provide subtle drift regardless of how
large the range is.

2 new constants added, Mu and Sigma for the GaussianGradient routines.
  • Loading branch information
booherbg committed Sep 4, 2011
1 parent 1ca74aa commit f94c321
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pyevolve/Consts.py
Expand Up @@ -489,6 +489,10 @@
CDefG2DListInit = Initializators.G2DListInitializatorInteger
CDefG2DListCrossUniformProb = 0.5

# Gaussian Gradient
CDefGaussianGradientMU = 1.0
CDefGaussianGradientSIGMA = 0.1

# - DB Adapters SQLite defaults
CDefSQLiteDBName = "pyevolve.db"
CDefSQLiteDBTable = "statistics"
Expand Down
181 changes: 181 additions & 0 deletions pyevolve/Mutators.py
Expand Up @@ -165,6 +165,48 @@ def G1DListMutatorRealRange(genome, **args):

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.1
Same as IntegerGaussian, except that this uses relative gradient rather than
absolute gaussian. A value is randomly generated about gauss(mu=1, sigma=.1)
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[which_gene] = final_value

return int(mutations)

def G1DListMutatorIntegerGaussian(genome, **args):
""" A gaussian mutator for G1DList of Integers
Expand Down Expand Up @@ -254,6 +296,53 @@ def G1DListMutatorRealGaussian(genome, **args):

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.1
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.1 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[which_gene] = final_value

return int(mutations)

def G1DListMutatorIntegerBinary(genome, **args):
""" The mutator of G1DList, the binary mutator
Expand Down Expand Up @@ -377,6 +466,53 @@ def G2DListMutatorIntegerRange(genome, **args):
return int(mutations)


def G2DListMutatorIntegerGaussianGradient(genome, **args):
""" 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.1 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
height, width = genome.getSize()
elements = height * width

mutations = args["pmut"] * elements

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 = int(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))

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)

final_value = int(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))

genome.setItem(which_y, which_x, final_value)

return int(mutations)

def G2DListMutatorIntegerGaussian(genome, **args):
""" A gaussian mutator for G2DList of Integers
Expand Down Expand Up @@ -520,6 +656,51 @@ def G2DListMutatorRealGaussian(genome, **args):

return int(mutations)

def G2DListMutatorRealGaussianGradient(genome, **args):
""" 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.1), allowing
for a smooth gradient drift about the value.
"""
if args["pmut"] <= 0.0: return 0
height, width = genome.getSize()
elements = height * width

mutations = args["pmut"] * elements

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

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)

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

genome.setItem(which_y, which_x, final_value)

return int(mutations)

#############################
## 2D Binary String ##
Expand Down

0 comments on commit f94c321

Please sign in to comment.