Python,networkx

Pyt*_*hon 12 python graph networkx

我需要帮助,因为我不是编程方面的专家.

对于具有n个节点和E边缘的给定图形,如何绘制平面图形(如果图形可以在平面中绘制,使得没有边缘交叉,则称为平面图形).然后翻转边缘以获得另一个平面图.(循环直到我们获得所有可能性).

在此先感谢,我感谢您的帮助.

PY


>>>#visualize with pygraphviz
    A=pgv.AGraph()
    File "<stdin>", line 6
    A=pgv.AGraph()
    ^
    SyntaxError: invalid syntax
>>> A.add_edges_from(G.edges())
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    NameError: name 'A' is not defined
>>> A.layout(prog='dot')
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    NameError: name 'A' is not defined
>>> A.draw('planar.png')
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    NameError: name 'A' is not defined
Run Code Online (Sandbox Code Playgroud)

Max*_* Li 22

您的问题涉及几个硬计算问题.

一,一些理论.如果图G是平面的,那么G的每个子图都是平面的.从G(具有e边缘)翻转边缘将给出2^e-1平面子图(如果我们不关心连通性),这是指数的(即巨大的和"坏的").也许,你想找到"最大的"平面子图.

如果你想绘制平面图也看起来像平面计算难度,即知道存在边缘不交叉的图形表示而另一个找到这样的表示是一回事.

实施.似乎networkx没有检查图形是否为平面的功能.使用图形的一些其他包具有(例如,sage具有g.is_planar()函数,其中g是图形对象).下面,我基于Kuratowski定理,用networkx写了一个"天真"(必须有更有效的方法)平面性检查.

import pygraphviz as pgv
import networkx as nx
import itertools as it
from networkx.algorithms import bipartite

def is_planar(G):
    """
    function checks if graph G has K(5) or K(3,3) as minors,
    returns True /False on planarity and nodes of "bad_minor"
    """
    result=True
    bad_minor=[]
    n=len(G.nodes())
    if n>5:
        for subnodes in it.combinations(G.nodes(),6):
            subG=G.subgraph(subnodes)
            if bipartite.is_bipartite(G):# check if the graph G has a subgraph K(3,3)
                X, Y = bipartite.sets(G)
                if len(X)==3:
                    result=False
                    bad_minor=subnodes
    if n>4 and result:
        for subnodes in it.combinations(G.nodes(),5):
            subG=G.subgraph(subnodes)
            if len(subG.edges())==10:# check if the graph G has a subgraph K(5)
                result=False
                bad_minor=subnodes
    return result,bad_minor

#create random planar graph with n nodes and p probability of growing
n=8
p=0.6
while True:
    G=nx.gnp_random_graph(n,p)
    if is_planar(G)[0]:
        break
#visualize with pygraphviz
A=pgv.AGraph()
A.add_edges_from(G.edges())
A.layout(prog='dot')
A.draw('planar.png')
Run Code Online (Sandbox Code Playgroud)

Edit2.如果您遇到pygraphviz的问题,尝试使用networkx绘图,也许您会发现结果正常.因此,请尝试以下方法,而不是"使用pygraphviz可视化"块.

import matplotlib.pyplot as plt
nx.draw(G)
# comment the line above and uncomment one of the 3 lines below (try each of them):
#nx.draw_random(G)
#nx.draw_circular(G)
#nx.draw_spectral(G)
plt.show()
Run Code Online (Sandbox Code Playgroud)

编辑结束2.

结果看起来像这样.随机平面图

你看到图片上有一个交叉点(但是图形是平面的),它实际上是一个很好的结果(不要忘记问题在计算上很难),pygraphviz是Graphviz的一个使用启发式算法的包装器.在该行中,A.layout(prog='dot')您可以尝试将'dot'替换为'twopi','neato','circo'等,以确定您是否实现了更好的可视化效果.

编辑.我们还要考虑你对平面子图的问题.让我们生成一个非平面图:

while True:
    J=nx.gnp_random_graph(n,p)
    if is_planar(J)[0]==False:
        break
Run Code Online (Sandbox Code Playgroud)

我认为找到平面子图的最有效方法是从"坏小"中消除节点(即K(5)或K(3,3)).这是我的实现:

def find_planar_subgraph(G):
    if len(G)<3:
        return G
    else:
        is_planar_boolean,bad_minor=is_planar(G)
        if is_planar_boolean:
            return G
        else:
            G.remove_node(bad_minor[0])
            return find_planar_subgraph(G)
Run Code Online (Sandbox Code Playgroud)

行动:

L=find_planar_subgraph(J)
is_planar(L)[0]
>> True
Run Code Online (Sandbox Code Playgroud)

现在你有一个非平面图G的平面子图L(networkx图形对象).

  • 可能是我见过的最好的答案之一...干得好 (4认同)
  • 计算平面图的嵌入可以在线性时间内完成.参见例如[Hopcroft,Tarjan '74](http://dx.doi.org/10.1145%2F321850.321852).嵌入非平面图以使边缘交叉的数量最小化是很困难的. (4认同)
  • [平面测试](http://en.wikipedia.org/wiki/Planarity_testing)并不难。 (2认同)
  • Max是正确的,NetworkX不包含平面度测试和绘图的代码.但Boyer的C平面度代码有一个包装器,它可以平滑地与NetworkX互操作,并包含is_planar()和绘图函数.有关代码,请参阅https://bitbucket.org/hagberg/nxtools-planarity,特别是https://bitbucket.org/hagberg/nxtools-planarity/src/ee97b7dc9807/examples上的示例 (2认同)
  • 抱歉,但是这个答案是错误的,我不理解很多投票。首先,正如其他人已经指出的那样,发现平面嵌入可以在线性时间内完成,并且在计算上并不困难。第二,正如其他人已经指出的那样,您的算法仅检查K5和K3,3子图,而不检查平面性所需的K5和K3,3小调。请编辑您的答案,以免混淆未来的读者!!! (2认同)