def test_reuse_checks(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('neat') domain = darwin.Domain('unicycle') experiment_a = universe.new_experiment(domain, population, name='A') # currently, once a population or a domain _instance_ is used by an experiment, # it cannot be reused in other experiments new_population = darwin.Population('neat') with self.assertRaises(RuntimeError): experiment_b = universe.new_experiment(domain, new_population, name='B') new_domain = darwin.Domain('unicycle') with self.assertRaises(RuntimeError): experiment_c = universe.new_experiment(new_domain, population, name='C') # after the experiment is disposed, we can reuse the population and domain experiment_a = None experiment_d = universe.new_experiment(domain, population, name='D')
def test_experiment_name(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('neat') domain = darwin.Domain('unicycle') experiment = universe.new_experiment(domain, population, name='foo') self.assertEqual(experiment.name, 'foo') self.assertRegex(repr(experiment), "'foo'") experiment.name = ' a new name with lots of spaces! ' self.assertRegex(repr(experiment), "' a new name with lots of spaces! '") experiment.name = None self.assertRegex(repr(experiment), 'Unnamed') # invalid name (empty) with self.assertRaises(RuntimeError): experiment.name = '' experiment.name = 'final' experiment.initialize_population() # can't set the name after the experiment is initialized with self.assertRaises(RuntimeError): experiment.name = 'baz' second_population = darwin.Population('cne.lstm') second_domain = darwin.Domain('tic_tac_toe') # duplicate name with self.assertRaises(RuntimeError): second_experiment = universe.new_experiment( domain=second_domain, population=second_population, name='final') second_experiment = universe.new_experiment( domain=second_domain, population=second_population, name='baz') # ok... second_experiment.name = 'new name' # duplicate name with self.assertRaises(RuntimeError): second_experiment.name = 'final'
def test_available_domains(self): domains = darwin.available_domains() self.assertTrue(domains) for name in domains: domain = darwin.Domain(name) self.assertEqual(name, domain.name) self.assertIsNotNone(domain.config)
def test_basic_evolution(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('neat') population.size = 10 domain = darwin.Domain('unicycle') experiment = universe.new_experiment(domain, population) # basic evolution cycle experiment.initialize_population() for generation in range(5): summary = experiment.evaluate_population() experiment.create_next_generation() # evolution trace trace = experiment.trace self.assertEqual(trace.size, 5) self.assertEqual(trace.size, len(trace)) self.assertEqual(trace[4].champion.fitness, summary.champion.fitness) self.assertEqual(trace[4].champion.fitness, trace[-1].champion.fitness) self.assertEqual(trace[0].champion.fitness, trace[-5].champion.fitness) with self.assertRaises(IndexError): tmp = trace[5] with self.assertRaises(IndexError): tmp = trace[-6] universe.close()
def test_property_attributes(self): d = darwin.Domain('conquest') for prop_name in dir(d.config): prop = d.config.__getattr__(prop_name) self.assertEqual(prop.name, prop_name) self.assertTrue(prop.description) self.assertTrue(prop.default_value)
def test_genotype_lifetime(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('cne.feedforward') domain = darwin.Domain('tic_tac_toe') population.size = 10 experiment = universe.new_experiment(domain, population) experiment.initialize_population() genotype = population[0] json_checkpoint_1 = genotype.to_json() experiment.evaluate_population() # this is fine, although our genotype may be ranked to a different index now json_checkpoint_2 = genotype.to_json() experiment.create_next_generation() # the old genotype is no longer owned by the population json_checkpoint_3 = genotype.to_json() experiment.reset() # the old population is no longer owned by the experiment json_checkpoint_4 = genotype.to_json() self.assertEqual(json_checkpoint_1, json_checkpoint_2) self.assertEqual(json_checkpoint_1, json_checkpoint_3) self.assertEqual(json_checkpoint_1, json_checkpoint_4)
def test_evaluate_population(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('neat') domain = darwin.Domain('tic_tac_toe') population.size = 10 experiment = universe.new_experiment(domain, population) experiment.initialize_population() summary = experiment.evaluate_population() self.assertEqual(population.size, 10) self.assertEqual(population.size, len(population)) # generation summary self.assertEqual(summary.generation, 0) self.assertEqual(summary.best_fitness, summary.champion.fitness) # population fitness values self.assertGreaterEqual(population[0].fitness, population[-1].fitness) self.assertEqual(population[0].fitness, summary.champion.fitness) prev_fitness = summary.champion.fitness for genotype in population: self.assertLessEqual(genotype.fitness, prev_fitness) prev_fitness = genotype.fitness universe.close()
def test_indexing(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('cne.feedforward') domain = darwin.Domain('tic_tac_toe') population.size = 10 experiment = universe.new_experiment(domain, population) # can't index into an uninitialized population with self.assertRaises(RuntimeError): genotype = population[0] experiment.initialize_population() # correct indexing genotype = population[0] genotype = population[9] genotype = population[-1] genotype = population[-10] # out of bounds with self.assertRaises(IndexError): genotype = population[10] with self.assertRaises(IndexError): genotype = population[-11]
def test_json_support(self): d = darwin.Domain('conquest') d.config.max_steps = 100 d.config.points_draw = 0.4 d.config.board = 'hexagon' d.config.tournament_type = 'swiss' d.config.tournament_type.variant.rematches = False json_str = d.config.to_json() # roundtrip d = darwin.Domain('conquest') d.config.from_json(json_str) self.assertEqual(d.config.max_steps.auto, 100) self.assertEqual(d.config.points_draw.auto, 0.4) self.assertEqual(d.config.board.auto, 'hexagon') self.assertEqual(d.config.tournament_type.auto, 'swiss') self.assertEqual(d.config.tournament_type.variant.rematches.auto, False)
def test_config_assignment(self): d1 = darwin.Domain('pong') d2 = darwin.Domain('tic_tac_toe') # this is ok, we can bind to config instances c = d1.config c = d2.config # ... but we can't set the config with self.assertRaises(AttributeError): d1.config = d2.config # ... even self assignments with self.assertRaises(AttributeError): d1.config = d1.config # ... or setting to None with self.assertRaises(AttributeError): d1.config = None
def test_new_experiment(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') with darwin.create_universe(path) as universe: p = darwin.Population('neat') d = darwin.Domain('unicycle') exp = universe.new_experiment(population=p, domain=d) self.assertRegex(repr(exp), p.name) self.assertRegex(repr(exp), d.name) self.assertIs(exp.population, p) self.assertIs(exp.domain, d) self.assertIs(exp.universe, universe)
def test_sealed_state(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('neat') domain = darwin.Domain('unicycle') experiment = universe.new_experiment(domain, population) # changes are ok population.size = 10 population.config.normalize_input = False domain.config.gravity = 10.5 experiment.config.save_genealogy = True experiment.core_config.mutation_std_dev = 0.5 d_config = domain.config d_config.max_torque = 100 # initializing the population will seal all configuration values experiment.initialize_population() # shouldn't be able to change sealed state with self.assertRaises(RuntimeError): population.size = 10 with self.assertRaises(RuntimeError): population.config.normalize_input = True with self.assertRaises(RuntimeError): domain.config.gravity = 0 with self.assertRaises(RuntimeError): experiment.config.save_genealogy = False with self.assertRaises(RuntimeError): experiment.core_config.mutation_std_dev = 0 with self.assertRaises(RuntimeError): d_config.max_torque = 0 # make sure the values were not changed self.assertEqual(population.size, 10) self.assertEqual(population.config.normalize_input.auto, False) self.assertEqual(domain.config.gravity.auto, 10.5) self.assertEqual(experiment.config.save_genealogy.auto, True) self.assertEqual(experiment.core_config.mutation_std_dev.auto, 0.5) self.assertEqual(d_config.max_torque.auto, 100) # resetting the experiment allows configuration changes again experiment.reset() population.size = 1 population.config.normalize_input = 'true' domain.config.gravity = 0.1 experiment.config.save_genealogy = False experiment.core_config.mutation_std_dev = '0.1' d_config.max_torque = 1.5 universe.close()
def test_experiment_reset(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('neat') domain = darwin.Domain('unicycle') population.size = 5 experiment_a = universe.new_experiment(domain, population) for i in range(3): experiment_a.name = f'A{i}' # name must be unique experiment_a.initialize_population() experiment_a.evaluate_population() experiment_a.create_next_generation() experiment_a.reset()
def test_reinitialize_population(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('neat') population.size = 10 domain = darwin.Domain('unicycle') experiment = universe.new_experiment(domain, population) # multiple runs of the same experiment variation for evolution_run in range(3): # reinitialize the population (which would result in a new evolution trace) experiment.initialize_population() for generation in range(2): experiment.evaluate_population() experiment.create_next_generation() universe.close()
def test_variant_property_sets(self): d = darwin.Domain('tic_tac_toe') config = d.config # not all the properties have sub-variants with self.assertRaises(RuntimeError): dummy = config.ann_type.variant d = None # stress the ownership/lifetimes management prop = config.tournament_type config.tournament_type = 'swiss' swiss_tournament = prop.variant config.tournament_type = 'simple' simple_tournament = prop.variant prop = None # stress the ownership/lifetimes management config.tournament_type.variant.eval_games = 123 config = None # stress the ownership/lifetimes management self.assertEqual(int(swiss_tournament.rounds), 20) self.assertEqual(int(simple_tournament.eval_games), 123)
def test_auto_cast(self): d = darwin.Domain('conquest') d.config.max_steps = 100 d.config.points_draw = 0.4 d.config.board = 'hexagon' d.config.tournament_type = 'swiss' d.config.tournament_type.variant.rematches = False self.assertIs(type(d.config.max_steps.auto), int) self.assertIs(type(d.config.points_draw.auto), float) self.assertIs(type(d.config.board.auto), str) self.assertIs(type(d.config.tournament_type.auto), str) self.assertIs(type(d.config.tournament_type.variant.rematches.auto), bool) self.assertEqual(d.config.max_steps.auto, 100) self.assertEqual(d.config.points_draw.auto, 0.4) self.assertEqual(d.config.board.auto, 'hexagon') self.assertEqual(d.config.tournament_type.auto, 'swiss') self.assertEqual(d.config.tournament_type.variant.rematches.auto, False)
def test_genotype_and_brain(self): path = darwin_test_utils.reserve_universe('python_bindings.darwin') universe = darwin.create_universe(path) population = darwin.Population('cne.feedforward') population.size = 10 domain = darwin.Domain('tic_tac_toe') domain.config.ann_type = 'value' experiment = universe.new_experiment(domain, population) experiment.initialize_population() genotype = population[0].clone() self.assertEqual(genotype.to_json(), population[0].to_json()) brain = genotype.grow() for index in range(9): brain.set_input(index, 0) brain.think() board_value = brain.output(index=0)
def test_cast_attributes(self): d = darwin.Domain('conquest') d.config.int_unit_scale = 10 d.config.points_draw = 0.4 d.config.board = 'hexagon' self.assertEqual(int(d.config.int_unit_scale), 10) self.assertEqual(float(d.config.points_draw), 0.4) self.assertEqual(repr(d.config.board), 'hexagon') self.assertEqual(str(d.config.board), 'hexagon') d.config.tournament_type = 'swiss' d.config.tournament_type.variant.rematches = 'true' self.assertEqual(bool(d.config.tournament_type.variant.rematches), True) d.config.tournament_type.variant.rematches = 'false' self.assertEqual(bool(d.config.tournament_type.variant.rematches), False) # invalid cast with self.assertRaises(RuntimeError): value = int(d.config.board)
def test_config_lifetime(self): d = darwin.Domain('conquest') config = d.config d = None self.assertTrue(repr(config))
def test_property_lifetime(self): d = darwin.Domain('conquest') property = d.config.board d = None self.assertEqual(str(property), 'hexagon')