Ejemplo n.º 1
0
    def _inner_solve(self, graph: Graph, first_sol: Union[AngularGraphSolution,
                                                          List]):
        angles = get_graph_angles(graph)
        start_time = time.time()
        time_limit = self.time_limit
        max_iter = self.max_iterations
        max_no_impr = self.max_no_improve
        best_order, best_cost = self._get_cost(first_sol, angles=angles)
        curr_cost = best_cost
        curr_order = best_order
        heat_function = self.heat_function if self.heat_function is not None else\
            BolzmanHeatWithReheat()

        neighborhood = np.array([
            neighbor
            for neighbor in itertools.permutations(range(len(best_order)), 2)
        ])
        i = 0
        improved_in_step = 0
        while (max_iter is None or i < max_iter) and\
              (max_no_impr is None or i - improved_in_step < max_no_impr) and\
              (time.time() - start_time < time_limit):
            swap_index = np.random.randint(0, len(neighborhood), size=1)
            swap = neighborhood[swap_index]
            order, cost = self._calculate_swap(angles, swap, curr_order)
            if cost < curr_cost or heat_function(best_cost, cost, i,
                                                 i - improved_in_step):
                improved_in_step = i if cost < best_cost else improved_in_step
                curr_cost = cost
                curr_order = order
                if cost < best_cost:
                    best_cost = cost
                    best_order = order
            i += 1
        return best_order, best_cost
Ejemplo n.º 2
0
    def solve(self, graph: Graph, no_sol_return=None, **kwargs):
        if no_sol_return is None:
            no_sol_return = self.no_sol_return if self.no_sol_return is not None else False

        start_time = time.time()
        # Process kwargs
        upper_bound = kwargs.pop("ub", None)
        order = kwargs.pop("presolved", [])
        order = order.copy()
        headings = kwargs.pop("headings", [[] for head in graph.vertices])
        assert isinstance(headings, list)
        headings = headings.copy()
        for i, heading in enumerate(headings):
            headings[i] = heading.copy()
        remaining_edges = kwargs.pop("remaining", graph.edges)
        if isinstance(remaining_edges, np.ndarray):
            remaining_edges = remaining_edges.tolist()
        remaining_edges = remaining_edges.copy()
        # If one is empty, the other also needs to be emtpy
        assert order or len(remaining_edges) == graph.edge_amount
        assert len(remaining_edges) != graph.edge_amount or not order
        angles = graph.costs
        if angles is None:
            angles = get_graph_angles(graph)
        overall_cost = self._calc_pre_cost(headings, angles)
        while remaining_edges and (upper_bound is None
                                   or upper_bound > overall_cost):
            candidate_edge, candidate_cost = self._get_candidate(
                order, remaining_edges, headings, angles)

            self._set_new_headings(candidate_edge, headings)

            to_remove = self._get_edge(remaining_edges, candidate_edge)
            remaining_edges.remove(to_remove)
            order.append(to_remove)
            overall_cost += candidate_cost

        if no_sol_return:
            return order, overall_cost
        sol = AngularGraphSolution(graph,
                                   time.time() - start_time,
                                   self.__class__.__name__,
                                   self.solution_type,
                                   is_optimal=False,
                                   order=order)
        return sol
Ejemplo n.º 3
0
    def solve(self, graph: Graph, start_solution=None, **kwargs):
        self.time_limit = float(kwargs.pop("time_limit", self.max_time))
        start_time = time.time()

        #    graph.costs = get_graph_angles(graph)
        solution = self.sub_solver(
            graph) if start_solution is None else start_solution
        angles = None
        if not isinstance(solution, AngularGraphSolution):
            angles = get_graph_angles(graph)
        best_order, best_cost = self._get_cost(solution, angles)
        with concurrent.futures.ThreadPoolExecutor(
                max_workers=cpu_count()) as executor:
            try:
                error_message = None
                futures = [
                    executor.submit(self._inner_solve, graph, best_order)
                    for swap in range(cpu_count())
                ]
                timeout = self.time_limit - (time.time() - start_time) + 10
                concurrent.futures.wait(futures, timeout=timeout)
            except TimeoutError as time_error:
                error_message = str(time_error)
            for future in futures:
                if future.done():
                    order, cost = future.result()
                    if cost < best_cost:
                        best_cost = cost
                        best_order = order
            if isinstance(best_order, np.ndarray):
                best_order = best_order.tolist()
            sol = AngularGraphSolution(graph,
                                       time.time() - start_time,
                                       self.__class__.__name__,
                                       self.solution_type,
                                       is_optimal=False,
                                       order=best_order,
                                       error_message=error_message)
            return sol
Ejemplo n.º 4
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
Ejemplo n.º 5
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