def solve(self, graph: Graph, **kwargs): if graph.costs is None: graph.costs = get_graph_angles(graph) error_message = None self.time_limit = kwargs.pop("time_limit", self.max_time) self.graph = graph try: self.start_time = time.time() genomes = np.zeros(self.pop_size, dtype=object) genomes[:] = [ EdgeOrderGraphGenome(graph, skip_graph_calc=True) for i in range(self.pop_size) ] with concurrent.futures.ThreadPoolExecutor( max_workers=cpu_count()) as executor: self.executor = executor if self.greedy_start: slicings = self._get_slicing(genomes) futures = [ executor.submit( _greedy_order, [ genome.order_numbers for genome in genomes[slicing] ], self.graph, self.sub_solvers[np.random.randint( 0, len(self.sub_solvers))] #self._greedy_order, genomes[slicing],\ #self.sub_solvers[np.random.randint(0, len(self.sub_solvers))] ) for slicing in slicings ] timeout_time = self.time_limit - (time.time() - self.start_time) concurrent.futures.wait(futures, timeout=timeout_time) for future in futures: future.exception() # Start solver genetic_algorithm = GeneticAlgorithm( genomes=genomes, selection=self.selection, mutation=self._mutation, fitness=self._fitness, crossover=self.crossover, callback=self.callback, termCon=self.termination_condition, elitism=self.elitism, mutationChance=self.mutation_chance_genome, mutationChanceGene=self.mutation_chance_gene) last_gen = genetic_algorithm.evolve() except concurrent.futures.TimeoutError as time_error: error_message = str(time_error) last_gen = genetic_algorithm.genomes finally: self.executor = None self.graph = None max_index = np.argmax([gen.solution for gen in last_gen]) arg_sorted = np.argsort(last_gen[max_index].order_numbers) order = graph.edges[arg_sorted].tolist() sol = AngularGraphSolution(graph, time.time() - self.start_time, self.__class__.__name__, self.solution_type, is_optimal=False, order=order, error_message=error_message) return sol
def solve(self, graph: Graph, start_solution=None, **kwargs): time_limit = float(kwargs.pop("time_limit", self.time_limit)) start_time = time.time() if graph.costs is None: angles = get_graph_angles(graph) graph.costs = angles else: angles = [i.copy() for i in graph.costs] solution = self.sub_solver( graph) if start_solution is None else start_solution improvement = True # solution can be AngularGraphSolution or simple edge order best_order = np.array(solution.order) if isinstance( solution, AngularGraphSolution) else np.array(solution) best_cost = self._get_cost(solution, angles) with concurrent.futures.ThreadPoolExecutor( max_workers=cpu_count()) as executor: try: error_message = None with tqdm.tqdm( total=self.max_iterations, desc= f"Iterating local neighborhood. Best Sol: {best_cost}" ) as progressbar: iteration = 0 while (self.max_iterations is None or iteration < self.max_iterations) and\ (time_limit or time.time() - start_time < time_limit) and\ (improvement): improvement = False candidate_order = None candidate_cost = None futures = [ executor.submit(self._inner_solve, [i.copy() for i in angles], i, best_order, best_cost, time_limit, start_time) for i in range(graph.edge_amount) ] timeout = time_limit - (time.time() - start_time) + 10 concurrent.futures.wait(futures, timeout=timeout) for future in futures: if future.done(): order, cost = future.result() if candidate_cost is None or cost < candidate_cost: candidate_cost = cost candidate_order = order if candidate_cost is not None and candidate_cost < best_cost: improvement = True best_cost = candidate_cost best_order = candidate_order progressbar.set_description( f"Iterating local neighborhood. Best Sol: {best_cost}" ) if not improvement: break progressbar.update() iteration += 1 except concurrent.futures.TimeoutError as time_error: error_message = str(time_error) + " in iteration " + str( iteration) sol = AngularGraphSolution(graph, time.time() - start_time, self.__class__.__name__, self.solution_type, is_optimal=False, order=best_order.tolist(), error_message=error_message) return sol