def save(self, timestep, map, tracks): """Saves plot of current population.""" self.status_msg(timestep, writing=True) if self.grade != 0: grade = self.grade else: grade = "" with Timer() as write_timer: save_svg(self.filename(timestep), map, tracks, grade, out_directory=self.out_directory) write_duration = write_timer.elapsed self.write_durations.append(write_duration) self.status_msg(timestep, writing=False)
def run(self): """Runs the simulation.""" parser = argparse.ArgumentParser(description="Simulates evolution" " for tracks on a given map.") parser.add_argument("--config_file", help="file name of the config file", default="default.cfg") args = parser.parse_args() self.init_msg("Reading config ...", ok=False) config = configparser.ConfigParser() if os.path.isfile(args.config_file): config.read(args.config_file) map_file_name = config["Map"]["filename"] population_size = config["Map"]["population_size"] max_acceleration = config["Map"]["max_acceleration"] distance_factor = config["Map"]["distance_factor"] collision_penalty = config["Map"]["collision_penalty"] retain_percentage = config["Map"]["retain_percentage"] random_select_chance = config["Map"]["random_select_chance"] mutate_chance = config["Map"]["mutate_chance"] self.max_timesteps = int(config["Map"]["max_timesteps"]) confidence_level = int(config["Map"]["confidence_level"]) write_plots = literal_eval(config["Plots"]["enabled"]) self.out_directory = config["Plots"]["out_directory"] write_frequency = int(config["Plots"]["frequency"]) clean_previous = literal_eval(config["Plots"]["clean_previous"]) plot_grades = literal_eval(config["Plots"]["plot_grades"]) else: raise Exception("Config file " + args.config_file + " not found. Exiting.") self.init_msg("Reading config", progress=1, ok=True) if clean_previous and os.path.exists(self.out_directory): self.init_msg("Cleaning previous plots ...", ok=False) os.system("rm -rf " + self.out_directory + "/*") self.init_msg("Cleaning previous plots", progress=1, ok=True) map = Map(max_acceleration, map_file_name) if write_plots: self.init_msg("Saving map ...", ok=False) save_svg("map.svg", map, out_directory=self.out_directory) self.init_msg("Saving map", progress=1, ok=True) self.init_msg("Generating population ", progress=0, ok=False) population = Population( map=map, population_size=population_size, distance_factor=distance_factor, collision_penalty=collision_penalty, retain_percentage=retain_percentage, random_select_chance=random_select_chance, mutate_chance=mutate_chance) self.init_msg("Generating population", progress=1, ok=True) # write first plot if write_plots: self.save(0, map, population.tracks) for i in range(1, self.max_timesteps + 1): self.status_msg(i, writing=False) with Timer() as timer: self.grade = population.evolve() self.timestep_durations.append(timer.elapsed) # write plots regularly self.grades.append((i, self.grade)) if (write_plots and i % write_frequency == 0): self.save(i, map, population.tracks) # check if population changes if len(self.grades) > confidence_level: mean = (sum(y for (x,y) in self.grades[-confidence_level:]) /confidence_level) not_changing = True for _, grade in self.grades[-confidence_level:]: if grade - mean > 1: not_changing = False if not_changing: break # write final plot if (write_plots and not (i % write_frequency == 0)): self.save(i, map, population.tracks) print("\nPopulation isn't changing anymore. Exiting ...") # write solution plot self.init_msg("Writing solution ...", ok=False) if write_plots: save_svg("solution.svg", map, [population.tracks[0]], out_directory=self.out_directory) with open(self.out_directory + "/solution", "w") as solution_file: length = str(len(str(max_acceleration)) + 1) for vector in population.tracks[0].acceleration_vectors: solution_file.write(("({:>" + length + "d}, {:>" + length + "d})\n").format(vector.x, vector.y)) self.init_msg("Writing solution", progress=1, ok=True) if plot_grades: with open(self.out_directory + "/grades", "w") as grade_file: for timestep, grade in self.grades: string = ("{:>" + str(len(str(self.max_timesteps))) + "} {:>4.5f}\n").format(timestep, grade) grade_file.write(string) with open(self.out_directory + "/plot", "w") as plot_file: plot_file.write("set term pdf\n") plot_file.write("set out '" + self.out_directory + "/grades.pdf'\n") plot_file.write("set xlabel 'Timestep'\n") plot_file.write("set ylabel ' Grade'\n") plot_file.write("p '" + self.out_directory + "/grades' u 1:2 w l title 'Grades'\n") os.system("gnuplot " + self.out_directory + "/plot")