def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.sut = StochasticRulePopulation('S')
        self.new_rule = self.mk_rule('A', 'B', 'C')
        self.another_rule_with_parent_a = self.mk_rule('A', 'E', 'F')
        self.randomizer_mock = create_autospec(Randomizer)
    def test_population_saving_and_loading(self):
        # Given:
        path = r"C:\Users\Michał\PycharmProjects\mgr\sgcs\sgcs\data\experimental"
        name = 'tmp'
        terminal_rule = Rule(Symbol(101), Symbol(-101))
        non_terminal_rule = Rule(Symbol(101), Symbol(101), Symbol(101))

        population = StochasticRulePopulation(self.starting_symbol)
        population.add_rule(terminal_rule, self.sut.randomizer)
        population.add_rule(non_terminal_rule, self.sut.randomizer)

        # When:
        self.sut.save_population(population, lambda _: '', path, name)
        loaded_pop = self.sut.load_population(path, name, starting_symbol=self.starting_symbol)

        # Then:
        assert_that(loaded_pop.get_all_non_terminal_rules(), only_contains(non_terminal_rule))
        assert_that(loaded_pop.get_terminal_rules(), only_contains(terminal_rule))
示例#3
0
    def create_rules(self, rules):
        rule_population = StochasticRulePopulation(Symbol('S'), universal_symbol=Symbol('U'))
        for rule in rules:
            rule_population.add_rule(rule, self.randomizer)

        return rule_population
class TestStochasticRulePopulation(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.sut = StochasticRulePopulation('S')
        self.new_rule = self.mk_rule('A', 'B', 'C')
        self.another_rule_with_parent_a = self.mk_rule('A', 'E', 'F')
        self.randomizer_mock = create_autospec(Randomizer)

    @staticmethod
    def mk_rule(parent, left_child, right_child):
        return Rule(hash(parent), hash(left_child), hash(right_child))

    def test_adding_new_rule_should_result_in_generating_probability_for_it(self):
        # Given:
        self.randomizer_mock.uniform.return_value = 0.3

        # When:
        self.sut.add_rule(self.new_rule, self.randomizer_mock)

        # Then:
        self.randomizer_mock.uniform.assert_called_once_with(0.01, 1)
        assert_that(self.sut.has_rule(self.new_rule))
        assert_that(self.sut.get_normalized_rule_probability(self.new_rule), is_(equal_to(1)))

    def test_not_existing_rule_should_have_0_probability(self):
        assert_that(self.sut.get_normalized_rule_probability(self.new_rule), is_(equal_to(0)))

    def test_normalization_should_be_performed_after_rule_adding(self):
        # Given:
        self.randomizer_mock.uniform.side_effect = [0.1, 0.3]

        # When:
        self.sut.add_rule(self.new_rule, self.randomizer_mock)
        self.sut.add_rule(self.another_rule_with_parent_a, self.randomizer_mock)

        # Then:
        self.randomizer_mock.uniform.assert_has_calls([call(0.01, 1), call(0.01, 1)])
        assert_that(self.sut.has_rule(self.new_rule))
        assert_that(self.sut.has_rule(self.another_rule_with_parent_a))
        assert_that(self.sut.get_normalized_rule_probability(self.new_rule), is_(close_to(0.25, delta=0.01)))
        assert_that(self.sut.get_normalized_rule_probability(self.another_rule_with_parent_a),
                    is_(close_to(0.75, delta=0.01)))

    def test_normalization_should_be_performed_after_rule_removal(self):
        # Given:
        self.randomizer_mock.uniform.side_effect = [0.1, 0.3]
        self.sut.add_rule(self.new_rule, self.randomizer_mock)
        self.sut.add_rule(self.another_rule_with_parent_a, self.randomizer_mock)

        # When:
        self.sut.remove_rule(self.new_rule)

        # Then:
        assert_that(self.sut.has_rule(self.new_rule), is_(False))
        assert_that(self.sut.has_rule(self.another_rule_with_parent_a))
        assert_that(self.sut.get_normalized_rule_probability(self.new_rule), is_(equal_to(0)))
        assert_that(self.sut.get_normalized_rule_probability(self.another_rule_with_parent_a),
                    is_(close_to(1, delta=0.01)))

    @staticmethod
    def create_fitness_getter_mock(rule_usages):
        return lambda rule: rule_usages[rule]

    def test_probability_estimation_should_work(self):
        # Given:
        self.randomizer_mock.uniform.side_effect = [0.1, 0.3]
        self.sut.add_rule(self.new_rule, self.randomizer_mock)
        self.sut.add_rule(self.another_rule_with_parent_a, self.randomizer_mock)

        rule_usages = dict()
        rule_usages[self.new_rule] = 1
        rule_usages[self.another_rule_with_parent_a] = 2
        fitness_getter = self.create_fitness_getter_mock(rule_usages)

        # When:
        self.sut.perform_probability_estimation(fitness_getter)

        # Then:
        assert_that(self.sut.rule_probabilities[self.new_rule],
                    is_(close_to(0.33, delta=0.01)))
        assert_that(self.sut.get_normalized_rule_probability(self.new_rule),
                    is_(close_to(0.33, delta=0.01)))
        assert_that(self.sut.get_normalized_rule_probability(self.another_rule_with_parent_a),
                    is_(close_to(0.67, delta=0.01)))
        assert_that(self.sut.rule_probabilities[self.another_rule_with_parent_a],
                    is_(close_to(0.67, delta=0.01)))
        assert_that(self.sut.left_side_probabilities[self.new_rule.parent],
                    is_(close_to(1, delta=0.01)))