def test_should_specialize(self, _p0, _p1, _init_cond, _init_effect, _res_cond, _res_effect, cfg): # given cls = Classifier(condition=Condition(_init_cond), effect=Effect(_init_effect), cfg=cfg) p0 = Perception(_p0) p1 = Perception(_p1) # when cls.specialize(p0, p1, leave_specialized=False) # then assert cls.condition == Condition(_res_cond) assert cls.effect == Effect(_res_effect)
def test_should_handle_unexpected_case_2(self, cfg): # given cls = Classifier(condition='#######0', action=4, quality=0.4, cfg=cfg) cls.mark[0].update([0, 1]) cls.mark[1].update([0, 1]) cls.mark[2].update([0, 1]) cls.mark[3].update([0, 1]) cls.mark[4].update([1]) cls.mark[5].update([0, 1]) cls.mark[6].update([0, 1]) p0 = Perception('11101010') p1 = Perception('10011101') time = 94 # when new_cl = unexpected_case(cls, p0, p1, time) # then assert new_cl.condition == Condition('#110#010') assert new_cl.effect == Effect('#001#101') assert new_cl.is_marked() is False assert time == new_cl.tga assert time == new_cl.talp assert abs(cls.q - 0.38) < 0.01
def get_differences(self, p0: Perception) -> Condition: """ Determines the strongest differences in between the mark and current perception. :param: perception :return: condition that specifies all the differences. """ diff = Condition.empty(length=self.cfg.classifier_length) nr1, nr2 = 0, 0 # Count difference types for idx, item in enumerate(self): if len(item) > 0 and p0[idx] not in item: nr1 += 1 elif len(item) > 1: nr2 += 1 if nr1 > 0: possible_idx = [pi for pi, p in enumerate(p0) if p not in self[pi] and len(self[pi]) > 0] rand_idx = random.choice(possible_idx) diff[rand_idx] = p0[rand_idx] elif nr2 > 0: for idx, item in enumerate(self): if len(item) > 1: diff[idx] = p0[idx] return diff
def test_should_get_differences_1(self, _p0, cfg): # given generic_condition = Condition.empty(length=cfg.classifier_length) p0 = Perception(_p0) mark = PMark(cfg) # when diff = mark.get_differences(p0) # then assert diff == generic_condition
def test_should_build_initial_population(self, cfg): agent = ACS(cfg) assert len(agent.population) == 4 actions = [cl.action for cl in agent.population] assert actions == [0, 1, 2, 3] for cl in agent.population: assert cl.condition == Condition("####") assert cl.effect == Effect("####")
def test_should_generalize_second_unchanging_attribute(self, cfg): # given cls = Classifier(condition='#####0#0', effect='########', cfg=cfg) assert len(cls.specified_unchanging_attributes) == 2 # when generalized = cls.generalize_unchanging_condition_attribute( lambda x: 7) # then assert generalized is True assert len(cls.specified_unchanging_attributes) == 1 assert Condition('#####0##') == cls.condition
def test_should_construct_correct_classifier(self, cfg): cl = Classifier(condition="000#", effect="000#", quality=0.2, cfg=cfg) p0 = Perception("0000") p1 = Perception("0001") assert cl.does_match(p0) new_cl = Classifier.build_corrected(cl, p0, p1) assert new_cl is not cl assert new_cl.condition is not cl.condition assert new_cl.effect is not cl.effect assert new_cl.condition == Condition("0000") assert new_cl.action == cl.action assert new_cl.effect == Effect("0001") assert new_cl.q == 0.5 assert new_cl.does_match(p0)
def test_should_handle_unexpected_case_1(self, cfg): # given cls = Classifier(action=2, cfg=cfg) p0 = Perception('01100000') p1 = Perception('10100010') time = 14 new_cls = unexpected_case(cls, p0, p1, time) # Quality should be decreased assert 0.475 == cls.q # Should be marked with previous perception for mark_attrib in cls.mark: assert 1 == len(mark_attrib) assert '0' in cls.mark[0] assert '1' in cls.mark[1] assert '1' in cls.mark[2] assert '0' in cls.mark[3] assert '0' in cls.mark[4] assert '0' in cls.mark[5] assert '0' in cls.mark[6] assert '0' in cls.mark[7] # New classifier should not be the same object assert cls is not new_cls # Check attributes of a new classifier assert Condition('01####0#') == new_cls.condition assert 2 == new_cls.action assert Effect('10####1#') == new_cls.effect # There should be no mark for mark_attrib in new_cls.mark: assert 0 == len(mark_attrib) assert 0.5 == new_cls.q assert cls.r == new_cls.r assert time == new_cls.tga assert time == new_cls.talp
def build_corrected(cls, old: Classifier, p0: Perception, p1: Perception) -> Classifier: """ Constructs the classifier for "correctable case". C_new and E_new will be different from the old classifier in the non-matching components of p0 and p1. There - E_new will be equal to p1 - C_new will be equal to p0 respectively. Parameters ---------- old: Classifier Old classifier that will be cloned and changed p0: Perception previous perception p1: Perception perception Returns ------- Classifier new corrected classifier """ assert p0 != p1 new_c = Condition(old.condition) new_e = Effect(old.effect) for idx, (ci, ei, p0i, p1i) in \ enumerate(zip(old.condition, old.effect, p0, p1)): if p0i != p1i: new_c[idx] = p0i new_e[idx] = p1i return Classifier(condition=new_c, action=old.action, effect=new_e, cfg=old.cfg)
def test_should_create_new_classifier_using_covering(self, cfg): # given action = random.randint(0, cfg.number_of_possible_actions) time = random.randint(0, 1000) p0 = Perception('01001101') p1 = Perception('00011111') # when new_cl = cover(p0, action, p1, time, cfg) # then assert new_cl.condition == Condition('#1#0##0#') assert new_cl.action == action assert new_cl.effect == Effect('#0#1##1#') 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
def test_should_handle_unexpected_case_6(self, cfg): # given cls = Classifier(condition='0#1####1', action=2, effect='1#0####0', quality=0.38505, reward=1.20898, immediate_reward=0, experience=11, tga=95, talp=873, tav=71.3967, cfg=cfg) cls.mark[1].update(['1']) cls.mark[3].update(['1']) cls.mark[4].update(['0', '1']) cls.mark[5].update(['1']) cls.mark[6].update(['0', '1']) p0 = Perception('01111101') p1 = Perception('11011110') time = 873 # when new_cls = unexpected_case(cls, p0, p1, time) # then assert new_cls is not None assert Condition('0#1###01') == new_cls.condition assert Effect('1#0###10') == new_cls.effect assert abs(0.5 - new_cls.q) < 0.1 assert abs(1.20898 - new_cls.r) < 0.1 assert abs(0 - new_cls.ir) < 0.1 assert abs(71.3967 - new_cls.tav) < 0.1 assert 1 == new_cls.exp assert 1 == new_cls.num assert time == new_cls.tga assert time == new_cls.talp
def test_should_handle_unexpected_case_5(self, cfg): # given cls = Classifier(condition='00####1#', action=2, effect='########', quality=0.129, reward=341.967, immediate_reward=130.369, experience=201, tga=129, talp=9628, tav=25.08, cfg=cfg) cls.mark[2].add('2') cls.mark[3].add('1') cls.mark[4].add('1') cls.mark[5].add('0') cls.mark[7].add('0') p0 = Perception('00211010') p1 = Perception('00001110') time = 9628 # when new_cls = unexpected_case(cls, p0, p1, time) # then assert new_cls is not None assert Condition('0021#01#') == new_cls.condition assert Effect('##00#1##') == new_cls.effect assert abs(0.5 - new_cls.q) < 0.1 assert abs(341.967 - new_cls.r) < 0.1 assert abs(130.369 - new_cls.ir) < 0.1 assert abs(25.08 - new_cls.tav) < 0.1 assert 1 == new_cls.exp assert 1 == new_cls.num assert time == new_cls.tga assert time == new_cls.talp
def test_should_calculate_specificity(self, _condition, _specificity, cfg): cls = Classifier(Condition(_condition), cfg=cfg) assert cls.specificity == _specificity
def test_distinguish_general_classifier(self, _c, _e, _result, cfg): cl = Classifier(condition=Condition(_c), effect=Effect(_e), cfg=cfg) assert cl.is_general() == _result
def test_should_create_general_classifier(self, cfg): cl = Classifier.general(action=1, cfg=cfg) assert cl.condition == Condition("####") assert cl.action == 1 assert cl.condition == Effect("####")
def is_general(self): cl_length = self.cfg.classifier_length return self.condition == Condition.empty(cl_length) \ and self.effect == Effect.empty(cl_length)