def explore(self, current_patch, current_fitness): assert self.debug_patch is not None self.report['best_fitness'] = None self.report['best_patch'] = None for edit in cleaned_patch.edit_list: # move patch = Patch(self.program) patch.add(edit) # compare run = self.evaluate_patch(patch) h = [self.stats['steps'] + 1, run.status, ' ', run.fitness, patch] if run.status == 'SUCCESS': accept = True if self.dominates(run.fitness, self.report['best_fitness']): self.report['best_fitness'] = run.fitness self.report['best_patch'] = patch h[2] = '*' # log self.program.logger.debug(self.program.diff(patch)) self.program.logger.debug(run) self.program.logger.info('{}\t{}\t{}{}\t{}'.format(*h)) # next self.stats['steps'] += 1 self.report['stop'] = 'validation end' return current_patch, current_fitness
def test_diff(self, setup_tree): program = setup_tree patch = Patch(program) assert not program.diff(patch).strip() patch.add( StmtInsertion(('triangle.py', 1), ('triangle.py', 10), direction='after')) assert program.diff(patch).strip()
def test_diff(self, setup_tree): program = setup_tree patch = Patch() print(patch.raw()) assert not program.diff(patch).strip() patch.add( StmtInsertion(('triangle.py', 'stmt', 1), ('triangle.py', 'stmt', 10))) assert program.diff(patch).strip()
def explore(self, current_patch, current_fitness): if self.debug_patch is None: raise ValueError() self.cleaned_patch = self.do_clean_patch(self.debug_patch) self.program.logger.debug('CLEAN_PATCH: {}'.format(str(self.cleaned_patch))) self.program.logger.debug('CLEAN_SIZE: %d (was %d)', len(self.cleaned_patch), len(self.debug_patch)) self.report['best_fitness'] = None self.report['best_patch'] = None self.report['cleaned_patch'] = self.cleaned_patch # full patch first if self.debug_patch.edit_list: run = self.do_eval_patch(self.debug_patch) else: self.report['stop'] = 'validation end (empty patch)' return current_patch, current_fitness # ranking self.program.logger.info('-- ranking --') ranking = list() for edit in self.debug_patch.edit_list: patch = Patch([edit]) run = self.do_eval_patch(patch) if run.fitness: ranking.append((edit, run.fitness)) ranking.sort(key=lambda c: c[1]) # rebuild if ranking[0][1] > self.report['initial_fitness']: self.program.logger.info('-- rebuild --') rebuild = Patch(ranking[0]) rebuild_fitness = ranking[0][1] for (edit,fit) in ranking[1:]: patch = copy.deepcopy(rebuild) patch.add(edit) run = self.do_eval_patch(patch) if run.status == 'SUCCESS' and self.dominates(run.fitness, rebuild_fitness): rebuild_fitness = run.fitness rebuild.add(edit) # round robin ablation self.program.logger.info('-- ablation --') n = len(self.debug_patch.edit_list)+1 last_i = 0 while n > len(self.report['best_patch'].edit_list): n = len(self.report['best_patch'].edit_list) for i in range(n): patch = Patch([e for (j, e) in enumerate(self.report['best_patch'].edit_list) if (j+last_i)%n != i]) run = self.do_eval_patch(patch) if run.fitness == self.report['best_fitness']: self.report['best_patch'] = patch # accept because smaller last_i = i # round robin break self.report['stop'] = 'validation end' return current_patch, current_fitness
def test_apply(self, setup_line): program = setup_line patch = Patch(program) patch.add( LineInsertion(('triangle.py', 1), ('triangle.py', 10), direction='after')) program.apply(patch) file_contents = open(os.path.join(program.tmp_path, 'triangle.py'), 'r').read() assert file_contents == program.dump( program.get_modified_contents(patch), 'triangle.py')
def test_apply(self, setup_tree): program = setup_tree patch = Patch() patch.add( StmtInsertion(('triangle.py', 'stmt', 1), ('triangle.py', 'stmt', 10))) program.apply(patch) file_contents = open(os.path.join(program.work_path, 'triangle.py'), 'r').read() assert file_contents == program.dump( program.get_modified_contents(patch), 'triangle.py')
def explore(self, current_patch, current_fitness): if self.debug_patch is None: raise ValueError() self.cleaned_patch = self.do_clean_patch(self.debug_patch) self.program.logger.debug('CLEAN_PATCH: {}'.format(str(self.cleaned_patch))) self.program.logger.debug('CLEAN_SIZE: %d (was %d)', len(self.cleaned_patch), len(self.debug_patch)) self.report['best_fitness'] = None self.report['best_patch'] = None self.report['cleaned_patch'] = self.cleaned_patch # full patch first if self.debug_patch.edit_list: self.do_eval_patch(self.debug_patch) else: self.report['stop'] = 'validation end (empty patch)' return current_patch, current_fitness # ranking ranking = list() for edit in self.debug_patch.edit_list: patch = Patch([edit]) run = self.do_eval_patch(patch) ranking.append((edit, run.fitness)) ranking.sort(key=lambda c: c[1]) if ranking[0][1] > self.report['initial_fitness']: self.report['stop'] = 'validation end (all bad)' return current_patch, current_fitness # rebuild rebuild = Patch() rebuild_fitness = None for (k,(edit,fit)) in enumerate(ranking): # move patch = copy.deepcopy(rebuild) patch.add(edit) # compare if k == 0: rebuild.add(edit) rebuild_fitness = fit continue run = self.do_eval_patch(patch) if run.status == 'SUCCESS' and self.dominates(run.fitness, rebuild_fitness): rebuild_fitness = run.fitness rebuild.add(edit) self.report['stop'] = 'validation end' return current_patch, current_fitness
def test_init(self, setup_program): class MyLocalSearch(LocalSearch): def get_neighbour(self, patch): temp_patch = patch.clone() if len(temp_patch) > 0 and random.random() < 0.1: temp_patch.remove(random.randrange(0, len(temp_patch))) else: operators = [ StmtReplacement, StmtInsertion, StmtDeletion, StmtMoving ] temp_patch.add( random.choice(operators).create(program, method="weighted")) return temp_patch def is_better_than_the_best(self, fitness, best_fitness): return fitness < best_fitness def stopping_criterion(self, iter, fitness): return fitness == 0 max_iter = 10 program = setup_program run = program.evaluate_patch(Patch(program)) ls = MyLocalSearch(program) result = ls.run(warmup_reps=1, epoch=1, max_iter=max_iter, timeout=10) assert len(result) == 1 assert result[0]['FitnessEval'] <= max_iter if result[0]['FitnessEval'] < max_iter: assert result[0]['BestFitness'] < run.fitness
def crossover(self, sol1, sol2): c = Patch(self.program) for edit in sol1.edit_list: if random.random() > self.config['uniform_rate']: c.add(edit) for edit in sol2.edit_list: if random.random() > self.config['uniform_rate']: c.add(edit) if len(c) == 0: sol3, sol4 = [sol1, sol2 ] if random.random() > 0.5 else [sol2, sol1] if len(sol3) > 0: c.add(random.choice(sol3.edit_list)) elif len(sol4) > 0: c.add(random.choice(sol4.edit_list)) return c
def run(self): logger = self.program.logger # start! self.stats['steps'] = 0 self.stats['neighbours'] = 0 self.stats['wallclock_start'] = time.time() logger.info('==== {} ===='.format(self.name)) try: # initial fitness empty_patch = Patch(self.program) current_patch = empty_patch current_fitness = None if self.report['initial_fitness'] is None: for i in range(self.config['warmup']+1, 0, -1): run = self.evaluate_patch(empty_patch, force=True) l = 'WARM' if i > 1 else 'INITIAL' logger.info("{}\t{}\t{}".format(l, run.status, run.fitness)) assert run.status == 'SUCCESS', 'initial solution has failed' current_fitness = run.fitness self.report['best_patch'] = current_patch self.report['best_fitness'] = current_fitness self.report['initial_fitness'] = current_fitness self.program.base_fitness = current_fitness # main loop while not self.stopping_condition(): current_patch, current_fitness = self.explore(current_patch, current_fitness) finally: # the end self.stats['wallclock_end'] = time.time() logger.info('==== END ====')
def setup(): program = LineProgram('../sample/Triangle_bug_java') assert len(program.target_files) == 1 assert program.target_files[0] == 'Triangle.java' patch = Patch(program) return patch, program
def run(self): logger = self.program.logger # setup instances self.program.instances = self.sample_instances( self.config['nb_instances']) logger.debug('INSTANCES: %s', repr(self.program.instances)) # warmup logger.info('==== WARMUP ====') empty_patch = Patch(self.program) if self.report['initial_patch'] is None: self.report['initial_patch'] = empty_patch for i in range(self.config['warmup'] + 1, 0, -1): self.program.base_fitness = None self.program.truth_table = {} l = 'WARM' if i > 1 else 'INITIAL' run = self.evaluate_patch(empty_patch, force=True) logger.debug(run) logger.info("{}\t{}\t{}".format(l, run.status, run.fitness)) assert run.status == 'SUCCESS', 'initial solution has failed' current_fitness = run.fitness self.report['initial_fitness'] = current_fitness if self.report['best_patch'] is None: self.report['best_fitness'] = current_fitness self.report['best_patch'] = empty_patch else: run = self.evaluate_patch(self.report['best_patch'], force=True) logger.debug(run) logger.info("{}\t{}\t{}".format('BEST', run.status, run.fitness)) if self.dominates(run.fitness, current_fitness): self.report['best_fitness'] = run.fitness else: self.report['best_patch'] = empty_patch self.report['best_fitness'] = current_fitness if self.program.base_fitness is None: self.program.base_fitness = current_fitness # start! self.stats['steps'] = 0 self.stats['neighbours'] = 0 self.stats['wallclock_start'] = time.time() logger.info('==== {} ===='.format(self.name)) try: # main loop current_patch = self.report['best_patch'] while not self.stopping_condition(): current_patch, current_fitness = self.explore( current_patch, current_fitness) finally: # the end self.stats['wallclock_end'] = time.time() logger.info('==== END ====')
def test_apply(self, setup_line): program = setup_line patch = Patch([ LineInsertion(('triangle.py', '_inter_line', 1), ('triangle.py', 'line', 10)) ]) program.apply(patch) file_contents = open(os.path.join(program.work_path, 'triangle.py'), 'r').read() assert file_contents == program.dump( program.get_modified_contents(patch), 'triangle.py')
def setup(): config = { 'target_files': ["Triangle.java"], 'test_command': "./run.sh", } program = LineProgram('../sample/Triangle_bug_java', config=config) assert len(program.target_files) == 1 assert program.target_files[0] == 'Triangle.java' patch = Patch() return patch, program
def crossover(self, sol1, sol2): c = Patch(self.program) k1 = random.randint(0, len(sol1)) k2 = random.randint(0, len(sol1)) k3 = random.randint(0, len(sol2)) k4 = random.randint(0, len(sol2)) for edit in sol1.edit_list[:min(k1, k2)]: c.add(edit) for edit in sol2.edit_list[min(k3, k4):max(k3, k4)]: c.add(edit) for edit in sol1.edit_list[max(k1, k2):]: c.add(edit) return c
def explore(self, current_patch, current_fitness): if self.debug_patch is None: raise ValueError() self.report['best_fitness'] = None self.report['best_patch'] = None # eval every single patch for edit in full_patch.edit_list: patch = Patch([edit]) self.do_eval_patch(patch) self.report['stop'] = 'validation end' return current_patch, current_fitness
def crossover(self, sol1, sol2): c = Patch(self.program) k1 = random.randint(0, len(sol1)) k2 = random.randint(0, len(sol2)) for edit in sol1.edit_list[:k1]: c.add(edit) for edit in sol2.edit_list[k2:]: c.add(edit) return c
def run(self): # warmup self.hook_warmup() empty_patch = Patch() if self.report['initial_patch'] is None: self.report['initial_patch'] = empty_patch for i in range(self.config['warmup'] + 1, 0, -1): self.program.base_fitness = None self.program.truth_table = {} run = self.evaluate_patch(empty_patch, force=True) l = 'INITIAL' if i == 1 else 'WARM' self.hook_warmup_evaluation(l, empty_patch, run) if run.status != 'SUCCESS': raise RuntimeError('initial solution has failed') current_fitness = run.fitness self.report['initial_fitness'] = current_fitness if self.report['best_patch'] is None: self.report['best_fitness'] = current_fitness self.report['best_patch'] = empty_patch else: run = self.evaluate_patch(self.report['best_patch'], force=True) self.hook_warmup_evaluation('BEST', empty_patch, run) if self.dominates(run.fitness, current_fitness): self.report['best_fitness'] = run.fitness else: self.report['best_patch'] = empty_patch self.report['best_fitness'] = current_fitness if self.program.base_fitness is None: self.program.base_fitness = current_fitness # start! self.stats['steps'] = 0 self.stats['neighbours'] = 0 self.hook_start() try: # main loop current_patch = self.report['best_patch'] while not self.stopping_condition(): self.hook_main_loop() current_patch, current_fitness = self.explore( current_patch, current_fitness) finally: # the end self.hook_end()
def crossover(self, sol1, sol2): c = Patch(self.program) l1 = [(i / len(sol1), 0) for i in sorted( random.sample(range(len(sol1)), math.ceil(len(sol1) * self.config['uniform_rate'])))] l2 = [(i / len(sol2), 1) for i in sorted( random.sample(range(len(sol2)), math.ceil(len(sol2) * self.config['uniform_rate'])))] for (x, k) in sorted(l1 + l2): sol = [sol1, sol2][k] edit = sol.edit_list[int(x * len(sol))] c.add(edit) if len(c) == 0: sol3, sol4 = [sol1, sol2 ] if random.random() > 0.5 else [sol2, sol1] if len(sol3) > 0: c.add(random.choice(sol3.edit_list)) elif len(sol4) > 0: c.add(random.choice(sol4.edit_list)) return c
def explore(self, current_patch, current_fitness): # move patch = Patch() self.mutate(patch) # compare run = self.evaluate_patch(patch) best = False if run.status == 'SUCCESS': if self.dominates(run.fitness, self.report['best_fitness']): self.report['best_fitness'] = run.fitness self.report['best_patch'] = patch best = True # hook self.hook_evaluation(patch, run, False, best) # next self.stats['steps'] += 1 return patch, run.fitness
def explore(self, current_patch, current_fitness): debug_patch = self.report['debug_patch'] for edit in debug_patch.edit_list: # move patch = Patch([edit]) # compare run = self.evaluate_patch(patch) accept = best = False if run.status == 'SUCCESS': accept = True if self.dominates(run.fitness, self.report['best_fitness']): self.report['best_fitness'] = run.fitness self.report['best_patch'] = patch best = True # hook self.hook_evaluation(patch, run, accept, best) # next self.stats['steps'] += 1 self.report['stop'] = 'debug end' return current_patch, current_fitness
def explore(self, current_patch, current_fitness): # move patch = Patch(self.program) self.mutate(patch) # compare run = self.evaluate_patch(patch) h = [self.stats['steps'] + 1, run.status, ' ', run.fitness, patch] if run.status == 'SUCCESS': if self.dominates(run.fitness, self.report['best_fitness']): self.report['best_fitness'] = run.fitness self.report['best_patch'] = patch h[2] = '*' # log if h[2] == '*': self.program.logger.debug( self.program.diff(self.report['best_patch'])) self.program.logger.debug(run) self.program.logger.info('{}\t{}\t{}{}\t{}'.format(*h)) # next self.stats['steps'] += 1 return patch, run.fitness
def explore(self, current_patch, current_fitness): assert self.debug_patch is not None self.cleaned_patch = self.clean_patch(self.debug_patch) self.program.logger.debug('CLEAN_PATCH: {}'.format( str(self.cleaned_patch))) self.program.logger.debug('CLEAN_SIZE: %d (was %d)', len(self.cleaned_patch), len(self.debug_patch)) self.report['best_fitness'] = None self.report['best_patch'] = None # ranking ranking = list() for edit in cleaned_patch.edit_list: # move patch = Patch(self.program) patch.add(edit) # compare run = self.evaluate_patch(patch) accept = best = False if run.status == 'SUCCESS': accept = True if self.dominates(run.fitness, self.report['best_fitness']): self.report['best_fitness'] = run.fitness self.report['best_patch'] = patch best = True ranking.append((edit, run.fitness)) # hook self.hook_evaluation(patch, run, accept, best) # next self.stats['steps'] += 1 # rebuild ranking.sort(key=lambda c: c[1]) rebuild = Patch(self.program) # todo: fail if first bad for (k, (edit, _)) in enumerate(ranking): # move patch = copy.deepcopy(rebuild) patch.add(edit) # compare if k == 0: rebuild.add(edit) continue run = self.evaluate_patch(patch) accept = best = False if run.status == 'SUCCESS': accept = True # todo: accept only over a threshold if self.dominates(run.fitness, self.report['best_fitness']): self.program.logger.debug(self.program.diff(patch)) self.report['best_fitness'] = run.fitness self.report['best_patch'] = patch best = True rebuild.add(edit) # hook self.hook_evaluation(patch, run, accept, best) # next self.stats['steps'] += 1 self.report['stop'] = 'validation end' return current_patch, current_fitness
def run(self): logger = self.program.logger # setup instances self.program.instances = self.sample_instances( self.config['nb_instances']) logger.debug('INSTANCES: %s', repr(self.program.instances)) if self.config['reassess']: # seed magic to preserve randomness rng_state = self.inst_sample_random.getstate() self.inst_sample_random.seed( self.inst_sample_random.randrange(2 << 31 - 1)) self.program.reassess_instances = self.sample_instances( self.config['reassess_nb_instances']) logger.debug('REASSESS_INSTANCES: %s', repr(self.program.reassess_instances)) self.inst_sample_random.setstate(rng_state) # warmup logger.info('==== WARMUP ====') empty_patch = Patch(self.program) for i in range(self.config['warmup'] + 1, 0, -1): self.program.base_fitness = None self.program.truth_table = {} run = self.evaluate_patch(empty_patch, force=True) logger.debug(run) l = 'WARM' if i > 1 else 'INITIAL' logger.info("{}\t{}\t{}".format(l, run.status, run.fitness)) assert run.status == 'SUCCESS', 'initial solution has failed' self.report['initial_fitness'] = run.fitness self.report['best_fitness'] = run.fitness self.report['best_patch'] = empty_patch if self.config['reassess']: bak_initial_fitness = self.report['initial_fitness'] bak_instances = self.program.instances self.program.instances = self.program.reassess_instances self.program.base_fitness = None run = self.evaluate_patch(empty_patch, force=True, forget=True) logger.debug(run) logger.info("INITIAL\t{}\t{}".format(run.status, run.fitness)) assert run.status == 'SUCCESS', 'initial solution has failed' self.report['reassess_initial_fitness'] = run.fitness self.report['best_fitness'] = run.fitness self.program.base_fitness = bak_initial_fitness self.program.instances = bak_instances # start! self.stats['steps'] = 0 self.stats['wallclock_start'] = time.time() logger.info('==== {} ===='.format(self.name)) try: # initial pop pop = dict() local_best = None local_best_fitness = None while len(pop) < self.config['pop_size']: dist = 1 + int(random.random() * self.config['horizon'] - 1) sol = copy.deepcopy(empty_patch) for _ in range(dist): self.mutate(sol) if sol in pop: continue run = self.evaluate_patch(sol) h = [ self.stats['gen'], self.stats['steps'] + 1, run.status, ' ', run.fitness, sol ] if run.status == 'SUCCESS': if self.dominates(run.fitness, local_best_fitness): self.program.logger.debug(self.program.diff(sol)) local_best_fitness = run.fitness local_best = sol h[3] = '+' logger.debug(run) logger.info('{}\t{}\t{}\t{}{}\t{}'.format(*h)) pop[sol] = run self.stats['steps'] += 1 if local_best is not None: if self.config['reassess']: bak_initial_fitness = self.report['initial_fitness'] bak_instances = self.program.instances self.program.instances = self.program.reassess_instances self.program.base_fitness = self.report[ 'reassess_initial_fitness'] run = self.evaluate_patch(local_best, force=True, forget=True) h = [ self.stats['gen'] + 1, self.stats['steps'] + 1, run.status, ' ', run.fitness, local_best ] if run.status == 'SUCCESS': if self.dominates(run.fitness, self.report['best_fitness']): self.program.logger.debug( self.program.diff(local_best)) self.report['best_fitness'] = run.fitness self.report['best_patch'] = local_best h[3] = '*' logger.debug(run) logger.info('{}\t{}\t{}\t{}{}\t{}'.format(*h)) self.stats['steps'] += 1 self.program.instances = bak_instances self.program.base_fitness = bak_initial_fitness else: self.report['best_fitness'] = local_best_fitness self.report['best_patch'] = local_best # main loop while not self.stopping_condition(): offsprings = list() parents = self.select(pop) # elitism copy_parents = copy.deepcopy(parents) for parent in copy_parents[:self.config['offspring_elitism']]: offsprings.append(parent) # crossover copy_pop = copy.deepcopy(self.filter(pop)) copy_parents = copy.deepcopy(parents) for parent in copy_parents[:self. config['offspring_crossover']]: sol = random.sample(copy_pop, 1)[0] if random.random() > 0.5: sol = self.crossover(parent, sol) else: sol = self.crossover(sol, parent) offsprings.append(sol) # mutation copy_parents = copy.deepcopy(parents) for parent in copy_parents[:self.config['offspring_mutation']]: self.mutate(parent) offsprings.append(parent) # regrow while len(offsprings) < self.config['pop_size']: dist = 1 + int(random.random() * self.config['horizon'] - 1) sol = copy.deepcopy(empty_patch) for _ in range(dist): self.mutate(sol) if sol in pop: continue offsprings.append(sol) # update instances if self.config['rolling']: self.program.instances = self.sample_instances( self.config['nb_instances']) logger.debug('INSTANCES: %s', repr(self.program.instances)) self.program.base_fitness = None self.program.truth_table = {} self.cache_reset() run = self.evaluate_patch(empty_patch) logger.debug(run) logger.info("{}\t{}\t{}".format('INITIAL', run.status, run.fitness)) self.report['initial_fitness'] = run.fitness if not self.config['reassess']: self.report['best_fitness'] = run.fitness self.report['best_patch'] = empty_patch # replace pop.clear() local_best = None local_best_fitness = None for sol in offsprings: if self.stopping_condition(): break run = self.evaluate_patch(sol) h = [ self.stats['gen'] + 1, self.stats['steps'] + 1, run.status, ' ', run.fitness, sol ] if run.status == 'SUCCESS': if self.dominates(run.fitness, local_best_fitness): self.program.logger.debug(self.program.diff(sol)) local_best = sol local_best_fitness = run.fitness h[3] = '+' logger.debug(run) logger.info('{}\t{}\t{}\t{}{}\t{}'.format(*h)) pop[sol] = run self.stats['steps'] += 1 if local_best is not None: if self.config['reassess']: bak_initial_fitness = self.report['initial_fitness'] bak_instances = self.program.instances self.program.instances = self.program.reassess_instances self.program.base_fitness = self.report[ 'reassess_initial_fitness'] run = self.evaluate_patch(local_best, force=True, forget=True) h = [ self.stats['gen'] + 1, self.stats['steps'] + 1, run.status, ' ', run.fitness, local_best ] if run.status == 'SUCCESS': if self.dominates(run.fitness, self.report['best_fitness']): self.program.logger.debug( self.program.diff(local_best)) self.report['best_fitness'] = run.fitness self.report['best_patch'] = local_best h[3] = '*' logger.debug(run) logger.info('{}\t{}\t{}\t{}{}\t{}'.format(*h)) self.stats['steps'] += 1 self.program.instances = bak_instances self.program.base_fitness = bak_initial_fitness else: self.report['best_fitness'] = local_best_fitness self.report['best_patch'] = local_best # next self.stats['gen'] += 1 finally: # the end if self.config['reassess']: self.report['initial_fitness'] = self.report[ 'reassess_initial_fitness'] del self.report['reassess_initial_fitness'] self.stats['wallclock_end'] = time.time() logger.info('==== END ====')
def setup(self): super().setup() self.name = 'Tabu Search' self.config['tabu_length'] = 10 self.tabu_list = [Patch()] # queues are not iterable self.local_tabu = set()
def test_evaluate_patch(self, setup_tree): program = setup_tree patch = Patch() run = program.evaluate_patch(patch) assert run.status == 'SUCCESS' assert run.fitness is not None
def eval_patch(program, string): patch = Patch(program) for s in string.split(' | '): patch.add(eval_edit(s)) return patch
def setup(self): super().setup() self.name = 'Validation Ranking' self.debug_patch = Patch()
def run(self): # warmup self.hook_warmup() empty_patch = Patch(self.program) for i in range(self.config['warmup'] + 1, 0, -1): self.program.base_fitness = None self.program.truth_table = {} run = self.evaluate_patch(empty_patch, force=True) l = 'INITIAL' if i == 1 else 'WARM' self.hook_warmup_evaluation(l, empty_patch, run) assert run.status == 'SUCCESS', 'initial solution has failed' self.report['initial_fitness'] = run.fitness self.report['best_fitness'] = run.fitness self.report['best_patch'] = empty_patch # start! self.stats['steps'] = 0 self.hook_start() try: # initial pop pop = dict() local_best = None local_best_fitness = None while len(pop) < self.config['pop_size']: dist = 1 + int(random.random() * self.config['horizon'] - 1) sol = copy.deepcopy(empty_patch) for _ in range(dist): self.mutate(sol) if sol in pop: continue run = self.evaluate_patch(sol) h = [ self.stats['gen'], self.stats['steps'] + 1, run.status, ' ', run.fitness, sol ] if run.status == 'SUCCESS': if self.dominates(run.fitness, local_best_fitness): self.program.logger.debug(self.program.diff(sol)) local_best_fitness = run.fitness local_best = sol h[3] = '+' logger.debug(run) logger.info('{}\t{}\t{}\t{}{}\t{}'.format(*h)) pop[sol] = run self.stats['steps'] += 1 # main loop while not self.stopping_condition(): self.hook_main_loop() offsprings = list() parents = self.select(pop) # elitism copy_parents = copy.deepcopy(parents) for parent in copy_parents[:self.config['offspring_elitism']]: offsprings.append(parent) # crossover copy_pop = copy.deepcopy(self.filter(pop)) copy_parents = copy.deepcopy(parents) for parent in copy_parents[:self. config['offspring_crossover']]: sol = random.sample(copy_pop, 1)[0] if random.random() > 0.5: sol = self.crossover(parent, sol) else: sol = self.crossover(sol, parent) offsprings.append(sol) # mutation copy_parents = copy.deepcopy(parents) for parent in copy_parents[:self.config['offspring_mutation']]: self.mutate(parent) offsprings.append(parent) # regrow while len(offsprings) < self.config['pop_size']: dist = 1 + int(random.random() * self.config['horizon'] - 1) sol = copy.deepcopy(empty_patch) for _ in range(dist): self.mutate(sol) if sol in pop: continue offsprings.append(sol) # update instances if self.config['rolling']: self.program.instances = self.sample_instances( self.config['nb_instances']) logger.debug('INSTANCES: %s', repr(self.program.instances)) self.program.base_fitness = None self.program.truth_table = {} self.cache_reset() run = self.evaluate_patch(empty_patch) logger.debug(run) logger.info("{}\t{}\t{}".format('INITIAL', run.status, run.fitness)) self.report['initial_fitness'] = run.fitness self.report['best_fitness'] = run.fitness self.report['best_patch'] = empty_patch # replace pop.clear() local_best = None local_best_fitness = None for sol in offsprings: if self.stopping_condition(): break run = self.evaluate_patch(sol) h = [ self.stats['gen'] + 1, self.stats['steps'] + 1, run.status, ' ', run.fitness, sol ] if run.status == 'SUCCESS': if self.dominates(run.fitness, local_best_fitness): self.program.logger.debug(self.program.diff(sol)) local_best = sol local_best_fitness = run.fitness h[3] = '+' logger.debug(run) logger.info('{}\t{}\t{}\t{}{}\t{}'.format(*h)) pop[sol] = run self.stats['steps'] += 1 if local_best is not None: self.report['best_fitness'] = local_best_fitness self.report['best_patch'] = local_best # next self.stats['gen'] += 1 finally: # the end self.hook_end()
def run(self): self.tabu_list.append(Patch(self.program)) return super().run()