From 7168dc01564d87ac63100da6d3e80342a56545fe Mon Sep 17 00:00:00 2001 From: pytlab Date: Wed, 13 Dec 2017 20:20:01 +0800 Subject: [PATCH] Add decimal individual support for flip bit mutation operator. --- gaft/operators/mutation/flip_bit_mutation.py | 19 ++++++++++++++++--- tests/flip_bit_mutation_test.py | 15 +++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/gaft/operators/mutation/flip_bit_mutation.py b/gaft/operators/mutation/flip_bit_mutation.py index 2ef945a..8d7195b 100644 --- a/gaft/operators/mutation/flip_bit_mutation.py +++ b/gaft/operators/mutation/flip_bit_mutation.py @@ -3,10 +3,12 @@ ''' Flip Bit mutation implementation. ''' -from random import random +from random import random, uniform from ...mpiutil import mpi from ...plugin_interfaces.operators.mutation import Mutation +from ...components.binary_individual import BinaryIndividual +from ...components.decimal_individual import DecimalIndividual class FlipBitMutation(Mutation): @@ -30,9 +32,20 @@ def mutate(self, individual, engine): if do_mutation: for i, genome in enumerate(individual.chromsome): - do_flip = True if random() <= self.pm else False - if do_flip: + no_flip = True if random() > self.pm else False + if no_flip: + continue + + if type(individual) is BinaryIndividual: individual.chromsome[i] = genome^1 + elif type(individual) is DecimalIndividual: + a, b = individual.ranges[i] + eps = individual.precisions[i] + n_intervals = (b - a)//eps + n = int(uniform(0, n_intervals + 1)) + individual.chromsome[i] = a + n*eps + else: + raise TypeError('Wrong individual type: {}'.format(type(individual))) # Update solution. individual.solution = individual.decode() diff --git a/tests/flip_bit_mutation_test.py b/tests/flip_bit_mutation_test.py index c533a1f..32281e7 100644 --- a/tests/flip_bit_mutation_test.py +++ b/tests/flip_bit_mutation_test.py @@ -6,7 +6,7 @@ import unittest -from gaft.components import BinaryIndividual +from gaft.components import BinaryIndividual, DecimalIndividual from gaft.operators.mutation.flip_bit_mutation import FlipBitMutation class FlipBitMutationTest(unittest.TestCase): @@ -14,7 +14,7 @@ class FlipBitMutationTest(unittest.TestCase): def setUp(self): self.maxDiff - def test_mutate(self): + def test_mutate_binary_indv(self): ''' Make sure the individual can be mutated correctly. ''' indv = BinaryIndividual(ranges=[(0, 1)], verbosity=0).init(solution=[0.398]) @@ -25,6 +25,17 @@ def test_mutate(self): mutation.mutate(indv, engine=None) self.assertListEqual(indv.chromsome, chromsome_after) + def test_mutate_decimal_indv(self): + ''' Make sure individual with decimal encoding can be mutated correctly. + ''' + indv = DecimalIndividual(ranges=[(0, 1), (0, 2)]).init(solution=[0.5, 1.5]) + mutation = FlipBitMutation(pm=1.0) + chromsome_before = [0.5, 1.5] + self.assertListEqual(indv.chromsome, chromsome_before) + mutation.mutate(indv, engine=None) + for a, b in zip(indv.chromsome, chromsome_before): + self.assertNotEqual(a, b) + if '__main__' == __name__: suite = unittest.TestLoader().loadTestsFromTestCase(FlipBitMutationTest) unittest.TextTestRunner(verbosity=2).run(suite)