Ejemplo n.º 1
0
    def test_form_sequence_backwards_5(self, cfg):
        # given
        gs = GoalSequenceSearcher()
        cl0 = Classifier(condition="01010101",
                         action=2,
                         effect="0000000",
                         cfg=cfg)
        cl1 = Classifier(condition="11111111",
                         action=0,
                         effect="0000000",
                         cfg=cfg)
        cl2 = Classifier(condition="11111111",
                         action=1,
                         effect="0000000",
                         cfg=cfg)
        gs.backward_classifiers = [
            ClassifiersList(cl0),
            ClassifiersList(cl0, cl1)
        ]
        i = 2
        idx = 0

        # when
        seq = gs._form_sequence_backwards(i, idx, cl2)

        # then
        assert len(seq) == 3
        assert cl0.action in seq
        assert cl1.action in seq
        assert cl2.action in seq
        assert seq == [cl2.action, cl0.action, cl1.action]
Ejemplo n.º 2
0
    def test_find_subsumer_finds_single_subsumer_among_nonsubsumers(self, cfg):
        # given
        subsumer = Classifier(condition='###0####',
                              action=3,
                              effect='##1#####',
                              quality=0.93,
                              reward=1.35,
                              experience=23,
                              cfg=cfg)

        nonsubsumer = Classifier(cfg=cfg)

        classifier = Classifier(condition='1##0####',
                                action=3,
                                effect='##1#####',
                                quality=0.5,
                                reward=0.35,
                                experience=1,
                                cfg=cfg)
        classifiers_list = ClassifiersList(
            *[nonsubsumer, subsumer, nonsubsumer], cfg=cfg)

        # when
        actual_subsumer = classifiers_list.find_subsumer(
            classifier, choice_func=lambda l: l[0])

        # then
        assert actual_subsumer == subsumer
Ejemplo n.º 3
0
def choose_action_from_knowledge_array(cll: ClassifiersList) -> int:
    """
    Creates 'knowledge array' that represents the average quality of the
    anticipation for each action in the current list. Chosen is
    the action, ACS2 knows least about the consequences.

    Parameters
    ----------
    cll: ClassifiersList
        classifier list

    Returns
    -------
    int
        chosen action
    """
    knowledge_array = {
        i: 0.0
        for i in range(cll.cfg.number_of_possible_actions)
    }

    cll.sort(key=lambda cl: cl.action)

    for _action, _clss in groupby(cll, lambda cl: cl.action):
        _classifiers = [cl for cl in _clss]

        agg_q = sum(cl.q * cl.num for cl in _classifiers)
        agg_num = sum(cl.num for cl in _classifiers)

        knowledge_array[_action] = agg_q / float(agg_num)

    by_quality = sorted(knowledge_array.items(), key=lambda el: el[1])
    action = by_quality[0][0]

    return action
Ejemplo n.º 4
0
def choose_latest_action(cll: ClassifiersList) -> Optional[int]:
    """
    Chooses latest executed action ("action delay bias")

    Parameters
    ----------
    cll: ClassifiersList
        classifier list

    Returns
    -------
    int
        chosen action number
    """
    last_executed_cls: Classifier
    number_of_cls_per_action = \
        {i: 0 for i in range(cll.cfg.number_of_possible_actions)}

    if len(cll) > 0:
        last_executed_cls = min(cll, key=lambda cl: cl.talp)

        cll.sort(key=lambda cl: cl.action)
        for _action, _clss in groupby(cll, lambda cl: cl.action):
            number_of_cls_per_action[_action] = \
                sum([cl.num for cl in _clss])

    # If there are some actions with no classifiers - select them
    for action, nCls in number_of_cls_per_action.items():
        if nCls == 0:
            return action

    # Otherwise return the action of the last executed classifier
    return last_executed_cls.action
Ejemplo n.º 5
0
    def test_should_insert_classifier_2(self, cfg):
        # given
        population = ClassifiersList(cfg=cfg)

        # when
        population.append(Classifier(cfg=cfg))

        # then
        assert 1 == len(population)
Ejemplo n.º 6
0
    def test_find_old_classifier_none(self, cfg):
        # given
        classifier_list = ClassifiersList(cfg=cfg)
        cl = Classifier(cfg=cfg)

        # when
        old_cl = classifier_list.find_old_classifier(cl)

        assert old_cl is None
Ejemplo n.º 7
0
    def test_should_insert_classifier(self, cfg):
        # given
        population = ClassifiersList()
        cl = Classifier(cfg=cfg)

        # when
        population.append(cl)

        # then
        assert len(population) == 1
Ejemplo n.º 8
0
    def test_delete_ga_classifiers(self, cfg):
        # given
        cl_1 = Classifier(action=1, cfg=cfg)
        cl_2 = Classifier(action=2, numerosity=20, cfg=cfg)
        cl_3 = Classifier(action=3, cfg=cfg)
        cl_4 = Classifier(action=4, cfg=cfg)
        action_set = ClassifiersList(*[cl_1, cl_2], cfg=cfg)
        match_set = ClassifiersList(*[cl_2], cfg=cfg)
        population = ClassifiersList(*[cl_1, cl_2, cl_3, cl_4], cfg=cfg)

        # when
        action_set.delete_ga_classifiers(population,
                                         match_set,
                                         2,
                                         randomfunc=RandomMock(
                                             ([0.5, 0.1] + [0.5] * 19) * 3))

        expected_action_set = ClassifiersList(
            *[cl_1, Classifier(action=2, numerosity=17, cfg=cfg)], cfg=cfg)
        expected_match_set = ClassifiersList(
            *[Classifier(action=2, numerosity=17, cfg=cfg)], cfg=cfg)
        expected_population = ClassifiersList(
            *[cl_1,
              Classifier(action=2, numerosity=17, cfg=cfg), cl_3, cl_4],
            cfg=cfg)

        # then
        assert expected_action_set == action_set
        assert expected_match_set == match_set
        assert expected_population == population
Ejemplo n.º 9
0
    def test_delete_a_classifier_decrease_numerosity(self, cfg):
        # given
        cl_1 = Classifier(action=1, cfg=cfg)
        cl_2 = Classifier(action=2, numerosity=3, cfg=cfg)
        cl_3 = Classifier(action=3, cfg=cfg)
        cl_4 = Classifier(action=4, cfg=cfg)
        action_set = ClassifiersList(*[cl_1, cl_2], cfg=cfg)
        match_set = ClassifiersList(*[cl_2], cfg=cfg)
        population = ClassifiersList(*[cl_1, cl_2, cl_3, cl_4], cfg=cfg)

        # when
        action_set.delete_a_classifier(match_set,
                                       population,
                                       randomfunc=RandomMock(
                                           [0.5, 0.1, 0.5, 0.5]))

        expected_action_set = ClassifiersList(
            *[cl_1, Classifier(action=2, numerosity=2, cfg=cfg)], cfg=cfg)
        expected_match_set = ClassifiersList(
            *[Classifier(action=2, numerosity=2, cfg=cfg)], cfg=cfg)
        expected_population = ClassifiersList(
            *[cl_1,
              Classifier(action=2, numerosity=2, cfg=cfg), cl_3, cl_4],
            cfg=cfg)

        # then
        assert expected_action_set == action_set
        assert expected_match_set == match_set
        assert expected_population == population
Ejemplo n.º 10
0
    def test_should_apply_reinforcement_learning(self, cfg):
        # given
        cl = Classifier(reward=34.29, immediate_reward=11.29, cfg=cfg)
        population = ClassifiersList(*[cl])

        # when
        ClassifiersList.apply_reinforcement_learning(population, 0, 28.79,
                                                     cfg.beta, cfg.gamma)

        # then
        assert abs(33.94 - cl.r) < 0.1
        assert abs(10.74 - cl.ir) < 0.1
Ejemplo n.º 11
0
    def test_should_return_best_fitness_action(self, cfg):
        # given
        population = ClassifiersList(cfg=cfg)

        # when & then
        # C1 - does not anticipate change
        c1 = Classifier(action=1, cfg=cfg)
        population.append(c1)

        # Some random action should be selected here
        best_action = exploit(population)
        assert best_action is not None

        # when & then
        # C2 - does anticipate some change
        c2 = Classifier(action=2, effect='1###0###', reward=0.25, cfg=cfg)
        population.append(c2)

        # Here C2 action should be selected
        best_action = exploit(population)
        assert 2 == best_action

        # when & then
        # C3 - does anticipate change and is quite good
        c3 = Classifier(action=3,
                        effect='1#######',
                        quality=0.8,
                        reward=5,
                        cfg=cfg)
        population.append(c3)

        # Here C3 has the biggest fitness score
        best_action = exploit(population)
        assert 3 == best_action
Ejemplo n.º 12
0
    def test_should_expand(self, cfg):
        # given
        cl_1 = Classifier(action=0, cfg=cfg)
        cl_2 = Classifier(action=1, numerosity=2, cfg=cfg)
        cl_3 = Classifier(action=2, numerosity=3, cfg=cfg)
        population = ClassifiersList(*[cl_1, cl_2, cl_3])

        # when
        expanded = population.expand()

        # then
        assert len(expanded) == 6
        assert cl_1 in expanded
        assert cl_2 in expanded
        assert cl_3 in expanded
Ejemplo n.º 13
0
    def test_find_subsumer_selects_most_general_subsumer(self, cfg):
        # given
        subsumer1 = Classifier(condition='1##0####',
                               action=3,
                               effect='##1#####',
                               quality=0.93,
                               reward=1.35,
                               experience=23,
                               cfg=cfg)

        subsumer2 = Classifier(condition='#1#0####',
                               action=3,
                               effect='##1#####',
                               quality=0.93,
                               reward=1.35,
                               experience=23,
                               cfg=cfg)

        most_general = Classifier(condition='###0####',
                                  action=3,
                                  effect='##1#####',
                                  quality=0.93,
                                  reward=1.35,
                                  experience=23,
                                  cfg=cfg)

        nonsubsumer = Classifier(cfg=cfg)

        classifier = Classifier(condition='11#0####',
                                action=3,
                                effect='##1#####',
                                quality=0.5,
                                reward=0.35,
                                experience=1,
                                cfg=cfg)

        classifiers_list = ClassifiersList(*[
            nonsubsumer, subsumer1, nonsubsumer, most_general, subsumer2,
            nonsubsumer
        ],
                                           cfg=cfg)

        # when
        actual_subsumer = classifiers_list.find_subsumer(
            classifier, choice_func=lambda l: l[0])

        # then
        assert actual_subsumer == most_general
Ejemplo n.º 14
0
    def test_find_old_classifier_only_subsumer(self, cfg):
        # given
        subsumer1 = Classifier(condition='1##0####',
                               action=3,
                               effect='##1#####',
                               quality=0.93,
                               reward=1.35,
                               experience=23,
                               cfg=cfg)

        subsumer2 = Classifier(condition='#1#0####',
                               action=3,
                               effect='##1#####',
                               quality=0.93,
                               reward=1.35,
                               experience=23,
                               cfg=cfg)

        most_general = Classifier(condition='###0####',
                                  action=3,
                                  effect='##1#####',
                                  quality=0.93,
                                  reward=1.35,
                                  experience=23,
                                  cfg=cfg)

        nonsubsumer = Classifier(cfg=cfg)

        classifier = Classifier(condition='11#0####',
                                action=3,
                                effect='##1#####',
                                quality=0.5,
                                reward=0.35,
                                experience=1,
                                cfg=cfg)

        classifiers_list = ClassifiersList(*[
            nonsubsumer, subsumer1, nonsubsumer, most_general, subsumer2,
            nonsubsumer
        ],
                                           cfg=cfg)

        # when
        actual_old_classifier = classifiers_list.find_old_classifier(
            classifier)

        # then
        assert most_general == actual_old_classifier
Ejemplo n.º 15
0
 def __init__(self,
              cfg: Configuration,
              estimated_average_reward: float = 0,
              population: ClassifiersList = None) -> None:
     self.cfg = cfg
     self.rho = estimated_average_reward
     self.population = population or ClassifiersList()
Ejemplo n.º 16
0
    def test_should_form_action_set(self, cfg):
        # given
        cl_1 = Classifier(action=0, cfg=cfg)
        cl_2 = Classifier(action=0, cfg=cfg)
        cl_3 = Classifier(action=1, cfg=cfg)

        population = ClassifiersList(*[cl_1, cl_2, cl_3])
        action = 0

        # when
        action_set = ClassifiersList.form_action_set(population, action)

        # then
        assert len(action_set) == 2
        assert cl_1 in action_set
        assert cl_2 in action_set
Ejemplo n.º 17
0
    def test_should_form_match_set(self, cfg):
        # given
        cl_1 = Classifier(cfg=cfg)
        cl_2 = Classifier(condition='1###0###', cfg=cfg)
        cl_3 = Classifier(condition='0###1###', cfg=cfg)

        population = ClassifiersList(*[cl_1, cl_2, cl_3])
        p0 = Perception('11110000')

        # when
        match_set = ClassifiersList.form_match_set(population, p0)

        # then
        assert len(match_set) == 2
        assert cl_1 in match_set
        assert cl_2 in match_set
Ejemplo n.º 18
0
    def test_search_one_backward_step_3(self, cfg):
        # given
        gs = GoalSequenceSearcher()
        start = "01111111"
        goal = "10111111"
        gs.forward_perceptions.append(Perception(start))
        gs.backward_perceptions.append(Perception(goal))
        reliable_classifiers = ClassifiersList(
            Classifier(condition="#1######",
                       action=1,
                       effect="#0######",
                       cfg=cfg),
            Classifier(condition="0#######",
                       action=1,
                       effect="1#######",
                       cfg=cfg))
        forward_size = 1
        forward_point = 0

        # when
        act_seq, size = gs._search_one_backward_step(reliable_classifiers,
                                                     forward_size,
                                                     forward_point)

        # then
        assert act_seq is None
        assert len(gs.backward_classifiers) == 2
Ejemplo n.º 19
0
    def test_find_old_classifier_only_similar(self, cfg):
        # given
        classifier_1 = Classifier(action=1, experience=32, cfg=cfg)
        classifier_2 = Classifier(action=1, cfg=cfg)
        classifiers = ClassifiersList(*[
            classifier_1,
            Classifier(action=2, cfg=cfg),
            Classifier(action=3, cfg=cfg), classifier_2
        ],
                                      cfg=cfg)

        # when
        actual_old_classifier = classifiers.find_old_classifier(
            Classifier(action=1, cfg=cfg))

        # then
        assert classifier_1 == actual_old_classifier
Ejemplo n.º 20
0
    def test_should_form_match_set_backwards(self, cfg):
        # given
        population = ClassifiersList()
        situation = Perception('11110000')

        # C1 - general condition
        c1 = Classifier(cfg=cfg)

        # C2 - matching
        c2 = Classifier(condition='0##0####', effect='1##1####', cfg=cfg)

        # C3 - non-matching
        c3 = Classifier(condition='0###1###', effect='1######0', cfg=cfg)

        # C4 - non-matching
        c4 = Classifier(condition='0###0###', effect='1###1###', cfg=cfg)

        population.append(c1)
        population.append(c2)
        population.append(c3)
        population.append(c4)

        # when
        match_set = ClassifiersList.form_match_set_backwards(
            population, situation)
        # then
        assert 2 == len(match_set)
        assert c1 in match_set
        assert c2 in match_set
Ejemplo n.º 21
0
    def test_select_classifier_to_delete(self, cfg):
        # given
        selected_first = Classifier(quality=0.5, cfg=cfg)
        much_worse = Classifier(quality=0.2, cfg=cfg)
        yet_another_to_consider = Classifier(quality=0.2, cfg=cfg)
        classifiers = ClassifiersList(*[
            Classifier(cfg=cfg), selected_first,
            Classifier(cfg=cfg), much_worse, yet_another_to_consider,
            Classifier(cfg=cfg)
        ],
                                      cfg=cfg)

        # when
        actual_selected = classifiers.select_classifier_to_delete(
            randomfunc=RandomMock([0.5, 0.1, 0.5, 0.1, 0.1, 0.5]))

        # then
        assert much_worse == actual_selected
Ejemplo n.º 22
0
    def test_should_exploit_with_single_classifier(self, cfg):
        # given
        cl = Classifier(action=2, effect='1###0###', reward=0.25, cfg=cfg)
        population = ClassifiersList(*[cl])

        # when
        action = exploit(population, cfg.number_of_possible_actions)

        # then
        assert action == 2
Ejemplo n.º 23
0
    def test_should_exploit_when_no_effect_specified(self, cfg):
        # given a classifier not anticipating change
        cl = Classifier(action=1, cfg=cfg)
        population = ClassifiersList(*[cl])

        # when
        action = exploit(population, cfg.number_of_possible_actions)

        # then random action is returned
        assert action is not None
Ejemplo n.º 24
0
    def test_other_not_preferred_to_delete_if_significantly_better(self, cfg):
        # given
        cl = Classifier(quality=0.8, cfg=cfg)
        cl_del = Classifier(quality=0.5, cfg=cfg)

        # when
        selected_cl = ClassifiersList(cfg=cfg)\
            .select_preferred_to_delete(cl, cl_del)

        # then
        assert cl_del == selected_cl
Ejemplo n.º 25
0
    def test_should_return_all_possible_actions(self, cfg):
        # given
        population = ClassifiersList(cfg=cfg)
        actions = set()

        # when
        for _ in range(1000):
            act = choose_action(population, epsilon=1.0)
            actions.add(act)

        # then
        assert 8 == len(actions)
Ejemplo n.º 26
0
    def test_should_form_action_set(self, cfg):
        # given
        population = ClassifiersList(cfg=cfg)
        c0 = Classifier(action=0, cfg=cfg)
        c01 = Classifier(action=0, cfg=cfg)
        c1 = Classifier(action=1, cfg=cfg)

        population.append(c0)
        population.append(c01)
        population.append(c1)

        # when & then
        action_set = ClassifiersList.form_action_set(population, 0, cfg)
        assert 2 == len(action_set)
        assert c0 in action_set
        assert c01 in action_set

        # when & then
        action_set = ClassifiersList.form_action_set(population, 1, cfg)
        assert 1 == len(action_set)
        assert c1 in action_set
Ejemplo n.º 27
0
    def test_quality_and_numerosity_influence_parent_selection(self, cfg):
        # given
        population = ClassifiersList(cfg=cfg)
        c0 = Classifier(condition='######00', quality=1, numerosity=1, cfg=cfg)
        c1 = Classifier(condition='######01', cfg=cfg)
        c2 = Classifier(condition='######10', cfg=cfg)
        population.append(c0)  # q3num = 1
        population.append(c1)  # q3num = 0.0625
        population.append(c2)  # q3num = 0.0625

        # when
        p1, p2 = roulette_wheel_parents_selection(population,
                                                  randomfunc=(RandomMock(
                                                      [0.888, 0.999])))

        # then
        assert c1 == p1
        assert c2 == p2

        # when
        p1, p2 = roulette_wheel_parents_selection(population,
                                                  randomfunc=(RandomMock(
                                                      [0.888, 0.777])))

        # then
        assert c0 == p1
        assert c1 == p2
Ejemplo n.º 28
0
    def test_apply_ga(self, cfg):
        # given
        cl_1 = Classifier(condition='#1#1#1#1', numerosity=12, cfg=cfg)
        cl_2 = Classifier(condition='0#0#0#0#', numerosity=9, cfg=cfg)
        action_set = ClassifiersList(*[cl_1, cl_2], cfg=cfg)
        match_set = ClassifiersList(*[cl_1, cl_2], cfg=cfg)
        population = ClassifiersList(*[cl_1, cl_2], cfg=cfg)

        random_sequence = \
            [
                0.1, 0.6,  # parent selection
                0.1, 0.5, 0.5, 0.5,  # mutation of child1
                0.5, 0.1, 0.5, 0.5,  # mutation of child2
                0.1,  # do crossover
            ] + [0.5] * 12 + [0.2] + [0.5] * 8 + \
            [0.2] + [0.5] * 20 + [0.2] + [0.5] * 20

        # when
        action_set.apply_ga(101,
                            population,
                            match_set,
                            None,
                            randomfunc=RandomMock(random_sequence),
                            samplefunc=SampleMock([0, 4]))

        # then
        modified_parent1 = Classifier(condition='#1#1#1#1',
                                      numerosity=10,
                                      tga=101,
                                      cfg=cfg)

        modified_parent2 = Classifier(condition='0#0#0#0#',
                                      numerosity=8,
                                      tga=101,
                                      cfg=cfg)

        child1 = Classifier(condition='0####1#1',
                            quality=0.25,
                            talp=101,
                            tga=101,
                            cfg=cfg)

        child2 = Classifier(condition='###10#0#',
                            quality=0.25,
                            talp=101,
                            tga=101,
                            cfg=cfg)

        expected_population = ClassifiersList(
            *[modified_parent1, modified_parent2, child1, child2], cfg=cfg)

        # it might sometime fails because one function RNDG is not mocked
        assert expected_population == population
        assert expected_population == match_set
        assert expected_population == action_set
Ejemplo n.º 29
0
    def test_get_quality_classifiers_list(self, cfg):
        # given
        population = ClassifiersList()

        # C1 - matching
        c1 = Classifier(quality=0.9, cfg=cfg)

        # C2 - matching
        c2 = Classifier(quality=0.7, cfg=cfg)

        # C3 - non-matching
        c3 = Classifier(quality=0.5, cfg=cfg)

        # C4 - non-matching
        c4 = Classifier(quality=0.1, cfg=cfg)

        population.append(c1)
        population.append(c2)
        population.append(c3)
        population.append(c4)

        # when
        match_set = get_quality_classifiers_list(population, 0.5)

        # then
        assert 2 == len(match_set)
        assert c1 in match_set
        assert c2 in match_set
Ejemplo n.º 30
0
    def test_should_get_similar_classifier(self, cfg):
        # given
        pop = ClassifiersList(cfg=cfg)
        pop.append(Classifier(action=1, cfg=cfg))
        pop.append(Classifier(action=2, cfg=cfg))
        pop.append(Classifier(action=3, cfg=cfg))

        # when & then
        # No similar classifiers exist
        assert pop.get_similar(Classifier(action=4, cfg=cfg)) is None

        # when & then
        # Should find similar classifier
        assert pop.get_similar(Classifier(action=2, cfg=cfg)) is not None