def run(target, cores, s=None): """ Genetic Hill Climbing Algorithm run here. Stores the image results in RESULTS directory, after every SAVE_PER_GEN generations . """ RESULTS = "results" # Make RESULTS directory, if not exists. if not os.path.exists(RESULTS): os.mkdir(RESULTS) # Logs file, in RESULTS directory. f = open(os.path.join(RESULTS, "logs.txt"), "a") generation = 1 INIT_GENES = 50 parent = Chromosome(target.size, INIT_GENES) # Load Save file from function parameter. if s is not None: generation = parent.load(jsonpickle.decode(s)) # First generation fitness. score = utils.fitness(parent.draw(), target) # Create thread pool for each core. p = multiprocessing.Pool(cores) # Frequency of saves and number of children # per generation of Genetic Hill Climbing Algorithm. SAVE_PER_GEN = 500 CHILDS_PER_GEN = 50 while True: f.write("Generation {0} Score {1}\n".format( generation, round(score, 5))) # Draw the image and save it. # Also save the logs. if generation % SAVE_PER_GEN == 0: print("Generation {0}\tScore {1}".format( generation, round(score, 5))) parent.draw().save(os.path.join( RESULTS, "{0}.png".format(generation))) save_file = open(os.path.join( RESULTS, "{0}.txt".format(generation)), "w") save_file.write(jsonpickle.encode(parent.save(generation))) save_file.close() generation += 1 # Mutate the current parent. try: results = utils.group_mutate(parent, CHILDS_PER_GEN - 1, p, target) except KeyboardInterrupt: print("Exiting program... Bye!") p.close() return # Children for the next generation. # Includes the current parent in case # bad mutation. new_score, new_children = map(list, zip(*results)) new_score.append(score) new_children.append(parent) # Choose the fittest child for next generation. fittest = min(zip(new_children, new_score), key=lambda x: x[1]) parent, score = fittest