def simple_individuals(atoms): return [ Individual(Genome([])), Individual(Genome([atoms["5"]])), Individual(Genome([atoms["5"], atoms["close"]])), Individual(Genome([atoms["5"]])), ]
def simple_individuals(atoms, push_config): sig = ProgramSignature(arity=0, output_stacks=["int"], push_config=push_config) return [ Individual(Genome([]), sig), Individual(Genome([atoms["5"]]), sig), Individual(Genome([atoms["5"], atoms["close"]]), sig), Individual(Genome([atoms["5"]]), sig), ]
def pop(atoms): i1 = Individual(Genome()) i1.error_vector = np.array([0, 20, 0]) # 20 i2 = Individual(Genome()) i2.error_vector = np.array([3, 3, 3]) # 9 i3 = Individual(Genome()) i3.error_vector = np.array([1, 2, 3]) # 6 i4 = Individual(Genome()) i4.error_vector = np.array([4, 3, 5]) # 12 return Population([i1, i2, i3, i4])
def produce(self, parents: Sequence[Genome], spawner: GeneSpawner = None) -> Genome: """Produce a child Genome from parent Genomes and optional GenomeSpawner. Parameters ---------- parents A list of parent Genomes given to the operator. spawner A GeneSpawner that can be used to produce new genes (aka Atoms). """ super().produce(parents, spawner) self.checknum_parents(parents) new_genome = Genome() for atom in parents[0]: if isinstance( atom, Literal ) and self.push_type == atom.push_type and random() < self.rate: new_atom = self._mutate_literal(atom) else: new_atom = atom new_genome = new_genome.append(new_atom) return new_genome
def test_add_evaluated(self, partially_evaluated_pop, simple_program_signature): i = Individual(Genome([]), simple_program_signature) i.error_vector = np.array([0, 1, 0]) partially_evaluated_pop.add(i) assert len(partially_evaluated_pop) == 5 assert len(partially_evaluated_pop.evaluated) == 3
def test_missing_close_genome_to_codeblock(self, atoms): gn = Genome([ atoms["true"], atoms["if"], atoms["1.2"], atoms["close"], atoms["5"] ]) cb = gn.to_code_block() assert cb[0] == Literal(True) assert isinstance(cb[1], Instruction) assert isinstance(cb[2], CodeBlock)
def test_genome_write(self, atoms): gn = Genome([ atoms["true"], atoms["if"], atoms["1.2"], atoms["close"], atoms["5"] ]) s = gn.jsonify() assert json.loads(s) == json.loads( '[{"a":"lit","t":"bool","v":true},{"a":"instr","n":"exec_if"},{"a":"lit","t":"float","v":1.2},{"a":"close"},{"a":"lit","t":"int","v":5}]' )
def test_simplify_no_change(self, simple_genome, atoms): evaluator = DatasetEvaluator([[]], [5]) err = evaluator.evaluate(simple_genome.to_code_block()) gs = GenomeSimplifier(evaluator) new_genome, new_err = gs.simplify(simple_genome, err, 100) assert new_genome == Genome([atoms["5"]]) assert new_err == [0.0]
def test_missing_close_genome_to_codeblock(self, atoms): gn = Genome([ atoms["true"], atoms["if"], atoms["1.2"], atoms["close"], atoms["5"] ]) cb = genome_to_code(gn) assert cb[0] == Literal(value=True, push_type=PushBool) assert isinstance(cb[1], InstructionMeta) assert isinstance(cb[2], CodeBlock)
def test_simplify(self, simple_individual, atoms): evaluator = DatasetEvaluator([[]], [5]) genome = simple_individual.genome err = evaluator.evaluate(simple_individual.program) gs = GenomeSimplifier(evaluator, simple_individual.signature) new_genome, new_err = gs.simplify(genome, err, 1000) assert new_genome == Genome([atoms["5"]]) assert new_err == [0.0]
def population(atoms, push_config): gn = Genome() sig = ProgramSignature(arity=0, output_stacks=[], push_config=push_config) i1 = Individual(gn, sig) i1.error_vector = np.array([0, 20, 0]) # 20 i2 = Individual(gn, sig) i2.error_vector = np.array([3, 3, 3]) # 9 i3 = Individual(gn, sig) i3.error_vector = np.array([1, 2, 3]) # 6 i4 = Individual(gn, sig) i4.error_vector = np.array([4, 3, 5]) # 12 return Population([i1, i2, i3, i4])
def produce(self, parents: Sequence[Genome], spawner: GeneSpawner) -> Genome: """Produce a child Genome from parent Genomes and optional GenomeSpawner. Parameters ---------- parents A list of parent Genomes given to the operator. spawner A GeneSpawner that can be used to produce new genes (aka Atoms). """ self.checknum_parents(parents) new_genome = Genome() for gene in parents[0]: if random() < self.rate: new_genome.append(spawner.spawn_atom()) new_genome.append(gene) return new_genome
def produce(self, parents: Sequence[Genome], spawner: GeneSpawner = None) -> Genome: """Produce a child Genome from parent Genomes and optional GenomeSpawner. Parameters ---------- parents A list of parent Genomes given to the operator. spawner A GeneSpawner that can be used to produce new genes (aka Atoms). """ super().produce(parents, spawner) self.checknum_parents(parents) gn1 = parents[0] gn2 = parents[1] new_genome = Genome() # Random pick which parent to start from use_parent_1 = choice([True, False]) loop_times = len(gn1) if not use_parent_1: loop_times = len(gn2) i = 0 while i < loop_times: if random() < self.rate: # Switch which parent we are pulling genes from i += round(self.alignment_deviation * _gaussian_noise_factor()) i = int(max(0, i)) use_parent_1 = not use_parent_1 else: # Pull gene from parent if use_parent_1: new_genome = new_genome.append(gn1[i]) else: new_genome = new_genome.append(gn2[i]) i = int(i + 1) # Change loop stop condition loop_times = len(gn1) if not use_parent_1: loop_times = len(gn2) return new_genome
def test_extra_close_genome_to_codeblock(self, atoms): gn = Genome( [atoms["close"], atoms["5"], atoms["close"], atoms["close"]]) cb = genome_to_code(gn) assert len(cb) == 1 assert cb[0] == Literal(value=5, push_type=PushInt)
def test_genome_bad_init(self, atoms): with pytest.raises(InvariantException): Genome([atoms["5"], CodeBlock([atoms["5"], atoms["add"]])])
def simple_genome(atoms): return Genome([atoms["5"], atoms["5"], atoms["add"]])
def load_genome(name, interpreter) -> Genome: with open("tests/resources/genomes/" + name + ".json") as f: atoms = _deserialize_atoms(json.load(f), interpreter.instruction_set) return Genome(atoms)
def test_add_unevaluated(self, partially_evaluated_pop): partially_evaluated_pop.add(Individual(Genome([]))) assert len(partially_evaluated_pop) == 5 assert len(partially_evaluated_pop.unevaluated) == 3
def test_extra_close_genome_to_codeblock(self, atoms): gn = Genome( [atoms["close"], atoms["5"], atoms["close"], atoms["close"]]) cb = gn.to_code_block() assert len(cb) == 1 assert cb[0] == Literal(5)
def test_add_evaluated(self, partially_evaluated_pop): i = Individual(Genome([])) i.error_vector = np.array([0, 1, 0]) partially_evaluated_pop.add(i) assert len(partially_evaluated_pop) == 5 assert len(partially_evaluated_pop.evaluated) == 3
def test_genome_bad_init(self, atoms): with pytest.raises(ValueError): Genome( CodeBlock.from_list([atoms["5"], [atoms["5"], atoms["add"]]]))
def test_best(self, partially_evaluated_pop, simple_program_signature): i = Individual(Genome([]), simple_program_signature) i.error_vector = np.array([0, 1, 0]) partially_evaluated_pop.add(i) assert partially_evaluated_pop.best().total_error == 0.0
def test_best(self, partially_evaluated_pop): i = Individual(Genome([])) i.error_vector = np.array([0, 1, 0]) partially_evaluated_pop.add(i) assert partially_evaluated_pop.best().total_error == 0.0
def test_add_unevaluated(self, partially_evaluated_pop, simple_program_signature): partially_evaluated_pop.add( Individual(Genome([]), simple_program_signature)) assert len(partially_evaluated_pop) == 5 assert len(partially_evaluated_pop.unevaluated) == 3
def test_empty_genome_to_codeblock(self): gn = Genome() cb = genome_to_code(gn) assert len(cb) == 0
def test_empty_genome_to_codeblock(self, atoms): gn = Genome() cb = gn.to_code_block() assert len(cb) == 0
def simple_genome(atoms): return Genome( [atoms["true"], atoms["if"], atoms["1.2"], atoms["close"], atoms["5"]])