diff --git a/deap/benchmarks/binary.py b/deap/benchmarks/binary.py index e97ad7324..1522f4c62 100644 --- a/deap/benchmarks/binary.py +++ b/deap/benchmarks/binary.py @@ -13,8 +13,6 @@ # You should have received a copy of the GNU Lesser General Public # License along with DEAP. If not, see . -from __future__ import division -import math def bin2float(min_, max_, nbits): """Convert a binary array into an array of float where each @@ -27,13 +25,9 @@ def bin2float(min_, max_, nbits): """ def wrap(function): def wrapped_function(individual, *args, **kargs): - nelem = len(individual)/nbits - if nelem.is_integer(): - nelem = int(nelem) - else: - raise ValueError( - "Got an array of size %s to divide into %s parts" % ( - nbits, nelem)) + # // Forces the division behavior to be the same in python2 and + # python3; user must take care to make nelem an integer. + nelem = len(individual)//nbits decoded = [0] * nelem for i in xrange(nelem): gene = int("".join(map(str, @@ -45,6 +39,7 @@ def wrapped_function(individual, *args, **kargs): return wrapped_function return wrap + def trap(individual): u = sum(individual) k = len(individual) @@ -53,6 +48,7 @@ def trap(individual): else: return k - 1 - u + def inv_trap(individual): u = sum(individual) k = len(individual) @@ -61,6 +57,7 @@ def inv_trap(individual): else: return u - 1 + def chuang_f1(individual): """Binary deceptive function from : Multivariate Multi-Model Approach for Globally Multimodal Problems by Chung-Yao Chuang and Wen-Lian Hsu. @@ -70,13 +67,14 @@ def chuang_f1(individual): """ total = 0 if individual[-1] == 0: - for i in xrange(0,len(individual)-1,4): + for i in xrange(0, len(individual)-1, 4): total += inv_trap(individual[i:i+4]) else: - for i in xrange(0,len(individual)-1,4): + for i in xrange(0, len(individual)-1, 4): total += trap(individual[i:i+4]) return total, + def chuang_f2(individual): """Binary deceptive function from : Multivariate Multi-Model Approach for Globally Multimodal Problems by Chung-Yao Chuang and Wen-Lian Hsu. @@ -86,19 +84,20 @@ def chuang_f2(individual): """ total = 0 if individual[-2] == 0 and individual[-1] == 0: - for i in xrange(0,len(individual)-2,8): + for i in xrange(0, len(individual)-2, 8): total += inv_trap(individual[i:i+4]) + inv_trap(individual[i+4:i+8]) elif individual[-2] == 0 and individual[-1] == 1: - for i in xrange(0,len(individual)-2,8): + for i in xrange(0, len(individual)-2, 8): total += inv_trap(individual[i:i+4]) + trap(individual[i+4:i+8]) elif individual[-2] == 1 and individual[-1] == 0: - for i in xrange(0,len(individual)-2,8): + for i in xrange(0, len(individual)-2, 8): total += trap(individual[i:i+4]) + inv_trap(individual[i+4:i+8]) else: - for i in xrange(0,len(individual)-2,8): + for i in xrange(0, len(individual)-2, 8): total += trap(individual[i:i+4]) + trap(individual[i+4:i+8]) return total, + def chuang_f3(individual): """Binary deceptive function from : Multivariate Multi-Model Approach for Globally Multimodal Problems by Chung-Yao Chuang and Wen-Lian Hsu. @@ -108,20 +107,21 @@ def chuang_f3(individual): """ total = 0 if individual[-1] == 0: - for i in xrange(0,len(individual)-1,4): + for i in xrange(0, len(individual)-1, 4): total += inv_trap(individual[i:i+4]) else: - for i in xrange(2,len(individual)-3,4): + for i in xrange(2, len(individual)-3, 4): total += inv_trap(individual[i:i+4]) total += trap(individual[-2:]+individual[:2]) return total, + # Royal Road Functions def royal_road1(individual, order): """Royal Road Function R1 as presented by Melanie Mitchell in : "An introduction to Genetic Algorithms". """ - nelem = len(individual) / order + nelem = len(individual) // order max_value = int(2**order - 1) total = 0 for i in xrange(nelem): @@ -129,6 +129,7 @@ def royal_road1(individual, order): total += int(order) * int(value/max_value) return total, + def royal_road2(individual, order): """Royal Road Function R2 as presented by Melanie Mitchell in : "An introduction to Genetic Algorithms". @@ -139,4 +140,3 @@ def royal_road2(individual, order): total += royal_road1(norder, individual)[0] norder *= 2 return total, - diff --git a/deap/tests/test_benchmarks.py b/deap/tests/test_benchmarks.py index 06b9f6d72..21ffe8520 100644 --- a/deap/tests/test_benchmarks.py +++ b/deap/tests/test_benchmarks.py @@ -1,4 +1,5 @@ """Test functions from deap/benchmarks.""" +import sys import unittest from nose import with_setup from past.builtins import xrange @@ -29,20 +30,34 @@ def tearDown(self): def test_bin2float(self): + # Correct evaluation of bin2float. zero_individual = creator.Individual([0 for x in xrange(10)]) full_individual = creator.Individual([1 for x in xrange(10)]) two_individiual = creator.Individual(8*[0] + [1, 0]) - population = [zero_individual, full_individual, two_individiual] - fitnesses = map(self.toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit - assert population[0].fitness.values == (0.0, ) assert population[1].fitness.values == (1023.0, ) assert population[2].fitness.values == (2.0, ) + # Incorrect evaluation of bin2float. + wrong_size_individual = creator.Individual([0, 1, 0, 1, 0, 1, 0, 1, 1]) + wrong_population = [wrong_size_individual] + # It is up the user to make sure that bin2float gets an individual with + # an adequate length; no exceptions are raised. + fitnesses = map(self.toolbox.evaluate, wrong_population) + for ind, fit in zip(wrong_population, fitnesses): + # In python 2.7 operator.mul works in a different way than in + # python3. Thus an error occurs in python2.7 but an assignment is + # correctly executed in python3. + if sys.version_info < (3, ): + with self.assertRaises(TypeError): + ind.fitness.values = fit + else: + assert wrong_population[0].fitness.values == () + if __name__ == "__main__": suite = unittest.TestLoader().loadTestsFromTestCase(BenchmarkTest)