使用 Networkx 的 Königsberg 桥梁

Königsberg Bridges using Networkx

我正在尝试使用 NetworkX 和 Python 3.8

绘制著名的 Königsberg Bridges 问题的图表

这是我正在使用的代码:

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np

G=nx.Graph()

G.add_node(1)  ## Land A
G.add_node(2)  ## Land B
G.add_node(3)  ## Land C
G.add_node(4)  ## Land D

## Connected Edges
G.add_edge(1,3,color='r',weight=1)  ## Bridge 1
G.add_edge(1,3,color='r',weight=1)  ## Bridge 2
G.add_edge(1,4,color='r',weight=1)  ## Bridge 3
G.add_edge(3,4,color='r',weight=1)  ## Bridge 4
G.add_edge(1,2,color='r',weight=1)  ## Bridge 5
G.add_edge(1,2,color='r',weight=1)  ## Bridge 6
G.add_edge(2,4,color='r',weight=1)  ## Bridge 7


colors = nx.get_edge_attributes(G,'color').values()
weights = nx.get_edge_attributes(G,'weight').values()

names = {1:"Land A",2:"Land B",3:"Land C",4:"Land D"}
H=nx.relabel_nodes(G,names)

pos = nx.circular_layout(H)
nx.draw_networkx(H,pos,edge_color=colors,width=list(weights))

plt.savefig("konigsberg_bridges_graph.png")
plt.show()

生成的图是这个:

问题是与互联网上出现的图表有很大不同:

我怎样才能使用 NetworkX 制作类似于那个图表的图表?

要扩展注释,您需要 MultiGraph 用于两个节点之间的多个边:

G=nx.MultiGraph()

G.add_node(1)  ## Land A
G.add_node(2)  ## Land B
G.add_node(3)  ## Land C
G.add_node(4)  ## Land D

## Connected Edges
G.add_edge(1,3,color='r',weight=1)  ## Bridge 1
G.add_edge(1,3,color='r',weight=1)  ## Bridge 2
G.add_edge(1,4,color='r',weight=1)  ## Bridge 3
G.add_edge(3,4,color='r',weight=1)  ## Bridge 4
G.add_edge(1,2,color='r',weight=1)  ## Bridge 5
G.add_edge(1,2,color='r',weight=1)  ## Bridge 6
G.add_edge(2,4,color='r',weight=1)  ## Bridge 7

colors = nx.get_edge_attributes(G,'color').values()
weights = nx.get_edge_attributes(G,'weight').values()

names = {1:"Land A",2:"Land B",3:"Land C",4:"Land D"}
H=nx.relabel_nodes(G,names)

要可视化网络,您可以使用显示平行边的 Graphviz。您可以在 dot 中编写图表并使用 graphviz.Source:

显示图表
path = 'multig.dot'
nx_pydot.write_dot(H, path)
Source.from_file(path)

我不确定这是否算作答案,但我发现使用 LaTeX 和 TikZ 绘制柯尼斯堡桥图更容易

这是代码:

\documentclass{article} 
\usepackage{tikz} 

\begin{document} 

    \begin{tikzpicture}[thick, main/.style = {draw, circle}] 
        \node[main,scale=0.6, label=left:$a$] (a) at (0,0) {}; 
        \node[main,scale=0.6, label=left:$b$] (b) at (0,2) {}; 
        \node[main,scale=0.6, label=left:$c$] (c) at (0,4) {}; 
        \node[main,scale=0.6, label=right:$d$] (d) at (4,2) {}; 
        
        \draw (a) -- (d);
        \draw (b) -- (d);
        \draw (c) -- (d);
        \draw (a) to [out=120,in=240,looseness=1] (b);
        \draw (a) to [out=60,in=300,looseness=1] (b);
        
        \draw (b) to [out=120,in=240,looseness=1] (c);
        \draw (b) to [out=60,in=300,looseness=1] (c);

    \end{tikzpicture} 

\end{document}

结果图像是:

也可以使用python创建一个tex文件,这样也可以使用NetworkX,这是代码:

import os
import networkx as nx

G=nx.Graph()

G.add_node('1', land="a")  ## Land A
G.add_node('2', land="b")  ## Land B
G.add_node('3', land="c")  ## Land C
G.add_node('4', land="d")  ## Land D

## Connected Edges
G.add_edge(1, 3)  ## Bridge 1
G.add_edge(1, 3)  ## Bridge 2
G.add_edge(1, 4)  ## Bridge 3
G.add_edge(3, 4)  ## Bridge 4
G.add_edge(1, 2)  ## Bridge 5
G.add_edge(1, 2)  ## Bridge 6
G.add_edge(2, 4)  ## Bridge 7

with open('konigsberg.tex','w') as file:
     file.write('\documentclass[margin=1mm]{standalone}\n')
     file.write('\usepackage{tikz} \n')
     file.write('\begin{document}\n')
     file.write('\begin{tikzpicture}[thick, main/.style = {draw, circle}] \n')
     file.write('\node[main,scale=0.6, label=left:$' + G.nodes['1']['land'] + '$] (' + G.nodes['1']['land'] + ') at (0,0) {}; \n')
     file.write('\node[main,scale=0.6, label=left:$' + G.nodes['2']['land'] + '$] (' + G.nodes['2']['land'] + ') at (0,2) {}; \n')
     file.write('\node[main,scale=0.6, label=left:$' + G.nodes['3']['land'] + '$] (' + G.nodes['3']['land'] + ') at (0,4) {}; \n')
     file.write('\node[main,scale=0.6, label=right:$' + G.nodes['4']['land'] + '$] (' + G.nodes['4']['land'] + ') at (4,2) {}; \n')
     file.write('\draw (' + G.nodes['1']['land'] + ') -- (' + G.nodes['4']['land'] + '); \n')
     file.write('\draw (' + G.nodes['2']['land'] + ') -- (' + G.nodes['4']['land'] + '); \n')
     file.write('\draw (' + G.nodes['3']['land'] + ') -- (' + G.nodes['4']['land'] + '); \n')
     file.write('\draw (' + G.nodes['1']['land'] + ') to [out=120,in=240,looseness=1] (' + G.nodes['2']['land'] + '); \n')
     file.write('\draw (' + G.nodes['1']['land'] + ') to [out=60,in=300,looseness=1] (' + G.nodes['2']['land'] + '); \n')
     file.write('\draw (' + G.nodes['2']['land'] + ') to [out=120,in=240,looseness=1] (' + G.nodes['3']['land'] + '); \n')
     file.write('\draw (' + G.nodes['2']['land'] + ') to [out=60,in=300,looseness=1] (' + G.nodes['3']['land'] + '); \n')
     file.write('\end{tikzpicture}  \n')
     file.write('\end{document}\n')

os.system("pdflatex konigsberg.tex") 

运行 此代码使用 Python3 和 Ubuntu 20.04 生成相同的图