Beispiel #1
0
 def test_networkx_graph(self):
     G = nx.Graph()
     G.add_path([100, 200, 300])
     G.add_node(1000)
     P = planarity.PGraph(G)
     H = planarity.networkx_graph(P)
     assert_equal(sorted(G.nodes()), sorted(H.nodes()))
     assert_equal(sorted(G.edges()), sorted(H.edges()))
Beispiel #2
0
 def test_write_adjlist(self):
     e = ([1, 2], )
     P = planarity.PGraph(e)
     fname = tempfile.mktemp()
     P.write(fname)
     d = open(fname).read()
     answer = 'N=2\n1: 2 0\n2: 1 0\n'
     assert_equal(d, answer)
     os.unlink(fname)
Beispiel #3
0
def kuratowski_subgraph(graph):
    """Return forbidden subgraph of nonplanar graph G."""
    try:
        import networkx as nx
    except ImportError:
        raise ImportError("NetworkX required for kuratowski_subgraph()")
    pgraph = planarity.PGraph(graph)
    edges = pgraph.kuratowski_edges()
    return nx.Graph(edges)
Beispiel #4
0
 def test_goldner_harary(self):
     # goldner-harary graph
     # http://en.wikipedia.org/wiki/Goldner%E2%80%93Harary_graph
     # a maximal planar graph
     e = [(1, 2), (1, 3), (1, 4), (1, 5), (1, 7), (1, 8), (1, 10), (1, 11),
          (2, 3), (2, 4), (2, 6), (2, 7), (2, 9), (2, 10), (2, 11), (3, 4),
          (4, 5), (4, 6), (4, 7), (5, 7), (6, 7), (7, 8), (7, 9), (7, 10),
          (8, 10), (9, 10), (10, 11)]
     P = planarity.PGraph(e)
     assert_true(P.is_planar())
Beispiel #5
0
def draw(graph, labels=True):
    """Draw planar graph with Matplotlib."""
    try:
        import matplotlib.pyplot as plt
        from matplotlib.patches import Circle
        from matplotlib.collections import PatchCollection
    except ImportError:
        raise ImportError("Matplotlib is required for draw()")
    pgraph = planarity.PGraph(graph)
    pgraph.embed_drawplanar()
    hgraph = networkx_graph(pgraph)
    patches = []
    node_labels = {}
    xs = []
    ys = []
    for node, data in hgraph.nodes(data=True):
        y = data['pos']
        xb = data['start']
        xe = data['end']
        x = int((xe + xb) / 2)
        node_labels[node] = (x, y)
        patches += [Circle((x, y), 0.25)]  #,0.5,fc='w')]
        xs.extend([xb, xe])
        ys.append(y)
        plt.hlines([y], [xb], [xe])

    for (_, _, data) in hgraph.edges(data=True):
        x = data['pos']
        yb = data['start']
        ye = data['end']
        ys.extend([yb, ye])
        xs.append(x)
        plt.vlines([x], [yb], [ye])

    # labels
    if labels:
        for n, (x, y) in node_labels.items():
            plt.text(x,
                     y,
                     n,
                     horizontalalignment='center',
                     verticalalignment='center',
                     bbox=dict(
                         boxstyle='round',
                         ec=(0.0, 0.0, 0.0),
                         fc=(1.0, 1.0, 1.0),
                     ))
    p = PatchCollection(patches)
    ax = plt.gca()
    ax.add_collection(p)
    plt.axis('equal')
    plt.xlim(min(xs) - 1, max(xs) + 1)
    plt.ylim(min(ys) - 1, max(ys) + 1)
Beispiel #6
0
 def test_is_planar_edgelist_input(self):
     P = planarity.PGraph(self.p4_edgelist)
     assert_true(P.is_planar())
     P = planarity.PGraph(self.k5_edgelist)
     assert_false(P.is_planar())
Beispiel #7
0
 def test_draw_text(self):
     e = ([1, 2], )
     P = planarity.PGraph(e)
     s = P.ascii()  #.decode()
     assert_equal(s, '1\n|\n2\n \n')
Beispiel #8
0
 def test_no_kuratowski_k5m(self):
     edges = self.k5_edgelist[:]
     edges.remove((0, 1))
     P = planarity.PGraph(edges)
     edges = P.kuratowski_edges()
     assert_equal(edges, [])
Beispiel #9
0
 def test_kuratowski_k5(self):
     P = planarity.PGraph(self.k5_edgelist)
     edges = P.kuratowski_edges()
     assert_equal(sorted(edges), sorted(self.k5_edgelist))
Beispiel #10
0
 def test_is_planar_adj_list(self):
     P = planarity.PGraph(self.k5_adj_list)
     assert_false(P.is_planar())
Beispiel #11
0
 def test_is_planar_adj_symmetric(self):
     P = planarity.PGraph(self.k5_adj_symmetric)
     assert_false(P.is_planar())
Beispiel #12
0
def write(graph, path='stdout'):
    """Write an adjacency list representation of graph to path."""
    planarity.PGraph(graph).write(path)
Beispiel #13
0
import planarity
# Example of the complete graph of 5 nodes, K5
# K5 is not planar
# any of the following formats can bed used for representing the graph

edgelist = [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3),
            (2, 4), (3, 4)]
P = planarity.PGraph(edgelist)
print(P.nodes())  # indexed from 1..n
print(P.mapping())  # the node mapping
print(P.edges())  # edges
print(P.is_planar())  # False
print(P.kuratowski_edges())

edgelist.remove((0, 1))
P = planarity.PGraph(edgelist)
print(P.ascii())
Beispiel #14
0
    def _construct_planar_graph(self):
        pd = self.planar_diagram()
        g, duplicates, heights, first_edge = pd.as_networkx_extended()

        import planarity

        pg = planarity.PGraph(g)
        pg.embed_drawplanar()
        g = planarity.networkx_graph(pg)

        node_labels = {}
        xs = []
        ys = []

        nodes_by_height = {}
        node_xs_by_y = {}
        node_xs_ys = {}
        node_lefts_rights = {}

        for node, data in g.nodes(data=True):
            y = data['pos']
            xb = data['start']
            xe = data['end']
            x = int((xe + xb) / 2.)

            node_labels[node] = (x, y)
            xs.extend([xb, xe])
            ys.append(y)

            nodes_by_height[data['pos']] = node
            node_xs_by_y[data['pos']] = x
            node_xs_ys[node] = (x, y)
            node_lefts_rights[node] = (xb, xe)

        lines = []

        rightmost_x = n.max(xs)
        leftmost_x = n.min(xs)
        x_span = rightmost_x - leftmost_x
        safe_yshift = 0.5 / x_span

        extra_x_shifts = []

        for n1, n2, data in g.edges(data=True):
            x = data['pos']
            yb = data['start']
            ye = data['end']

            start_node = nodes_by_height[yb]
            end_node = nodes_by_height[ye]
            if start_node >= len(self) and end_node >= len(self):
                continue

            start_left, start_right = node_lefts_rights[start_node]
            end_left, end_right = node_lefts_rights[end_node]

            start_frac = n.abs((x - start_left) / (start_right - start_left) -
                               0.5)
            start_frac = 0.5 - start_frac
            if True:  # ye < ys:  # This always evaluated to True - a bug?
                start_frac *= -1
            start_shift = start_frac

            end_frac = n.abs((x - end_left) / (end_right - end_left) - 0.5)
            end_frac = 0.5 - end_frac
            if False:  # ye > ys:  # This always evaluated to False - a bug?
                end_frac *= -1
            end_shift = end_frac

            start_node_x = node_xs_by_y[yb]
            start_node_y = yb

            end_node_x = node_xs_by_y[ye]
            end_node_y = ye

            line = n.array([[start_node_x, start_node_y],
                            [x, start_node_y - start_shift],
                            [x, end_node_y - end_shift],
                            [end_node_x, end_node_y]])
            if x == start_node_x:
                line = line[1:]
                line[0, 1] = start_node_y
            if x == end_node_x:
                line = line[:-1]
                line[-1, 1] = end_node_y
            lines.append(line)

            if sorted((n1, n2)) in duplicates:
                line = line.copy()
                n1x, n1y = node_xs_ys[n1]
                n2x, n2y = node_xs_ys[n2]

                lx, hx = sorted([n1x, n2x])
                ly, hy = sorted([n1y, n2y])
                if len(line) == 4:
                    join_1 = n.array([line[2, 0], line[2, 1], 0]) - n.array(
                        [line[0, 0], line[0, 1], 0])
                    normal_1 = n.cross(join_1, [0, 0, 1])[:2]
                    normal_1 /= n.linalg.norm(normal_1)

                    join_2 = n.array([line[3, 0], line[3, 1], 0]) - n.array(
                        [line[1, 0], line[1, 1], 0])
                    normal_2 = n.cross(join_2, [0, 0, 1])[:2]
                    normal_2 /= n.linalg.norm(normal_2)

                    extra_x_shifts.append(line[1][0] + 0.005 * normal_1[0])

                    line[1] += 0.01 * normal_1
                    line[2] += 0.01 * normal_2

                elif len(line) == 3:
                    join_1 = n.array([line[2, 0], line[2, 1], 0]) - n.array(
                        [line[0, 0], line[0, 1], 0])
                    normal_1 = n.cross(join_1, [0, 0, 1])[:2]
                    normal_1 /= n.linalg.norm(normal_1)

                    extra_x_shifts.append(line[1][0] + 0.005 * normal_1[0])

                    line[1] += 0.01 * normal_1
                elif len(line) == 2:
                    join_1 = n.array([line[1, 0], line[1, 1], 0]) - n.array(
                        [line[0, 0], line[0, 1], 0])
                    normal_1 = n.cross(join_1, [0, 0, 1])[:2]
                    normal_1 /= n.linalg.norm(normal_1)

                    line = n.vstack([
                        line[0],
                        line[0] + 0.5 * (line[1] - line[0]) + 0.01 * normal_1,
                        line[1]
                    ])

                    extra_x_shifts.append(line[1][0] - 0.005 * normal_1[0])

                lines.append(line)

        extra_x_shifts = sorted(extra_x_shifts)[::-1]

        return g, lines, node_labels, nodes_by_height, (
            leftmost_x, rightmost_x), first_edge, heights, extra_x_shifts
Beispiel #15
0
def pgraph_graph(graph):
    """Return pgraph graph built from NetworkX graph."""
    return planarity.PGraph(graph)
Beispiel #16
0
def kuratowski_edges(graph):
    """Return edges of forbidden subgraph of non-planar graph."""
    return planarity.PGraph(graph).kuratowski_edges()
Beispiel #17
0
def is_planar(graph):
    """Test planarity of graph."""
    return planarity.PGraph(graph).is_planar()
Beispiel #18
0
def mapping(graph):
    """Return dictionary of internal mapping of nodes to integers."""
    return planarity.PGraph(graph).mapping()
Beispiel #19
0
 def test_is_planar_adj_input(self):
     P = planarity.PGraph(self.p4_adj)
     assert_true(P.is_planar())
     P = planarity.PGraph(self.k5_adj)
     assert_false(P.is_planar())
Beispiel #20
0
def ascii(graph):
    """Draw text representation of a planar graph."""
    return planarity.PGraph(graph).ascii()