示例#1
0
    def test_crossover(self, cfg):
        # given
        parent = Classifier(
            condition=Condition(
                [UBR(1, 1), UBR(1, 1), UBR(1, 1)], cfg),
            effect=Effect(
                [UBR(1, 1), UBR(1, 1), UBR(1, 1)], cfg),
            cfg=cfg)
        donor = Classifier(
            condition=Condition(
                [UBR(2, 2), UBR(2, 2), UBR(2, 2)], cfg),
            effect=Effect(
                [UBR(2, 2), UBR(2, 2), UBR(2, 2)], cfg),
            cfg=cfg)

        # when
        np.random.seed(12345)  # left: 3, right: 6
        crossover(parent, donor)

        # then
        assert parent.condition == \
            Condition([UBR(1, 1), UBR(1, 2), UBR(2, 2)], cfg)
        assert parent.effect == \
            Effect([UBR(1, 1), UBR(1, 2), UBR(2, 2)], cfg)
        assert donor.condition == \
            Condition([UBR(2, 2), UBR(2, 1), UBR(1, 1)], cfg)
        assert donor.effect == \
            Effect([UBR(2, 2), UBR(2, 1), UBR(1, 1)], cfg)
示例#2
0
    def test_should_subsume_effect(self, _effect1, _effect2, _result, cfg):
        # given
        effect1 = Effect(_effect1, cfg=cfg)
        effect2 = Effect(_effect2, cfg=cfg)

        # then
        assert effect1.subsumes(effect2) == _result
示例#3
0
    def test_should_get_maximum_fitness(self, cfg):
        # given
        # anticipate change - low fitness
        cl1 = Classifier(effect=Effect([UBR(0, 1), UBR(0, 3)], cfg),
                         quality=0.3,
                         reward=1,
                         cfg=cfg)

        # do not anticipate change - high fitness
        cl2 = Classifier(effect=Effect([UBR(0, 15), UBR(0, 15)], cfg),
                         quality=0.5,
                         reward=1,
                         cfg=cfg)

        # anticipate change - medium fitness
        cl3 = Classifier(effect=Effect([UBR(0, 14), UBR(0, 15)], cfg),
                         quality=0.4,
                         reward=1,
                         cfg=cfg)

        population = ClassifierList(*[cl1, cl2, cl3])

        # when
        mf = population.get_maximum_fitness()

        # then
        assert mf == cl3.fitness
示例#4
0
def crossover(parent: Classifier, donor: Classifier):
    assert parent.cfg.classifier_length == donor.cfg.classifier_length

    # flatten parent and donor perception strings
    p_cond_flat = _flatten(parent.condition)
    d_cond_flat = _flatten(donor.condition)
    p_effect_flat = _flatten(parent.effect)
    d_effect_flat = _flatten(donor.effect)

    # select crossing points
    left, right = sorted(
        np.random.choice(range(0,
                               len(p_cond_flat) + 1), 2, replace=False))

    assert left < right

    # extract chromosomes
    p_cond_chromosome = p_cond_flat[left:right]
    d_cond_chromosome = d_cond_flat[left:right]
    p_effect_chromosome = p_effect_flat[left:right]
    d_effect_chromosome = d_effect_flat[left:right]

    # Flip everything
    p_cond_flat[left:right] = d_cond_chromosome
    d_cond_flat[left:right] = p_cond_chromosome
    p_effect_flat[left:right] = d_effect_chromosome
    d_effect_flat[left:right] = p_effect_chromosome

    # Rebuild proper perception strings
    parent.condition = Condition(_unflatten(p_cond_flat), cfg=parent.cfg)
    donor.condition = Condition(_unflatten(d_cond_flat), cfg=donor.cfg)
    parent.effect = Effect(_unflatten(p_effect_flat), cfg=parent.cfg)
    donor.effect = Effect(_unflatten(d_effect_flat), cfg=parent.cfg)
示例#5
0
    def test_should_specialize(self, _p0, _p1, _effect, is_specializable, cfg):
        # given
        p0 = Perception(_p0, oktypes=(float, ))
        p1 = Perception(_p1, oktypes=(float, ))
        effect = Effect(_effect, cfg=cfg)

        # then
        assert effect.is_specializable(p0, p1) is is_specializable
示例#6
0
    def test_should_detect_identical_classifier(self, cfg):
        cl_1 = Classifier(condition=Condition([UBR(0, 1), UBR(0, 2)], cfg=cfg),
                          action=1,
                          effect=Effect([UBR(2, 3), UBR(4, 5)], cfg=cfg),
                          cfg=cfg)

        cl_2 = Classifier(condition=Condition([UBR(0, 1), UBR(0, 2)], cfg=cfg),
                          action=1,
                          effect=Effect([UBR(2, 3), UBR(4, 5)], cfg=cfg),
                          cfg=cfg)

        assert cl_1 == cl_2
示例#7
0
    def test_aggressive_mutation(self, _cond, _effect, cfg):
        # given
        condition = Condition(_cond, cfg)
        effect = Effect(_effect, cfg)

        cfg.encoder = RealValueEncoder(16)  # more precise encoder
        cfg.mutation_noise = 0.5  # strong noise mutation range
        mu = 1.0  # mutate every attribute

        cl = Classifier(condition=deepcopy(condition),
                        effect=deepcopy(effect),
                        cfg=cfg)

        # when
        mutate(cl, mu)

        # then
        range_min, range_max = cfg.encoder.range
        for idx, (c, e) in enumerate(zip(cl.condition, cl.effect)):
            # assert that we have new locus
            if condition[idx] != cfg.classifier_wildcard:
                assert condition[idx] != c

            if effect[idx] != cfg.classifier_wildcard:
                assert effect[idx] != e

            # assert if condition values are in ranges
            assert c.lower_bound >= range_min
            assert c.upper_bound <= range_max

            # assert if effect values are in ranges
            assert e.lower_bound >= range_min
            assert e.upper_bound <= range_max
示例#8
0
    def test_should_create_new_classifier_with_covering(
            self, _p0, _p1, _child_cond, _child_effect, cfg):

        # given
        cfg.cover_noise = 0.0

        p0 = Perception(_p0, oktypes=(float, ))
        p1 = Perception(_p1, oktypes=(float, ))
        action = random.randint(0, cfg.number_of_possible_actions)
        time = random.randint(0, 100)

        # when
        new_cl = cover(p0, action, p1, time, cfg)

        # then
        assert new_cl is not None
        assert new_cl.condition == Condition(_child_cond, cfg)
        assert new_cl.action == action
        assert new_cl.effect == Effect(_child_effect, cfg)
        assert new_cl.q == .5
        assert new_cl.r == 0
        assert new_cl.ir == 0
        assert new_cl.tav == 0
        assert new_cl.tga == time
        assert new_cl.talp == time
        # assert new_cl.num == 1
        assert new_cl.exp == 0
示例#9
0
    def test_should_create_copy(self, cfg):
        # given
        operation_time = random.randint(0, 100)
        condition = Condition(
            [self._random_ubr(), self._random_ubr()], cfg=cfg)
        action = random.randint(0, 2)
        effect = Effect([self._random_ubr(), self._random_ubr()], cfg=cfg)

        cl = Classifier(condition,
                        action,
                        effect,
                        quality=random.random(),
                        reward=random.random(),
                        intermediate_reward=random.random(),
                        cfg=cfg)
        # when
        copied_cl = Classifier.copy_from(cl, operation_time)

        # then
        assert cl is not copied_cl
        assert cl.condition == copied_cl.condition
        assert cl.condition is not copied_cl.condition
        assert cl.action == copied_cl.action
        assert cl.effect == copied_cl.effect
        assert cl.effect is not copied_cl.effect
        assert copied_cl.is_marked() is False
        assert cl.r == copied_cl.r
        assert cl.q == copied_cl.q
        assert operation_time == copied_cl.tga
        assert operation_time == copied_cl.talp
示例#10
0
    def test_should_create_pass_through_effect(self, cfg):
        # when
        effect = Effect.pass_through(cfg)

        # then
        assert len(effect) == cfg.classifier_length
        for allele in effect:
            assert allele == cfg.classifier_wildcard
示例#11
0
    def test_should_find_similar(self):
        # given
        cfg = Configuration(3, 2, encoder=RealValueEncoder(2))
        cl1 = Classifier(
            condition=Condition([UBR(0, 0), UBR(0, 3), UBR(0, 3)], cfg=cfg),
            action=0,
            effect=Effect([UBR(0, 3), UBR(0, 3), UBR(0, 3)], cfg=cfg),
            cfg=cfg
        )
        cl2 = Classifier(
            condition=Condition([UBR(0, 0), UBR(0, 3), UBR(0, 3)], cfg=cfg),
            action=0,
            effect=Effect([UBR(0, 3), UBR(0, 3), UBR(0, 3)], cfg=cfg),
            cfg=cfg
        )

        # then
        assert cl1 == cl2
示例#12
0
    def test_should_return_zero_max_fitness(self, cfg):
        # given classifiers that does not anticipate change
        cl1 = Classifier(effect=Effect([UBR(0, 15), UBR(0, 15)], cfg),
                         quality=0.5,
                         reward=1,
                         cfg=cfg)

        cl2 = Classifier(effect=Effect([UBR(0, 15), UBR(0, 15)], cfg),
                         quality=0.7,
                         reward=1,
                         cfg=cfg)

        population = ClassifierList(*[cl1, cl2])

        # when
        mf = population.get_maximum_fitness()

        # then
        assert mf == 0.0
示例#13
0
    def test_should_count_specified_unchanging_attributes(
            self, _condition, _effect, _sua, cfg):

        # given
        cl = Classifier(condition=Condition(_condition, cfg),
                        effect=Effect(_effect, cfg),
                        cfg=cfg)

        # then
        assert len(cl.specified_unchanging_attributes) == _sua
示例#14
0
    def test_should_initialize_without_arguments(self, cfg):
        # when
        c = Classifier(cfg=cfg)

        # then
        assert c.condition == Condition.generic(cfg=cfg)
        assert c.action is None
        assert c.effect == Effect.pass_through(cfg=cfg)
        assert c.exp == 1
        assert c.talp is None
        assert c.tav == 0.0
示例#15
0
    def test_should_detect_subsumption(self, _e1, _e2, _exp1, _marked,
                                       _reliable, _more_general,
                                       _condition_matching, _result, mocker,
                                       cfg):
        # given
        cl1 = Classifier(effect=Effect(_e1, cfg), experience=_exp1, cfg=cfg)
        cl2 = Classifier(effect=Effect(_e2, cfg), cfg=cfg)

        # when
        mocker.patch.object(cl1, "is_reliable")
        mocker.patch.object(cl1, "is_marked")
        mocker.patch.object(cl1, "is_more_general")
        mocker.patch.object(cl1.condition, "does_match_condition")

        cl1.is_reliable.return_value = _reliable
        cl1.is_marked.return_value = _marked
        cl1.is_more_general.return_value = _more_general
        cl1.condition.does_match_condition.return_value = _condition_matching

        # then
        assert cl1.does_subsume(cl2) == _result
示例#16
0
    def test_should_handle_unexpected_case_3(self, cfg):
        # given
        p0 = Perception([.5, .5], oktypes=(float, ))
        p1 = Perception([.5, .8], oktypes=(float, ))
        # Second effect attribute is specializable
        effect = Effect([UBR(0, 15), UBR(10, 14)], cfg=cfg)
        quality = 0.4
        time = random.randint(0, 1000)
        cl = Classifier(effect=effect, quality=quality, cfg=cfg)

        # when
        child = unexpected_case(cl, p0, p1, time)

        # then
        assert cl.q < quality
        assert cl.is_marked() is True

        assert child is not None
        assert child.is_marked() is False
        assert child.q == .5
        assert child.condition == Condition([UBR(0, 15), UBR(0, 15)], cfg=cfg)
        assert child.effect == Effect([UBR(0, 15), UBR(10, 14)], cfg=cfg)
示例#17
0
    def test_should_generalize_randomly_unchanging_condition_attribute(
            self, _condition, _effect, _soa_before, _soa_after, cfg):

        # given
        condition = Condition(_condition, cfg)
        effect = Effect(_effect, cfg)
        cl = Classifier(condition=condition, effect=effect, cfg=cfg)
        assert len(cl.specified_unchanging_attributes) == _soa_before

        # when
        cl.generalize_unchanging_condition_attribute()

        # then
        assert (len(cl.specified_unchanging_attributes)) == _soa_after
示例#18
0
    def test_should_handle_unexpected_case_1(self, cfg):
        # given
        p0 = Perception([.5, .5], oktypes=(float, ))
        p1 = Perception([.5, .5], oktypes=(float, ))
        # Effect is all pass-through. Can be specialized.
        effect = Effect([UBR(0, 15), UBR(0, 15)], cfg=cfg)
        quality = .4
        time = random.randint(0, 1000)
        cl = Classifier(effect=effect, quality=quality, cfg=cfg)

        # when
        child = unexpected_case(cl, p0, p1, time)

        # then
        assert cl.q < quality
        assert cl.is_marked() is True
        assert child
        assert child.q == .5
        assert child.talp == time
        # There is no change in perception so the child condition
        # and effect should stay the same.
        assert child.condition == Condition([UBR(0, 15), UBR(0, 15)], cfg=cfg)
        assert child.effect == Effect([UBR(0, 15), UBR(0, 15)], cfg=cfg)
示例#19
0
    def test_should_handle_unexpected_case_2(self, cfg):
        # given
        p0 = Perception([.5, .5], oktypes=(float, ))
        p1 = Perception([.5, .5], oktypes=(float, ))
        # Effect is not specializable
        effect = Effect([UBR(0, 15), UBR(2, 4)], cfg=cfg)
        quality = random.random()
        time = random.randint(0, 1000)
        cl = Classifier(effect=effect, quality=quality, cfg=cfg)

        # when
        child = unexpected_case(cl, p0, p1, time)

        # then
        assert cl.q < quality
        assert cl.is_marked() is True
        # We cannot generate child from non specializable parent
        assert child is None
示例#20
0
    def test_disabled_mutation(self, _cond, _effect, cfg):
        # given
        condition = Condition(_cond, cfg)
        effect = Effect(_effect, cfg)
        cl = Classifier(condition=deepcopy(condition),
                        effect=deepcopy(effect),
                        cfg=cfg)
        mu = 0.0

        # when
        mutate(cl, mu)

        # then
        for idx, (c, e) in enumerate(zip(cl.condition, cl.effect)):
            assert c.lower_bound == condition[idx].lower_bound
            assert c.upper_bound == condition[idx].upper_bound
            assert e.lower_bound == effect[idx].lower_bound
            assert e.upper_bound == effect[idx].upper_bound
示例#21
0
 def test_should_visualize(self, _effect, _result, cfg):
     assert repr(Effect(_effect, cfg=cfg)) == _result
示例#22
0
 def test_should_flatten_effect(self, _effect, _result, cfg):
     assert _flatten(Effect(_effect, cfg=cfg)) == _result
示例#23
0
 def test_should_detect_change(self, _e, _result, cfg):
     assert Effect(_e, cfg).specify_change == _result