Exemplo n.º 1
0
 def create_random_instance(cls,
                            point_amount,
                            task,
                            bounds=(0, 500),
                            generation=0,
                            edge_chance=0.5):
     points = np.random.random_integers(bounds[0],
                                        bounds[1],
                                        size=(point_amount, 2))
     ad_matrix = np.zeros((len(points), len(points)))
     tril_indices = np.tril_indices_from(ad_matrix, -1)
     tril_edges = np.array([
         1 if i < edge_chance else 0
         for i in np.random.random(size=len(tril_indices[0]))
     ])
     while tril_edges.max() == 0:
         tril_edges = np.array([
             1 if i < edge_chance else 0
             for i in np.random.random(size=len(tril_indices[0]))
         ])
     ad_matrix[tril_indices] = tril_edges
     ad_matrix = ad_matrix + ad_matrix.T
     graph = Graph(points, ad_matrix=ad_matrix)
     return GraphGenome(graph,
                        bounds=bounds,
                        task=task,
                        generation=generation)
def create_random_bipartite(point_amount,
                            bounds=(0, 500),
                            edge_chance=0.5,
                            max_cone=np.inf):
    points = np.random.random_integers(bounds[0],
                                       bounds[1],
                                       size=(point_amount, 2))
    association = np.random.random_integers(0, 1, size=(point_amount))
    while association.max() == 0 or association.min() == 1:
        association = np.random.random_integers(0, 1, size=(point_amount))
    v_1 = []
    v_2 = []
    for i, a in enumerate(association):
        v_1.append(i) if not a else v_2.append(i)

    ad_matrix = np.zeros((len(points), len(points)))

    while ad_matrix.max() == 0:
        for i, j in itertools.product(v_1, v_2):
            if np.random.random() < edge_chance:
                ad_matrix[i, j] = ad_matrix[j, i] = 1
                lb = max(get_lower_bounds(points, ad_matrix))
                if lb > max_cone:
                    ad_matrix[i, j] = ad_matrix[j, i] = 0

    graph = Graph(points, ad_matrix=ad_matrix)
    return graph, association
Exemplo n.º 3
0
def test_build_paths():
    ip = AngularGraphScanMakespanHamilton()
    n = 3
    ad_vert = np.zeros([n * n], dtype=tuple)
    ad_vert[:] = [(i, j) for i in range(3) for j in range(3)]
    edges = set([(v1, v2) for v1 in ad_vert for v2 in ad_vert if v1 != v2])
    g = Graph(ad_vert, edges)
    model = gurobipy.Model()
    ip._build_hamilton_path(0)
    def solve(self, graph: Graph, **kwargs):
        start_time = time.time()
        times = None
        error_message = None
        try:
            coloring = self.coloring_solver(graph)
            max_color = max(coloring)
            index_colorings = []

            log_max_color = math.ceil(math.log2(max_color))
            color_bit_vector = np.array([[(color >>
                                           (log_max_color - 1 - i)) & 1
                                          for i in range(log_max_color)]
                                         for color in range(max_color)])

            for vec in color_bit_vector.T:
                # Get indices of the vertices where in one of the sets
                to_color = np.arange(len(vec))[vec == 1]
                isin = np.isin(coloring, to_color)
                both_sets_indices = (*np.where(isin == 0),
                                     *np.where(isin == 1))
                index_colorings.append(both_sets_indices)

            solutions = []
            used_edges = set()
            for set_one, set_two in index_colorings:
                subgraph = graph.get_bipartite_subgraph(
                    set_one, set_two, forbidden_edges=used_edges)
                if subgraph.edge_amount > 0:
                    sol = self.sub_solver.solve(
                        subgraph,
                        colors=[
                            int(i in set_one) for i in range(graph.vert_amount)
                        ])
                    solutions.append(sol)
                    # If wanted collect the already used edges to maybe get a better solution
                    if self.no_used_edges:
                        used_edges.update({(u)
                                           for u in product(set_one, set_two)})

            times = self._calculate_order(solutions, graph)
            if len(times) != graph.edge_amount:
                times = None
                raise Exception("Edge order does not contain all edges!")
        except Exception as e:
            error_message = str(e)
            raise e
        return AngularGraphSolution(graph,
                                    time.time() - start_time,
                                    self.__class__.__name__,
                                    self.sub_solver.solution_type,
                                    times=times,
                                    error_message=error_message)
Exemplo n.º 5
0
def test_ip_solver():
    ip = AngularGraphScanMakespanAbsoluteReduced()
    n = 3
    ad_vert = np.zeros([n * n], dtype=tuple)
    ad_vert[:] = [(i, j) for i in range(3) for j in range(3)]
    e_arr = np.triu_indices(n*n, 1)
    edges = {(ad_vert[e_arr[0][i]], ad_vert[e_arr[1][i]]) for i in range(len(e_arr[0]))}

    g = Graph(ad_vert, edges)
    solution = ip.build_ip_and_optimize(g)
    from utils.visualization import visualize_solution_2d, visualize_graph_2d
    #visualize_graph_2d(solution.graph)
    visualize_solution_2d(solution)
Exemplo n.º 6
0
def test_ip_solver_not_fully_connected():
    ip = AngularGraphScanMakespanAbsoluteReduced()
    n = 3
    ad_vert = np.zeros([n * n - 1], dtype=tuple)
    ad_vert[:] = [(i, j) for i in range(3) for j in range(3) if i != 1 or i != j]
    e_arr = np.triu_indices(n*n-1, 1)
    edges = [(ad_vert[e_arr[0][i]], ad_vert[e_arr[1][i]]) for i in range(len(e_arr[0]))]
    random.seed(0)

    chosen_edges = random.sample(edges, k=math.ceil(len(edges)/2))
    g = Graph(ad_vert, chosen_edges)
    solution = ip.build_ip_and_optimize(g)
    from utils.visualization import visualize_solution_2d, visualize_graph_2d
    #visualize_graph_2d(solution.graph)
    visualize_solution_2d(solution)
Exemplo n.º 7
0
 def create_random_instance(cls,
                            point_amount,
                            task,
                            bounds=(0, 500),
                            generation=0):
     points = np.random.random_integers(bounds[0],
                                        bounds[1],
                                        size=(point_amount, 2))
     ad_matrix = np.ones((len(points), len(points)))
     ad_matrix[np.diag_indices_from(ad_matrix)] = 0
     graph = Graph(points, ad_matrix=ad_matrix)
     return CompleteGraphGenome(graph,
                                bounds=bounds,
                                task=task,
                                generation=generation)
def create_random_instance_fixed_edges(point_amount,
                                       edge_amount,
                                       bounds=(0, 500),
                                       seed=None):
    gen = np.random.default_rng(seed)
    points = gen.integers(bounds[0], bounds[1], size=(point_amount, 2))
    ad_matrix = np.zeros((len(points), len(points)))
    tril_indices = np.tril_indices_from(ad_matrix, -1)
    l = len(tril_indices[0])
    chosen = gen.choice(range(l), size=edge_amount, replace=False)
    chosen_indices = np.zeros(l)
    chosen_indices[chosen] = 1
    ad_matrix[tril_indices] = chosen_indices
    ad_matrix = ad_matrix + ad_matrix.T
    graph = Graph(points, ad_matrix=ad_matrix)
    return graph
Exemplo n.º 9
0
def _visualize_edges_2d(graph: Graph, taken_edges=None, already_used=None):
    if graph.vertices.dtype == np.dtype('O'):
        graph.vertices = np.array([p for p in graph.vertices])
    for edge in graph.edges:
        plt.plot(graph.vertices[edge][:, 0],
                 graph.vertices[edge][:, 1],
                 color='black',
                 marker=',',
                 alpha=0.3)
    if already_used:
        for indices in already_used:
            edge = np.array([graph.vertices[i] for i in indices])
            plt.plot(edge[:, 0], edge[:, 1], "y-")
    if taken_edges:
        for indices in taken_edges:
            edge = np.array([graph.vertices[i] for i in indices])
            plt.plot(edge[:, 0], edge[:, 1], "r-")
Exemplo n.º 10
0
def convert_graph_to_angular_abstract_graph(graph: Graph,
                                            simple_graph=True,
                                            return_tripel_edges=False
                                            ) -> Graph:
    """Converts a graph into an abstract angular graph
    Can be used to calculate a path tsp
    
    Arguments:
        graph {Graph} -- Graph to be converted
        simple_graph {bool} -- Indicates if graph is simple
        return_tripel_edges {bool} -- Also return translation for original edges to abstract 
    
    Returns:
        Graph -- Converted abstract graph
    """
    # create a vertex for every edge in the original graph
    # For geometric instances, only one direction of edges is needed
    vertices = np.array([[u, v] for u, v in graph.edges if u < v])
    edges = {}
    tripel_edges = {}
    for i, vertex in enumerate(vertices):
        ran = range(i +
                    1, len(vertices)) if simple_graph else range(len(vertices))
        for j in ran:
            if j == i:
                continue
            other = vertices[j]
            if np.intersect1d(vertex, other).size > 0:
                shared_vertex = np.intersect1d(vertex, other)
                non_shared = np.setdiff1d(np.hstack([vertex, other]),
                                          shared_vertex)
                edges[(i, j)] = get_angle(graph.vertices[shared_vertex],
                                          graph.vertices[non_shared[0]],
                                          graph.vertices[non_shared[1]])
                if return_tripel_edges:
                    from_vertex = np.intersect1d(vertex, non_shared)
                    to_vertex = np.intersect1d(other, non_shared)
                    edge = (*from_vertex, *to_vertex)
                    tripel_edges[(*shared_vertex, *edge)] = (i, j)
    graph = Graph(vertices, edges.keys(), c=edges)
    if return_tripel_edges:
        return (tripel_edges, graph)
    return graph
Exemplo n.º 11
0
    def create_children(self, data, mother=None, **kwargs):
        generation = self.generation
        try:
            generation = max(generation, mother.generation)
        except AttributeError:
            pass
        generation = kwargs.pop("generation", generation + 1)

        vertices, ad_matrix = self._translate_chromosome(data)

        graph = Graph(V=vertices,
                      ad_matrix=ad_matrix,
                      i_type=self.graph.i_type)

        return GraphGenome(graph,
                           parents=[self, mother],
                           generation=generation,
                           bounds=self.bounds,
                           task=self.task)
Exemplo n.º 12
0
def create_random_instance(point_amount,
                           bounds=(0, 500),
                           edge_chance=0.5,
                           seed=None):
    gen = np.random.default_rng(seed)
    points = gen.integers(bounds[0], bounds[1], size=(point_amount, 2))
    ad_matrix = np.zeros((len(points), len(points)))
    tril_indices = np.tril_indices_from(ad_matrix, -1)
    tril_edges = np.array([
        1 if i < edge_chance else 0
        for i in gen.random(size=len(tril_indices[0]))
    ])
    while tril_edges.max() == 0:
        tril_edges = np.array([
            1 if i < edge_chance else 0
            for i in gen.random(size=len(tril_indices[0]))
        ])
    ad_matrix[tril_indices] = tril_edges
    ad_matrix = ad_matrix + ad_matrix.T
    graph = Graph(points, ad_matrix=ad_matrix)
    return graph
Exemplo n.º 13
0
def _greedy_order(orders, graph: Graph, solver: Solver, slice, timeout):
    start_time = time.time()
    results = []
    for orig_order in orders:
        if time.time() - start_time > timeout:
            return results, slice
        arg_ordered = np.argsort(orig_order)
        ordered = orig_order[arg_ordered]
        inner_graph = Graph(graph.vertices, graph.edges[arg_ordered])
        order, cost = solver.solve(inner_graph, no_sol_return=True)
        edge_dict = {(o[0], o[1]): i for i, o in enumerate(graph.edges)}
        order_translate = {
            edge_dict[(e1, e2)]: i
            for i, (e1, e2) in enumerate(order)
        }
        new_order = np.array(
            [ordered[order_translate[key]] for key in range(len(orig_order))])
        cost = _calculate_cost(solver, graph, new_order)
        results.append((new_order, -cost))

    return results, slice
Exemplo n.º 14
0
def _greedy_order(orders, graph: Graph, solver: Solver):
    results = []
    for orig_order in orders:
        arg_ordered = np.argsort(orig_order)
        ordered = orig_order[arg_ordered]
        inner_graph = Graph(graph.vertices, graph.edges[arg_ordered])
        order, cost = solver.solve(inner_graph, no_sol_return=True)
        edge_dict = {(o[0], o[1]): i for i, o in enumerate(graph.edges)}
        order_translate = {
            edge_dict[(e1, e2)]: i
            for i, (e1, e2) in enumerate(order)
        }
        new_order = np.array(
            [ordered[order_translate[key]] for key in range(len(orig_order))])
        times, heads = calculate_times(graph.edges[np.argsort(new_order)],
                                       graph,
                                       return_angle_sum=True)
        try:
            assert (graph.edges[np.argsort(new_order)] == order
                    ).all(), "Not all edges are sorted the same"
        except AssertionError as ar:
            print(ar)
        results.append((new_order, -cost))
    return results
Exemplo n.º 15
0
    def create_children(self, data, mother=None, **kwargs):
        # If no graph creation function is passed just create a fully connected graph
        generation = self.generation
        try:
            generation = max(generation, mother.generation)
        except AttributeError:
            pass
        generation = kwargs.pop("generation", generation + 1)

        if self.graph_creation_func is None:
            ad_matrix = np.ones((len(data), len(data)))
            ad_matrix[np.diag_indices_from(ad_matrix)] = 0
            self.graph_creation_func = None
            graph = Graph(data, ad_matrix=ad_matrix)
        else:
            graph = self.graph_creation_func(data)

        return CompleteGraphGenome(
            graph,
            parents=[self, mother],
            graph_creation_func=self.graph_creation_func,
            generation=generation,
            bounds=self.bounds,
            task=self.task)
Exemplo n.º 16
0
test_graphs = [
    Graph(V=np.array([[345,  53],
       [482,  51],
       [333, 455],
       [425, 128],
       [417, 316],
       [417, 382],
       [ 65, 101],
       [235, 207],
       [ 96, 229],
       [470,  60],
       [ 74, 253],
       [ 76, 478],
       [491, 473],
       [166, 176]]),
       ad_matrix=np.array([[0., 0., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 1., 1., 0., 1., 0., 0., 0., 0., 0.],
       [1., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 1., 0.],
       [0., 0., 1., 0., 0., 1., 0., 0., 0., 0., 0., 0., 1., 0.],
       [0., 1., 0., 0., 1., 0., 0., 1., 0., 0., 0., 0., 0., 1.],
       [0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 1., 0.],
       [1., 1., 0., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 1., 1., 0., 0., 1., 0., 1., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.]])
    ),
    Graph(
Exemplo n.º 17
0
 def _decode_graph(self, graph):
     return Graph(np.array(graph["vertices"]),
                  ad_matrix=np.array(graph["ad_matrix"]))
Exemplo n.º 18
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
Exemplo n.º 19
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
Exemplo n.º 20
0
 def calculate_graph(self):
     """(Re-)calculate the graph with new sorted order_numbers
     """
     sorted_indices = np.argsort(self.order_numbers)
     edges = self.orig_graph.edges[sorted_indices]
     self.graph = Graph(self.orig_graph.vertices, edges)