From 2143aac34f8ea24c4853bdd9ef865ccb71f362bf Mon Sep 17 00:00:00 2001 From: melevir Date: Thu, 19 Dec 2013 06:30:41 +0400 Subject: [PATCH] PEP8 fixes --- pyevolve/Network.py | 812 +++++++++++++++++++++--------------------- pyevolve/Scaling.py | 209 +++++------ pyevolve/Selectors.py | 283 ++++++++------- 3 files changed, 661 insertions(+), 643 deletions(-) diff --git a/pyevolve/Network.py b/pyevolve/Network.py index f885bd7..50b12a1 100644 --- a/pyevolve/Network.py +++ b/pyevolve/Network.py @@ -26,421 +26,429 @@ import Consts import logging + def getMachineIP(): - """ Return all the IPs from current machine. + """ Return all the IPs from current machine. + + Example: + >>> Util.getMachineIP() + ['200.12.124.181', '192.168.0.1'] - Example: - >>> Util.getMachineIP() - ['200.12.124.181', '192.168.0.1'] + :rtype: a python list with the string IPs - :rtype: a python list with the string IPs + """ + hostname = socket.gethostname() + addresses = socket.getaddrinfo(hostname, None) + ips = [x[4][0] for x in addresses] + return ips - """ - hostname = socket.gethostname() - addresses = socket.getaddrinfo(hostname, None) - ips = [x[4][0] for x in addresses] - return ips class UDPThreadBroadcastClient(threading.Thread): - """ The Broadcast UDP client thread class. - - This class is a thread to serve as Pyevolve client on the UDP - datagrams, it is used to send data over network lan/wan. - - Example: - >>> s = Network.UDPThreadClient('192.168.0.2', 1500, 666) - >>> s.setData("Test data") - >>> s.start() - >>> s.join() - - :param host: the hostname to bind the socket on sender (this is NOT the target host) - :param port: the sender port (this is NOT the target port) - :param target_port: the destination port target - - """ - def __init__(self, host, port, target_port): - threading.Thread.__init__(self) - self.host = host - self.port = port - self.targetPort = target_port - self.data = None - self.sentBytes = None - self.sentBytesLock = threading.Lock() - - self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - self.sock.bind((host, port)) - - def setData(self, data): - """ Set the data to send - - :param data: the data to send - - """ - self.data = data - - def getData(self): - """ Get the data to send - - :rtype: data to send - - """ - return self.data - - def close(self): - """ Close the internal socket """ - self.sock.close() - - def getSentBytes(self): - """ Returns the number of sent bytes. The use of this method makes sense - when you already have sent the data - - :rtype: sent bytes - - """ - sent = None - with self.sentBytesLock: - if self.sentBytes is None: - Util.raiseException('Bytes sent is None') - else: sent = self.sentBytes - return sent - - def send(self): - """ Broadcasts the data """ - return self.sock.sendto(self.data, (Consts.CDefBroadcastAddress, self.targetPort)) - - def run(self): - """ Method called when you call *.start()* of the thread """ - if self.data is None: - Util.raiseException('You must set the data with setData method', ValueError) - - with self.sentBytesLock: - self.sentBytes = self.send() - self.close() + """ The Broadcast UDP client thread class. + + This class is a thread to serve as Pyevolve client on the UDP + datagrams, it is used to send data over network lan/wan. + + Example: + >>> s = Network.UDPThreadClient('192.168.0.2', 1500, 666) + >>> s.setData("Test data") + >>> s.start() + >>> s.join() + + :param host: the hostname to bind the socket on sender (this is NOT the target host) + :param port: the sender port (this is NOT the target port) + :param target_port: the destination port target + + """ + def __init__(self, host, port, target_port): + threading.Thread.__init__(self) + self.host = host + self.port = port + self.targetPort = target_port + self.data = None + self.sentBytes = None + self.sentBytesLock = threading.Lock() + + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + self.sock.bind((host, port)) + + def setData(self, data): + """ Set the data to send + + :param data: the data to send + + """ + self.data = data + + def getData(self): + """ Get the data to send + + :rtype: data to send + + """ + return self.data + + def close(self): + """ Close the internal socket """ + self.sock.close() + + def getSentBytes(self): + """ Returns the number of sent bytes. The use of this method makes sense + when you already have sent the data + + :rtype: sent bytes + + """ + sent = None + with self.sentBytesLock: + if self.sentBytes is None: + Util.raiseException('Bytes sent is None') + else: + sent = self.sentBytes + return sent + + def send(self): + """ Broadcasts the data """ + return self.sock.sendto(self.data, (Consts.CDefBroadcastAddress, self.targetPort)) + + def run(self): + """ Method called when you call *.start()* of the thread """ + if self.data is None: + Util.raiseException('You must set the data with setData method', ValueError) + + with self.sentBytesLock: + self.sentBytes = self.send() + self.close() + class UDPThreadUnicastClient(threading.Thread): - """ The Unicast UDP client thread class. - - This class is a thread to serve as Pyevolve client on the UDP - datagrams, it is used to send data over network lan/wan. - - Example: - >>> s = Network.UDPThreadClient('192.168.0.2', 1500) - >>> s.setData("Test data") - >>> s.setTargetHost('192.168.0.50', 666) - >>> s.start() - >>> s.join() - - :param host: the hostname to bind the socket on sender (this is not the target host) - :param port: the sender port (this is not the target port) - :param pool_size: the size of send pool - :param timeout: the time interval to check if the client have data to send - - """ - def __init__(self, host, port, pool_size=10, timeout=0.5): - threading.Thread.__init__(self) - self.host = host - self.port = port - self.target = [] - self.sendPool = [] - self.poolSize = pool_size - self.sendPoolLock = threading.Lock() - self.timeout = timeout - - self.doshutdown = False - - self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - #self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.sock.bind((host, port)) - - def poolLength(self): - """ Returns the size of the pool - - :rtype: integer - - """ - with self.sendPoolLock: - ret = len(self.sendPool) - return ret - - def popPool(self): - """ Return the last data received on the pool - - :rtype: object - - """ - with self.sendPoolLock: - ret = self.sendPool.pop() - return ret - - def isReady(self): - """ Returns True when there is data on the pool or False when not - - :rtype: boolean - - """ - with self.sendPoolLock: - ret = True if len(self.sendPool) >= 1 else False - return ret - - def shutdown(self): - """ Shutdown the server thread, when called, this method will stop - the thread on the next socket timeout """ - self.doshutdown = True - - def addData(self, data): - """ Set the data to send - - :param data: the data to send - - """ - if self.poolLength() >= self.poolSize: - logging.warning('the send pool is full, consider increasing the pool size or decreasing the timeout !') - return - - with self.sendPoolLock: - self.sendPool.append(data) - - def setTargetHost(self, host, port): - """ Set the host/port of the target, the destination - - :param host: the target host - :param port: the target port - - .. note:: the host will be ignored when using broadcast mode - """ - del self.target[:] - self.target.append((host, port)) - - def setMultipleTargetHost(self, address_list): - """ Sets multiple host/port targets, the destinations - - :param address_list: a list with tuples (ip, port) - """ - del self.target[:] - self.target = address_list[:] - - def close(self): - """ Close the internal socket """ - self.sock.close() - - def send(self, data): - """ Send the data - - :param data: the data to send - :rtype: bytes sent to each destination - """ - bytes = -1 - for destination in self.target: - bytes = self.sock.sendto(data, destination) - return bytes - - def run(self): - """ Method called when you call *.start()* of the thread """ - if len(self.target) <= 0: - Util.raiseException('You must set the target(s) before send data', ValueError) - - while True: - if self.doshutdown: break - - while self.isReady(): - data = self.popPool() - self.send(data) - - time.sleep(self.timeout) - - self.close() + """ The Unicast UDP client thread class. + + This class is a thread to serve as Pyevolve client on the UDP + datagrams, it is used to send data over network lan/wan. + + Example: + >>> s = Network.UDPThreadClient('192.168.0.2', 1500) + >>> s.setData("Test data") + >>> s.setTargetHost('192.168.0.50', 666) + >>> s.start() + >>> s.join() + + :param host: the hostname to bind the socket on sender (this is not the target host) + :param port: the sender port (this is not the target port) + :param pool_size: the size of send pool + :param timeout: the time interval to check if the client have data to send + + """ + def __init__(self, host, port, pool_size=10, timeout=0.5): + threading.Thread.__init__(self) + self.host = host + self.port = port + self.target = [] + self.sendPool = [] + self.poolSize = pool_size + self.sendPoolLock = threading.Lock() + self.timeout = timeout + + self.doshutdown = False + + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + #self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.sock.bind((host, port)) + + def poolLength(self): + """ Returns the size of the pool + + :rtype: integer + + """ + with self.sendPoolLock: + ret = len(self.sendPool) + return ret + + def popPool(self): + """ Return the last data received on the pool + + :rtype: object + + """ + with self.sendPoolLock: + ret = self.sendPool.pop() + return ret + + def isReady(self): + """ Returns True when there is data on the pool or False when not + + :rtype: boolean + + """ + with self.sendPoolLock: + ret = True if len(self.sendPool) >= 1 else False + return ret + + def shutdown(self): + """ Shutdown the server thread, when called, this method will stop + the thread on the next socket timeout """ + self.doshutdown = True + + def addData(self, data): + """ Set the data to send + + :param data: the data to send + + """ + if self.poolLength() >= self.poolSize: + logging.warning('the send pool is full, consider increasing the pool size or decreasing the timeout !') + return + + with self.sendPoolLock: + self.sendPool.append(data) + + def setTargetHost(self, host, port): + """ Set the host/port of the target, the destination + + :param host: the target host + :param port: the target port + + .. note:: the host will be ignored when using broadcast mode + """ + del self.target[:] + self.target.append((host, port)) + + def setMultipleTargetHost(self, address_list): + """ Sets multiple host/port targets, the destinations + + :param address_list: a list with tuples (ip, port) + """ + del self.target[:] + self.target = address_list[:] + + def close(self): + """ Close the internal socket """ + self.sock.close() + + def send(self, data): + """ Send the data + + :param data: the data to send + :rtype: bytes sent to each destination + """ + bytes = -1 + for destination in self.target: + bytes = self.sock.sendto(data, destination) + return bytes + + def run(self): + """ Method called when you call *.start()* of the thread """ + if len(self.target) <= 0: + Util.raiseException('You must set the target(s) before send data', ValueError) + + while True: + if self.doshutdown: + break + + while self.isReady(): + data = self.popPool() + self.send(data) + + time.sleep(self.timeout) + + self.close() + class UDPThreadServer(threading.Thread): - """ The UDP server thread class. - - This class is a thread to serve as Pyevolve server on the UDP - datagrams, it is used to receive data from network lan/wan. - - Example: - >>> s = UDPThreadServer("192.168.0.2", 666, 10) - >>> s.start() - >>> s.shutdown() - - :param host: the host to bind the server - :param port: the server port to bind - :param poolSize: the size of the server pool - :param timeout: the socket timeout - - .. note:: this thread implements a pool to keep the received data, - the *poolSize* parameter specifies how much individuals - we must keep on the pool until the *popPool* method - is called; when the pool is full, the sever will - discard the received individuals. - - """ - def __init__(self, host, port, poolSize=10, timeout=3): - threading.Thread.__init__(self) - self.recvPool = [] - self.recvPoolLock = threading.Lock() - self.bufferSize = 4096 - self.host = host - self.port = port - self.timeout = timeout - self.doshutdown = False - self.poolSize = poolSize - - self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - #self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.sock.bind((host, port)) - self.sock.settimeout(self.timeout) - - def shutdown(self): - """ Shutdown the server thread, when called, this method will stop - the thread on the next socket timeout """ - self.doshutdown = True - - def isReady(self): - """ Returns True when there is data on the pool or False when not - - :rtype: boolean - - """ - with self.recvPoolLock: - ret = True if len(self.recvPool) >= 1 else False - return ret - - def poolLength(self): - """ Returns the size of the pool - - :rtype: integer - - """ - with self.recvPoolLock: - ret = len(self.recvPool) - return ret - - def popPool(self): - """ Return the last data received on the pool - - :rtype: object - - """ - with self.recvPoolLock: - ret = self.recvPool.pop() - return ret - - def close(self): - """ Closes the internal socket """ - self.sock.close() - - def setBufferSize(self, size): - """ Sets the receive buffer size - - :param size: integer - - """ - self.bufferSize = size - - def getBufferSize(self): - """ Gets the current receive buffer size - - :rtype: integer - - """ - return self.bufferSize - - def getData(self): - """ Calls the socket *recvfrom* method and waits for the data, - when the data is received, the method will return a tuple - with the IP of the sender and the data received. When a timeout - exception occurs, the method return None. - - :rtype: tuple (sender ip, data) or None when timeout exception - - """ - try: - data, sender = self.sock.recvfrom(self.bufferSize) - except socket.timeout: - return None - return (sender[0], data) - - def run(self): - """ Called when the thread is started by the user. This method - is the main of the thread, when called, it will enter in loop - to wait data or shutdown when needed. - """ - while True: - # Get the data - data = self.getData() - # Shutdown called - if self.doshutdown: break - # The pool is full - if self.poolLength() >= self.poolSize: - continue - # There is no data received - if data == None: continue - # It's a packet from myself - if data[0] == self.host: - continue - with self.recvPoolLock: - self.recvPool.append(data) - - self.close() + """ The UDP server thread class. + + This class is a thread to serve as Pyevolve server on the UDP + datagrams, it is used to receive data from network lan/wan. + + Example: + >>> s = UDPThreadServer("192.168.0.2", 666, 10) + >>> s.start() + >>> s.shutdown() + + :param host: the host to bind the server + :param port: the server port to bind + :param poolSize: the size of the server pool + :param timeout: the socket timeout + + .. note:: this thread implements a pool to keep the received data, + the *poolSize* parameter specifies how much individuals + we must keep on the pool until the *popPool* method + is called; when the pool is full, the sever will + discard the received individuals. + + """ + def __init__(self, host, port, poolSize=10, timeout=3): + threading.Thread.__init__(self) + self.recvPool = [] + self.recvPoolLock = threading.Lock() + self.bufferSize = 4096 + self.host = host + self.port = port + self.timeout = timeout + self.doshutdown = False + self.poolSize = poolSize + + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + #self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.sock.bind((host, port)) + self.sock.settimeout(self.timeout) + + def shutdown(self): + """ Shutdown the server thread, when called, this method will stop + the thread on the next socket timeout """ + self.doshutdown = True + + def isReady(self): + """ Returns True when there is data on the pool or False when not + + :rtype: boolean + + """ + with self.recvPoolLock: + ret = True if len(self.recvPool) >= 1 else False + return ret + + def poolLength(self): + """ Returns the size of the pool + + :rtype: integer + + """ + with self.recvPoolLock: + ret = len(self.recvPool) + return ret + + def popPool(self): + """ Return the last data received on the pool + + :rtype: object + + """ + with self.recvPoolLock: + ret = self.recvPool.pop() + return ret + + def close(self): + """ Closes the internal socket """ + self.sock.close() + + def setBufferSize(self, size): + """ Sets the receive buffer size + + :param size: integer + + """ + self.bufferSize = size + + def getBufferSize(self): + """ Gets the current receive buffer size + + :rtype: integer + + """ + return self.bufferSize + + def getData(self): + """ Calls the socket *recvfrom* method and waits for the data, + when the data is received, the method will return a tuple + with the IP of the sender and the data received. When a timeout + exception occurs, the method return None. + + :rtype: tuple (sender ip, data) or None when timeout exception + + """ + try: + data, sender = self.sock.recvfrom(self.bufferSize) + except socket.timeout: + return None + return sender[0], data + + def run(self): + """ Called when the thread is started by the user. This method + is the main of the thread, when called, it will enter in loop + to wait data or shutdown when needed. + """ + while True: + # Get the data + data = self.getData() + # Shutdown called + if self.doshutdown: + break + # The pool is full + if self.poolLength() >= self.poolSize: + continue + # There is no data received + if data is None: + continue + # It's a packet from myself + if data[0] == self.host: + continue + with self.recvPoolLock: + self.recvPool.append(data) + + self.close() + def pickleAndCompress(obj, level=9): - """ Pickles the object and compress the dumped string with zlib - - :param obj: the object to be pickled - :param level: the compression level, 9 is the best - and -1 is to not compress - - """ - pickled = cPickle.dumps(obj) - if level < 0: return pickled - else: - if not ZLIB_SUPPORT: - Util.raiseException('zlib not found !', ImportError) - pickled_zlib = zlib.compress(pickled, level) - return pickled_zlib + """ Pickles the object and compress the dumped string with zlib + + :param obj: the object to be pickled + :param level: the compression level, 9 is the best + and -1 is to not compress + + """ + pickled = cPickle.dumps(obj) + if level < 0: + return pickled + else: + if not ZLIB_SUPPORT: + Util.raiseException('zlib not found !', ImportError) + pickled_zlib = zlib.compress(pickled, level) + return pickled_zlib + def unpickleAndDecompress(obj_dump, decompress=True): - """ Decompress a zlib compressed string and unpickle the data - - :param obj: the object to be decompressend and unpickled - """ - if decompress: - if not ZLIB_SUPPORT: - Util.raiseException('zlib not found !', ImportError) - obj_decompress = zlib.decompress(obj_dump) - else: - obj_decompress = obj_dump - return cPickle.loads(obj_decompress) + """ Decompress a zlib compressed string and unpickle the data + + :param obj: the object to be decompressend and unpickled + """ + if decompress: + if not ZLIB_SUPPORT: + Util.raiseException('zlib not found !', ImportError) + obj_decompress = zlib.decompress(obj_dump) + else: + obj_decompress = obj_dump + return cPickle.loads(obj_decompress) + if __name__ == "__main__": - arg = sys.argv[1] - myself = getMachineIP() - - if arg == "server": - s = UDPThreadServer(myself[0], 666) - s.start() - - while True: - print ".", - time.sleep(10) - if s.isReady(): - item = s.popPool() - print item - time.sleep(4) - s.shutdown() - break - - - elif arg == "client": - print "Binding on %s..." % myself[0] - s = UDPThreadUnicastClient(myself[0], 1500) - s.setData("dsfssdfsfddf") - s.setTargetHost(myself[0], 666) - s.start() - s.join() - print s.getSentBytes() - - print "end..." - - - + arg = sys.argv[1] + myself = getMachineIP() + + if arg == "server": + s = UDPThreadServer(myself[0], 666) + s.start() + + while True: + print ".", + time.sleep(10) + if s.isReady(): + item = s.popPool() + print item + time.sleep(4) + s.shutdown() + break + + elif arg == "client": + print "Binding on %s..." % myself[0] + s = UDPThreadUnicastClient(myself[0], 1500) + s.setData("dsfssdfsfddf") + s.setTargetHost(myself[0], 666) + s.start() + s.join() + print s.getSentBytes() + + print "end..." diff --git a/pyevolve/Scaling.py b/pyevolve/Scaling.py index 71dd9ec..09be894 100644 --- a/pyevolve/Scaling.py +++ b/pyevolve/Scaling.py @@ -11,121 +11,124 @@ import math import logging + def LinearScaling(pop): - """ Linear Scaling scheme - - .. warning :: Linear Scaling is only for positive raw scores - - """ - logging.debug("Running linear scaling.") - pop.statistics() - c = Consts.CDefScaleLinearMultiplier - a = b = delta = 0.0 - - pop_rawAve = pop.stats["rawAve"] - pop_rawMax = pop.stats["rawMax"] - pop_rawMin = pop.stats["rawMin"] - - if pop_rawAve == pop_rawMax: - a = 1.0 - b = 0.0 - elif pop_rawMin > (c * pop_rawAve - pop_rawMax / c - 1.0): - delta = pop_rawMax - pop_rawAve - a = (c - 1.0) * pop_rawAve / delta - b = pop_rawAve * (pop_rawMax - (c * pop_rawAve)) / delta - else: - delta = pop_rawAve - pop_rawMin - a = pop_rawAve / delta - b = -pop_rawMin * pop_rawAve / delta - - for i in xrange(len(pop)): - f = pop[i].score - if f < 0.0: - Util.raiseException("Score %r is negative, linear scaling not supported !" % (f,), ValueError) - f = f * a + b - if f < 0: - f = 0.0 - pop[i].fitness = f + """ Linear Scaling scheme + + .. warning :: Linear Scaling is only for positive raw scores + + """ + logging.debug("Running linear scaling.") + pop.statistics() + c = Consts.CDefScaleLinearMultiplier + + pop_rawAve = pop.stats["rawAve"] + pop_rawMax = pop.stats["rawMax"] + pop_rawMin = pop.stats["rawMin"] + + if pop_rawAve == pop_rawMax: + a = 1.0 + b = 0.0 + elif pop_rawMin > (c * pop_rawAve - pop_rawMax / c - 1.0): + delta = pop_rawMax - pop_rawAve + a = (c - 1.0) * pop_rawAve / delta + b = pop_rawAve * (pop_rawMax - (c * pop_rawAve)) / delta + else: + delta = pop_rawAve - pop_rawMin + a = pop_rawAve / delta + b = -pop_rawMin * pop_rawAve / delta + + for i in xrange(len(pop)): + f = pop[i].score + if f < 0.0: + Util.raiseException("Score %r is negative, linear scaling not supported !" % (f,), ValueError) + f = f * a + b + if f < 0: + f = 0.0 + pop[i].fitness = f + def SigmaTruncScaling(pop): - """ Sigma Truncation scaling scheme, allows negative scores """ - logging.debug("Running sigma truncation scaling.") - pop.statistics() - c = Consts.CDefScaleSigmaTruncMultiplier - pop_rawAve = pop.stats["rawAve"] - pop_rawDev = pop.stats["rawDev"] - for i in xrange(len(pop)): - f = pop[i].score - pop_rawAve - f+= c * pop_rawDev - if f < 0: f = 0.0 - pop[i].fitness = f + """ Sigma Truncation scaling scheme, allows negative scores """ + logging.debug("Running sigma truncation scaling.") + pop.statistics() + c = Consts.CDefScaleSigmaTruncMultiplier + pop_rawAve = pop.stats["rawAve"] + pop_rawDev = pop.stats["rawDev"] + for i in xrange(len(pop)): + f = pop[i].score - pop_rawAve + f += c * pop_rawDev + if f < 0: + f = 0.0 + pop[i].fitness = f + def PowerLawScaling(pop): - """ Power Law scaling scheme + """ Power Law scaling scheme - .. warning :: Power Law Scaling is only for positive raw scores + .. warning :: Power Law Scaling is only for positive raw scores - """ - logging.debug("Running power law scaling.") - k = Consts.CDefScalePowerLawFactor - for i in xrange(len(pop)): - f = pop[i].score - if f < 0.0: - Util.raiseException("Score %r is negative, power law scaling not supported !" % (f,), ValueError) - f = math.pow(f, k) - pop[i].fitness = f + """ + logging.debug("Running power law scaling.") + k = Consts.CDefScalePowerLawFactor + for i in xrange(len(pop)): + f = pop[i].score + if f < 0.0: + Util.raiseException("Score %r is negative, power law scaling not supported !" % (f,), ValueError) + f = math.pow(f, k) + pop[i].fitness = f def BoltzmannScaling(pop): - """ Boltzmann scaling scheme. You can specify the **boltz_temperature** to the - population parameters, this parameter will set the start temperature. You - can specify the **boltz_factor** and the **boltz_min** parameters, the **boltz_factor** - is the value that the temperature will be subtracted and the **boltz_min** is the - mininum temperature of the scaling scheme. - - .. versionadded: 0.6 - The `BoltzmannScaling` function. - - """ - boltz_temperature = pop.getParam("boltz_temperature", Consts.CDefScaleBoltzStart) - boltz_factor = pop.getParam("boltz_factor", Consts.CDefScaleBoltzFactor) - boltz_min = pop.getParam("boltz_min", Consts.CDefScaleBoltzMinTemp) - - boltz_temperature-= boltz_factor - boltz_temperature = max(boltz_temperature, boltz_min) - pop.setParams(boltzTemperature=boltz_temperature) - - boltz_e = [] - avg = 0.0 - - for i in xrange(len(pop)): - val = math.exp(pop[i].score / boltz_temperature) - boltz_e.append(val) - avg += val - - avg /= len(pop) - - for i in xrange(len(pop)): - pop[i].fitness = boltz_e[i] / avg - -def ExponentialScaling(pop): - """ Exponential Scaling Scheme. The fitness will be the same as (e^score). + """ Boltzmann scaling scheme. You can specify the **boltz_temperature** to the + population parameters, this parameter will set the start temperature. You + can specify the **boltz_factor** and the **boltz_min** parameters, the **boltz_factor** + is the value that the temperature will be subtracted and the **boltz_min** is the + mininum temperature of the scaling scheme. - .. versionadded: 0.6 - The `ExponentialScaling` function. - """ - for i in xrange(len(pop)): - score = pop[i].score - pop[i].fitness = math.exp(score) + .. versionadded: 0.6 + The `BoltzmannScaling` function. -def SaturatedScaling(pop): - """ Saturated Scaling Scheme. The fitness will be the same as 1.0-(e^score) + """ + boltz_temperature = pop.getParam("boltz_temperature", Consts.CDefScaleBoltzStart) + boltz_factor = pop.getParam("boltz_factor", Consts.CDefScaleBoltzFactor) + boltz_min = pop.getParam("boltz_min", Consts.CDefScaleBoltzMinTemp) + + boltz_temperature -= boltz_factor + boltz_temperature = max(boltz_temperature, boltz_min) + pop.setParams(boltzTemperature=boltz_temperature) + + boltz_e = [] + avg = 0.0 - .. versionadded: 0.6 - The `SaturatedScaling` function. - """ - for i in xrange(len(pop)): - score = pop[i].score - pop[i].fitness = 1.0 - math.exp(score) + for i in xrange(len(pop)): + val = math.exp(pop[i].score / boltz_temperature) + boltz_e.append(val) + avg += val + avg /= len(pop) + for i in xrange(len(pop)): + pop[i].fitness = boltz_e[i] / avg + + +def ExponentialScaling(pop): + """ Exponential Scaling Scheme. The fitness will be the same as (e^score). + + .. versionadded: 0.6 + The `ExponentialScaling` function. + """ + for i in xrange(len(pop)): + score = pop[i].score + pop[i].fitness = math.exp(score) + + +def SaturatedScaling(pop): + """ Saturated Scaling Scheme. The fitness will be the same as 1.0-(e^score) + + .. versionadded: 0.6 + The `SaturatedScaling` function. + """ + for i in xrange(len(pop)): + score = pop[i].score + pop[i].fitness = 1.0 - math.exp(score) diff --git a/pyevolve/Selectors.py b/pyevolve/Selectors.py index 7367480..14aba73 100644 --- a/pyevolve/Selectors.py +++ b/pyevolve/Selectors.py @@ -9,169 +9,176 @@ import random import Consts -import operator + def GRankSelector(population, **args): - """ The Rank Selector - This selector will pick the best individual of - the population every time. - """ - count = 0 - - if args["popID"] != GRankSelector.cachePopID: - if population.sortType == Consts.sortType["scaled"]: - best_fitness = population.bestFitness().fitness - for index in xrange(1, len(population.internalPop)): - if population[index].fitness == best_fitness: - count += 1 - else: - best_raw = population.bestRaw().score - for index in xrange(1, len(population.internalPop)): - if population[index].score == best_raw: - count += 1 - - GRankSelector.cachePopID = args["popID"] - GRankSelector.cacheCount = count - - else: count = GRankSelector.cacheCount - - return population[random.randint(0, count)] + """ The Rank Selector - This selector will pick the best individual of + the population every time. + """ + count = 0 + + if args["popID"] != GRankSelector.cachePopID: + if population.sortType == Consts.sortType["scaled"]: + best_fitness = population.bestFitness().fitness + for index in xrange(1, len(population.internalPop)): + if population[index].fitness == best_fitness: + count += 1 + else: + best_raw = population.bestRaw().score + for index in xrange(1, len(population.internalPop)): + if population[index].score == best_raw: + count += 1 + + GRankSelector.cachePopID = args["popID"] + GRankSelector.cacheCount = count + + else: + count = GRankSelector.cacheCount + + return population[random.randint(0, count)] GRankSelector.cachePopID = None GRankSelector.cacheCount = None + def GUniformSelector(population, **args): - """ The Uniform Selector """ - return population[random.randint(0, len(population)-1)] + """ The Uniform Selector """ + return population[random.randint(0, len(population)-1)] + def GTournamentSelector(population, **args): - """ The Tournament Selector - - It accepts the *tournamentPool* population parameter. + """ The Tournament Selector + + It accepts the *tournamentPool* population parameter. + + .. note:: + the Tournament Selector uses the Roulette Wheel to + pick individuals for the pool - .. note:: - the Tournament Selector uses the Roulette Wheel to - pick individuals for the pool + .. versionchanged:: 0.6 + Changed the parameter `poolSize` to the `tournamentPool`, now the selector + gets the pool size from the population. - .. versionchanged:: 0.6 - Changed the parameter `poolSize` to the `tournamentPool`, now the selector - gets the pool size from the population. + """ + should_minimize = population.minimax == Consts.minimaxType["minimize"] + minimax_operator = min if should_minimize else max - """ - choosen = None - should_minimize = population.minimax == Consts.minimaxType["minimize"] - minimax_operator = min if should_minimize else max + poolSize = population.getParam("tournamentPool", Consts.CDefTournamentPoolSize) + tournament_pool = [GRouletteWheel(population, **args) for _ in xrange(poolSize)] - poolSize = population.getParam("tournamentPool", Consts.CDefTournamentPoolSize) - tournament_pool = [GRouletteWheel(population, **args) for i in xrange(poolSize) ] + if population.sortType == Consts.sortType["scaled"]: + choosen = minimax_operator(tournament_pool, key=lambda ind: ind.fitness) + else: + choosen = minimax_operator(tournament_pool, key=lambda ind: ind.score) - if population.sortType == Consts.sortType["scaled"]: - choosen = minimax_operator(tournament_pool, key=lambda ind: ind.fitness) - else: - choosen = minimax_operator(tournament_pool, key=lambda ind: ind.score) + return choosen - return choosen def GTournamentSelectorAlternative(population, **args): - """ The alternative Tournament Selector - - This Tournament Selector don't uses the Roulette Wheel + """ The alternative Tournament Selector - It accepts the *tournamentPool* population parameter. + This Tournament Selector don't uses the Roulette Wheel - .. versionadded: 0.6 - Added the GTournamentAlternative function. + It accepts the *tournamentPool* population parameter. - """ - pool_size = population.getParam("tournamentPool", Consts.CDefTournamentPoolSize) - len_pop = len(population) - should_minimize = population.minimax == Consts.minimaxType["minimize"] - minimax_operator = min if should_minimize else max - tournament_pool = [population[random.randint(0, len_pop-1)] for i in xrange(pool_size)] - - if population.sortType == Consts.sortType["scaled"]: - choosen = minimax_operator(tournament_pool, key=lambda ind: ind.fitness) - else: - choosen = minimax_operator(tournament_pool, key=lambda ind: ind.score) + .. versionadded: 0.6 + Added the GTournamentAlternative function. + + """ + pool_size = population.getParam("tournamentPool", Consts.CDefTournamentPoolSize) + len_pop = len(population) + should_minimize = population.minimax == Consts.minimaxType["minimize"] + minimax_operator = min if should_minimize else max + tournament_pool = [population[random.randint(0, len_pop-1)] for i in xrange(pool_size)] + + if population.sortType == Consts.sortType["scaled"]: + choosen = minimax_operator(tournament_pool, key=lambda ind: ind.fitness) + else: + choosen = minimax_operator(tournament_pool, key=lambda ind: ind.score) + + return choosen - return choosen def GRouletteWheel(population, **args): - """ The Roulette Wheel selector """ - psum = None - if args["popID"] != GRouletteWheel.cachePopID: - GRouletteWheel.cachePopID = args["popID"] - psum = GRouletteWheel_PrepareWheel(population) - GRouletteWheel.cacheWheel = psum - else: - psum = GRouletteWheel.cacheWheel - - cutoff = random.random() - lower = 0 - upper = len(population) - 1 - while(upper >= lower): - i = lower + ((upper-lower)/2) - if psum[i] > cutoff: upper = i-1 - else: lower = i+1 - - lower = min(len(population)-1, lower) - lower = max(0, lower) - - return population.bestFitness(lower) + """ The Roulette Wheel selector """ + if args["popID"] != GRouletteWheel.cachePopID: + GRouletteWheel.cachePopID = args["popID"] + psum = GRouletteWheel_PrepareWheel(population) + GRouletteWheel.cacheWheel = psum + else: + psum = GRouletteWheel.cacheWheel + + cutoff = random.random() + lower = 0 + upper = len(population) - 1 + while upper >= lower: + i = lower + ((upper-lower)/2) + if psum[i] > cutoff: + upper = i - 1 + else: + lower = i + 1 + + lower = min(len(population)-1, lower) + lower = max(0, lower) + + return population.bestFitness(lower) + GRouletteWheel.cachePopID = None GRouletteWheel.cacheWheel = None + def GRouletteWheel_PrepareWheel(population): - """ A preparation for Roulette Wheel selection """ - - len_pop = len(population) - - psum = [i for i in xrange(len_pop)] - - population.statistics() - - if population.sortType == Consts.sortType["scaled"]: - pop_fitMax = population.stats["fitMax"] - pop_fitMin = population.stats["fitMin"] - - if pop_fitMax == pop_fitMin: - for index in xrange(len_pop): - psum[index] = (index+1) / float(len_pop) - elif (pop_fitMax > 0 and pop_fitMin >= 0) or (pop_fitMax <= 0 and pop_fitMin < 0): - population.sort() - if population.minimax == Consts.minimaxType["maximize"]: - psum[0] = population[0].fitness - for i in xrange(1, len_pop): - psum[i] = population[i].fitness + psum[i-1] - for i in xrange(len_pop): - psum[i] /= float(psum[len_pop - 1]) - else: - psum[0] = -population[0].fitness + pop_fitMax + pop_fitMin - for i in xrange(1, len_pop): - psum[i] = -population[i].fitness + pop_fitMax + pop_fitMin + psum[i-1] - for i in xrange(len_pop): - psum[i] /= float(psum[len_pop - 1]) - else: - pop_rawMax = population.stats["rawMax"] - pop_rawMin = population.stats["rawMin"] - - if pop_rawMax == pop_rawMin: - for index in xrange(len_pop): - psum[index] = (index+1) / float(len_pop) - - elif (pop_rawMax > 0 and pop_rawMin >= 0) or (pop_rawMax <= 0 and pop_rawMin < 0): - population.sort() - if population.minimax == Consts.minimaxType["maximize"]: - psum[0] = population[0].score - for i in xrange(1, len_pop): - psum[i] = population[i].score + psum[i-1] - for i in xrange(len_pop): - psum[i] /= float(psum[len_pop-1]) - else: - psum[0] = - population[0].score + pop_rawMax + pop_rawMin - for i in xrange(1, len_pop): - psum[i] = - population[i].score + pop_rawMax + pop_rawMin + psum[i-1] - for i in xrange(len_pop): - psum[i] /= float(psum[len_pop-1]) - - return psum + """ A preparation for Roulette Wheel selection """ + + len_pop = len(population) + + psum = [i for i in xrange(len_pop)] + + population.statistics() + + if population.sortType == Consts.sortType["scaled"]: + pop_fitMax = population.stats["fitMax"] + pop_fitMin = population.stats["fitMin"] + + if pop_fitMax == pop_fitMin: + for index in xrange(len_pop): + psum[index] = (index+1) / float(len_pop) + elif (pop_fitMax > 0 and pop_fitMin >= 0) or (pop_fitMax <= 0 and pop_fitMin < 0): + population.sort() + if population.minimax == Consts.minimaxType["maximize"]: + psum[0] = population[0].fitness + for i in xrange(1, len_pop): + psum[i] = population[i].fitness + psum[i-1] + for i in xrange(len_pop): + psum[i] /= float(psum[len_pop - 1]) + else: + psum[0] = -population[0].fitness + pop_fitMax + pop_fitMin + for i in xrange(1, len_pop): + psum[i] = -population[i].fitness + pop_fitMax + pop_fitMin + psum[i-1] + for i in xrange(len_pop): + psum[i] /= float(psum[len_pop - 1]) + else: + pop_rawMax = population.stats["rawMax"] + pop_rawMin = population.stats["rawMin"] + + if pop_rawMax == pop_rawMin: + for index in xrange(len_pop): + psum[index] = (index+1) / float(len_pop) + + elif (pop_rawMax > 0 and pop_rawMin >= 0) or (pop_rawMax <= 0 and pop_rawMin < 0): + population.sort() + if population.minimax == Consts.minimaxType["maximize"]: + psum[0] = population[0].score + for i in xrange(1, len_pop): + psum[i] = population[i].score + psum[i-1] + for i in xrange(len_pop): + psum[i] /= float(psum[len_pop-1]) + else: + psum[0] = - population[0].score + pop_rawMax + pop_rawMin + for i in xrange(1, len_pop): + psum[i] = - population[i].score + pop_rawMax + pop_rawMin + psum[i-1] + for i in xrange(len_pop): + psum[i] /= float(psum[len_pop-1]) + + return psum