Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
Update for Python 3 compatibility
  • Loading branch information
BubaVV authored Aug 25, 2016
1 parent 589b6a9 commit 07b000a
Show file tree
Hide file tree
Showing 53 changed files with 11,763 additions and 614 deletions.
537 changes: 537 additions & 0 deletions Consts.py

Large diffs are not rendered by default.

810 changes: 810 additions & 0 deletions Crossovers.py

Large diffs are not rendered by default.

792 changes: 792 additions & 0 deletions DBAdapters.py

Large diffs are not rendered by default.

202 changes: 202 additions & 0 deletions FunctionSlot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
"""
:mod:`FunctionSlot` -- function slots module
==================================================================
The *function slot* concept is large used by Pyevolve, the idea
is simple, each genetic operator or any operator, can be assigned
to a slot, by this way, we can add more than simple one operator,
we can have for example, two or more mutator operators at same time,
two or more evaluation functions, etc. In this :mod:`FunctionSlot` module,
you'll find the class :class:`FunctionSlot.FunctionSlot`, which is the slot class.
"""

from random import uniform as rand_uniform

from . import Util
import collections

class FunctionSlot(object):
""" FunctionSlot Class - The function slot
Example:
>>> genome.evaluator.set(eval_func)
>>> genome.evaluator[0]
<function eval_func at 0x018C8930>
>>> genome.evaluator
Slot [Evaluation Function] (Count: 1)
Name: eval_func
>>> genome.evaluator.clear()
>>> genome.evaluator
Slot [Evaluation Function] (Count: 0)
No function
You can add weight to functions when using the `rand_apply` paramter:
>>> genome.evaluator.set(eval_main, 0.9)
>>> genome.evaluator.add(eval_sec, 0.3)
>>> genome.evaluator.setRandomApply()
In the above example, the function *eval_main* will be called with 90% of
probability and the *eval_sec* will be called with 30% of probability.
There are another way to add functions too:
>>> genome.evaluator += eval_func
:param name: the slot name
:param rand_apply: if True, just one of the functions in the slot
will be applied, this function is randomly picked based
on the weight of the function added.
"""

def __init__(self, name="Anonymous Function", rand_apply=False):
""" The creator of the FunctionSlot Class """
self.funcList = []
self.funcWeights = []
self.slotName = name
self.rand_apply = rand_apply

def __typeCheck(self, func):
""" Used internally to check if a function passed to the
function slot is callable. Otherwise raises a TypeError exception.
:param func: the function object
"""
if not isinstance(func, collections.Callable):

This comment has been minimized.

Copy link
@wkdawson

wkdawson Oct 21, 2022

wls (windows linux subsystem), python3.10 no longer accepts "collections.Callable". I had to change it to "collections.abc.Callable". Python3.9 still had the workaround, and it seems to have been the case since python3.3, based on the information at "https://docs.python.org/3.10/library/collections.abc.html". So, even if maybe this is a failure of "future", this should be kept in mind.

Util.raiseException("The function must be a method or function", TypeError)

def __iadd__(self, func):
""" To add more functions using the += operator
.. versionadded:: 0.6
The __iadd__ method.
"""
self.__typeCheck(func)
self.funcList.append(func)
return self

def __getitem__(self, index):
""" Used to retrieve some slot function index """
return self.funcList[index]

def __setitem__(self, index, value):
""" Used to set the index slot function """
self.__typeCheck(value)
self.funcList[index] = value

def __iter__(self):
""" Return the function list iterator """
return iter(self.funcList)

def __len__(self):
""" Return the number of functions on the slot
.. versionadded:: 0.6
The *__len__* method
"""
return len(self.funcList)

def setRandomApply(self, flag=True):
""" Sets the random function application, in this mode, the
function will randomly choose one slot to apply
:param flag: True or False
"""
if not isinstance(flag, bool):
Util.raiseException("Random option must be True or False", TypeError)

self.rand_apply = flag

def clear(self):
""" Used to clear the functions in the slot """
if len(self.funcList) > 0:
del self.funcList[:]
del self.funcWeights[:]

def add(self, func, weight=0.5):
""" Used to add a function to the slot
:param func: the function to be added in the slot
:param weight: used when you enable the *random apply*, it's the weight
of the function for the random selection
.. versionadded:: 0.6
The `weight` parameter.
"""
self.__typeCheck(func)
self.funcList.append(func)
self.funcWeights.append(weight)

def isEmpty(self):
""" Return true if the function slot is empy """
return (len(self.funcList) == 0)

def set(self, func, weight=0.5):
""" Used to clear all functions in the slot and add one
:param func: the function to be added in the slot
:param weight: used when you enable the *random apply*, it's the weight
of the function for the random selection
.. versionadded:: 0.6
The `weight` parameter.
.. note:: the method *set* of the function slot remove all previous
functions added to the slot.
"""
self.clear()
self.__typeCheck(func)
self.add(func, weight)

def apply(self, index, obj, **args):
""" Apply the index function
:param index: the index of the function
:param obj: this object is passes as parameter to the function
:param args: this args dictionary is passed to the function
"""
if len(self.funcList) <= 0:
raise Exception("No function defined: " + self.slotName)
return self.funcList[index](obj, **args)

def applyFunctions(self, obj=None, **args):
""" Generator to apply all function slots in obj
:param obj: this object is passes as parameter to the function
:param args: this args dictionary is passed to the function
"""
if len(self.funcList) <= 0:
Util.raiseException("No function defined: " + self.slotName)

if not self.rand_apply:
for f in self.funcList:
yield f(obj, **args)
else:
v = rand_uniform(0, 1)
fobj = None
for func, weight in zip(self.funcList, self.funcWeights):
fobj = func
if v < weight:
break
v = v - weight

yield fobj(obj, **args)

def __repr__(self):
""" String representation of FunctionSlot """
strRet = "Slot [%s] (Count: %d)\n" % (self.slotName, len(self.funcList))

if len(self.funcList) <= 0:
strRet += "\t\tNo function\n"
return strRet

for f, w in zip(self.funcList, self.funcWeights):
strRet += "\t\tName: %s - Weight: %.2f\n" % (f.__name__, w)
if f.__doc__:
strRet += "\t\tDoc: " + f.__doc__ + "\n"

return strRet
173 changes: 173 additions & 0 deletions G1DBinaryString.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
"""
:mod:`G1DBinaryString` -- the classical binary string chromosome
=====================================================================
This is the classical chromosome representation on GAs, it is the 1D
Binary String. This string looks like "00011101010".
Default Parameters
-------------------------------------------------------------
*Initializator*
:func:`Initializators.G1DBinaryStringInitializator`
The Binatry String Initializator for G1DBinaryString
*Mutator*
:func:`Mutators.G1DBinaryStringMutatorFlip`
The Flip Mutator for G1DBinaryString
*Crossover*
:func:`Crossovers.G1DBinaryStringXSinglePoint`
The Single Point Crossover for G1DBinaryString
Class
-------------------------------------------------------------
"""

from .GenomeBase import GenomeBase, G1DBase
from . import Consts
from . import Util

class G1DBinaryString(G1DBase):
""" G1DBinaryString Class - The 1D Binary String chromosome
Inheritance diagram for :class:`G1DBinaryString.G1DBinaryString`:
.. inheritance-diagram:: G1DBinaryString.G1DBinaryString
This chromosome class extends the :class:`GenomeBase.G1DBase` class.
Example:
>>> genome = G1DBinaryString.G1DBinaryString(5)
:param length: the 1D Binary String size
"""
__slots__ = ["stringLength"]

def __init__(self, length=10):
""" The initializator of G1DList representation """
super(G1DBinaryString, self).__init__(length)
self.genomeList = []
self.stringLength = length
self.initializator.set(Consts.CDefG1DBinaryStringInit)
self.mutator.set(Consts.CDefG1DBinaryStringMutator)
self.crossover.set(Consts.CDefG1DBinaryStringCrossover)

def __setitem__(self, key, value):
""" Set the specified value for an gene of List
>>> g = G1DBinaryString(5)
>>> for i in xrange(len(g)):
... g.append(1)
>>> g[4] = 0
>>> g[4]
0
"""
if isinstance(value, int) and value not in (0,1):
Util.raiseException("The value must be zero (0) or one (1), used (%s)" % value, ValueError)
elif isinstance(value, list) and not set(value) <= set([0, 1]):
# if slice notation is used we check all passed values
vals = set(value) - set([0, 1])
Util.raiseException("The value must be zero (0) or one (1), used (%s)" % vals, ValueError)
G1DBase.__setitem__(self, key, value)

def __repr__(self):
""" Return a string representation of Genome """
ret = GenomeBase.__repr__(self)
ret += "- G1DBinaryString\n"
ret += "\tString length:\t %s\n" % (self.getListSize(),)
ret += "\tString:\t\t %s\n\n" % (self.getBinary(),)
return ret

def getDecimal(self):
""" Converts the binary string to decimal representation
Example:
>>> g = G1DBinaryString(5)
>>> for i in xrange(len(g)):
... g.append(0)
>>> g[3] = 1
>>> g.getDecimal()
2
:rtype: decimal value
"""
return int(self.getBinary(), 2)

def getBinary(self):
""" Returns the binary string representation
Example:
>>> g = G1DBinaryString(2)
>>> g.append(0)
>>> g.append(1)
>>> g.getBinary()
'01'
:rtype: the binary string
"""
return "".join(map(str, self))

def append(self, value):
""" Appends an item to the list
Example:
>>> g = G1DBinaryString(2)
>>> g.append(0)
:param value: value to be added, 0 or 1
"""
if value not in [0, 1]:
Util.raiseException("The value must be 0 or 1", ValueError)
G1DBase.append(self, value)

def copy(self, g):
""" Copy genome to 'g'
Example:
>>> g1 = G1DBinaryString(2)
>>> g1.append(0)
>>> g1.append(1)
>>> g2 = G1DBinaryString(2)
>>> g1.copy(g2)
>>> g2[1]
1
:param g: the destination genome
"""
GenomeBase.copy(self, g)
G1DBase.copy(self, g)

def clone(self):
""" Return a new instace copy of the genome
Example:
>>> g = G1DBinaryString(5)
>>> for i in xrange(len(g)):
... g.append(1)
>>> clone = g.clone()
>>> clone[0]
1
:rtype: the G1DBinaryString instance clone
"""
newcopy = G1DBinaryString(self.getListSize())
self.copy(newcopy)
return newcopy
Loading

1 comment on commit 07b000a

@wkdawson
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FunctionSlot.py line 66
wls (windows linux subsystem, default Ubuntu, Windows 11), python3.10 no longer accepts "collections.Callable". I had to change it to "collections.abc.Callable". Python3.9 still had the workaround, and it seems to have been the case since python3.3, based on the information at "https://docs.python.org/3.10/library/collections.abc.html". So, even if maybe this is a failure of "future", this should be kept in mind.

Please sign in to comment.