Exemple #1
0
def unexpected_case(cl: Classifier, p0: Perception, p1: Perception,
                    time: int) -> Optional[Classifier]:
    """
    Controls the unexpected case of the classifier.

    :param cl:
    :param p0:
    :param p1:
    :param time:
    :return: specialized classifier if generation was possible,
    None otherwise
    """
    cl.decrease_quality()
    cl.set_mark(p0)

    # Return if the effect is not specializable
    if not cl.effect.is_specializable(p0, p1):
        return None

    child = cl.copy_from(cl, time)

    child.specialize(p0, p1, leave_specialized=True)

    if child.q < 0.5:
        child.q = 0.5

    return child
Exemple #2
0
    def test_should_copy_classifier(self, cfg):
        # given
        operation_time = 123
        original_cl = Classifier(condition='1###1011',
                                 action=1,
                                 effect='10####1#',
                                 reward=50,
                                 quality=0.7,
                                 cfg=cfg)

        # when
        copied_cl = Classifier.copy_from(original_cl, operation_time)

        # Assert that we are dealing with different object
        assert original_cl is not copied_cl

        # Assert that condition is equal but points to another object
        assert original_cl.condition == copied_cl.condition
        assert original_cl.condition is not copied_cl.condition

        # Assert that action is equal
        assert original_cl.action == copied_cl.action

        # Assert that effect is equal but points to another object
        assert original_cl.effect == copied_cl.effect
        assert original_cl.effect is not copied_cl.effect

        # Assert that other properties were set accordingly
        assert copied_cl.is_marked() is False
        assert 50 == copied_cl.r
        assert 0.7 == copied_cl.q
        assert operation_time == copied_cl.tga
        assert operation_time == copied_cl.talp
Exemple #3
0
    def test_copy_from_and_mutate_does_not_influence_another_condition(
            self, cfg):
        """ Verify that not just reference to Condition copied (changing which
        will change the original - definitily not original C++ code did). """
        # given
        s = cfg.mu * 0.5  # less then MU
        b = 1 - (1 - cfg.mu) * 0.5  # more then MU

        operation_time = 123
        original_cl = Classifier(condition='1###1011', cfg=cfg)

        copied_cl = Classifier.copy_from(original_cl, operation_time)

        # when
        mutate(copied_cl, cfg.mu, RandomMock([s, b, b, b, b]))

        # then
        assert Condition('####1011') == copied_cl.condition
        assert Condition('1###1011') == original_cl.condition

        # when
        mutate(original_cl, cfg.mu, RandomMock([b, s, b, b, b]))

        # then
        assert Condition('1####011') == original_cl.condition
        assert Condition('####1011') == copied_cl.condition
Exemple #4
0
def unexpected_case(cl: Classifier, p0: Perception, p1: Perception,
                    time: int) -> Optional[Classifier]:
    """
    Controls the unexpected case of the classifier.

    :param cl:
    :param p0:
    :param p1:
    :param time:
    :return: specialized classifier if generation was possible,
    None otherwise
    """
    cl.decrease_quality()
    cl.set_mark(p0)

    # Return if the effect is not specializable
    if not cl.effect.is_specializable(p0, p1):
        return None

    child = cl.copy_from(cl, time)

    if cl.cfg.do_pee:
        # Probability-Enhanced attributes cannot appear in the effect part
        # if we leave already specialized attributes unchanged.
        # Therefore don't leave specialized.
        child.specialize(p0, p1, leave_specialized=False)
    else:
        child.specialize(p0, p1, leave_specialized=True)

    if child.q < 0.5:
        child.q = 0.5

    return child
Exemple #5
0
def expected_case(cl: Classifier, p0: Perception,
                  time: int) -> Optional[Classifier]:
    """
    Controls the expected case of a classifier. If the classifier
    is too specific it tries to add some randomness to it by
    generalizing some attributes.

    :param cl:
    :param p0:
    :param time:
    :return: new classifier or None
    """
    if cl.cfg.do_pee:
        cl.effect.update_enhanced_effect_probs(p0, cl.cfg.beta)

    diff = cl.mark.get_differences(p0)

    if diff.specificity == 0:
        if cl.cfg.do_pee and cl.is_marked():
            cl.ee = True

        cl.increase_quality()

        return None

    no_spec = len(cl.specified_unchanging_attributes)
    no_spec_new = diff.specificity
    child = cl.copy_from(cl, time)

    if no_spec >= cl.cfg.u_max:
        while no_spec >= cl.cfg.u_max:
            res = cl.generalize_unchanging_condition_attribute()
            assert res is True
            no_spec -= 1

        while no_spec + no_spec_new > cl.cfg.u_max:
            if random() < 0.5:
                diff.generalize_specific_attribute_randomly()
                no_spec_new -= 1
            else:
                if cl.generalize_unchanging_condition_attribute():
                    no_spec -= 1
    else:
        while no_spec + no_spec_new > cl.cfg.u_max:
            diff.generalize_specific_attribute_randomly()
            no_spec_new -= 1

    child.condition.specialize_with_condition(diff)

    if child.q < 0.5:
        child.q = 0.5

    return child
Exemple #6
0
    def test_copy_from_and_change_does_not_influence_another_effect(self, cfg):
        """ Verify that not just reference to Condition copied (changing which
        will change the original - definitily not original C++ code did). """
        # given
        operation_time = 123
        original_cl = Classifier(effect='10####1#', cfg=cfg)

        # when
        copied_cl = Classifier.copy_from(original_cl, operation_time)

        # when & then
        copied_cl.effect[2] = '1'
        assert Effect('101###1#') == copied_cl.effect
        assert Effect('10####1#') == original_cl.effect

        # when & then
        original_cl.effect[3] = '0'
        assert Effect('101###1#') == copied_cl.effect
        assert Effect('10#0##1#') == original_cl.effect