Кенигсбергские мосты с использованием Networkx

Я пытаюсь построить график известной проблемы Кенигсбергских мостов, используя NetworkX и Python 3.8.

введите здесь описание изображения

Этот код я использую:

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?


person DieDauphin    schedule 26.06.2020    source источник
comment
Чтобы смоделировать ситуацию, вам нужно будет использовать объект MultiGraph, а не объект Graph. Это работает с точки зрения моделирования, но, к сожалению, простая замена nx.Graph на nx.MultiGraph не приводит к лучшему графику (хотя приводит к лучшей структуре данных). Алгоритмы построения NetworkX, кажется, сворачивают параллельные ребра в отдельные ребра. См. этот вопрос для получения дополнительной информации.   -  person John Coleman    schedule 26.06.2020
comment
Вы должны быть в состоянии воспроизвести определение MultiGraph и экспорт в точечный файл, см. пример здесь   -  person yatu    schedule 26.06.2020


Ответы (1)


Чтобы расширить комментарии, вам понадобится 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)

введите здесь описание изображения

person yatu    schedule 26.06.2020
comment
отлично, но просто суетливый вопрос: нельзя ли расположить узлы так, чтобы они выглядели точно так же, как в обычном графе, который используется при изучении этой проблемы? Я знаю, что оба графа представляют одно и то же, и в теории графов они на самом деле одинаковы, но я хотел знать, можно ли расположить узлы так, как хотелось бы, имея эту дополнительную настройку. - person DieDauphin; 27.06.2020
comment
Никогда не делал ничего подобного. Я думаю, вы должны иметь возможность использовать graphviz, см. stackoverflow.com/questions/5343899/ @DieDauphin - person yatu; 27.06.2020