def test_crossover_allows_to_change_last_element(self, cfg): # given cl1 = Classifier(condition='0##10###', cfg=cfg) cl2 = Classifier(condition='#10##011', cfg=cfg) # when two_point_crossover(cl1, cl2, samplefunc=SampleMock([5, 8])) # then assert Condition('0##10011') == cl1.condition assert Condition('#10#####') == cl2.condition
def test_crossover(self, cfg): # given cl1 = Classifier(condition='0##10###', cfg=cfg) cl2 = Classifier(condition='#10##0##', cfg=cfg) # when two_point_crossover(cl1, cl2, samplefunc=SampleMock([1, 4])) # then assert Condition('010#0###') == cl1.condition assert Condition('###1#0##') == cl2.condition
def apply_ga(self, time: int, population: ClassifiersList, match_set: ClassifiersList, situation: Perception, randomfunc=random, samplefunc=sample) -> None: if self.should_apply_ga(time): self.set_ga_timestamp(time) parent1, parent2 = roulette_wheel_parents_selection( self, randomfunc=randomfunc) child1 = Classifier.copy_from(parent1, time) child2 = Classifier.copy_from(parent2, time) mutate(child1, child1.cfg.mu, randomfunc=randomfunc) mutate(child2, child2.cfg.mu, randomfunc=randomfunc) if randomfunc() < self.cfg.chi: if child1.effect == child2.effect: two_point_crossover(child1, child2, samplefunc=samplefunc) # Update quality and reward # TODO: check if needed child2.q = float(sum([child1.q, child2.q]) / 2) child2.r = float(sum([child1.r, child2.r]) / 2) child1.q /= 2 child2.q /= 2 children = [ child for child in [child1, child2] if child.condition.specificity > 0 ] # if two classifiers are identical, leave only one unique_children = set(children) self.delete_ga_classifiers(population, match_set, len(unique_children), randomfunc=randomfunc) # check for subsumers / similar classifiers for child in unique_children: self.add_ga_classifier(child, match_set, population)