Esempio n. 1
0
    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
Esempio n. 2
0
    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