Создание графика, где разные узлы имеют одинаковую метку? - PullRequest
0 голосов
/ 17 июня 2019

Давайте возьмем базовый график в networkx:

import networkx as nx
G = nx.Graph()
G.add_node("A")
G.add_node("B")
G.add_edge("A","B")

Экспорт в формате gml дает:

graph [
  node [
    id 0
    label "A"
  ]
  node [
    id 1
    label "B"
  ]
  edge [
    source 0
    target 1
  ]
]

Теперь мне интересно, есть ли способ иметь два разных узла с одинаковым именем, чтобы мой gml-файл выглядел так:

graph [
  node [
    id 0
    label "A"
  ]
  node [
    id 1
    label "A"
  ]
  edge [
    source 0
    target 1
  ]
]

По крайней мере, в файле номера идентификаторов различны, и поэтому узлы однозначно идентифицируются даже с одинаковыми именами. Этот файл можно открыть с помощью yEd без проблем.

Судя по синтаксису, я полагаю, что это невозможно в networkx, так какие еще есть способы сделать это?

Справочная информация:

У меня есть ориентированный граф, где два узла X и Y оба имеют одного и того же преемника Z, но я хочу, чтобы X и Y каждый имели свои собственные Z вместо того, чтобы оба указывали на то же самое Z. По сути, я хочу направленное дерево, где у каждого узла есть только один предшественник, в то время как дубликаты в дереве разрешены.

1 Ответ

1 голос
/ 17 июня 2019

Да, это возможно.Вам нужно определить свою собственную функцию, которая будет принимать узел в качестве входных данных и выводить его метку в виде строки.Это что-то вроде хака, так как функция действительно предназначена для создания строки, которая служит меткой в ​​случае, если у узла нет метки, которая автоматически преобразуется в строку.Но это работает.

import networkx as nx
G = nx.Graph()
G.add_edge('a', 'b')
G.add_edge('b','c')

def stringizer(x):  #replaces both 'a' and 'b' with 'a'
   if x == 'a':
       return 'a'
   elif x == 'b':
       return 'a'
   else:
       return x

nx.write_gml(G, path='tmp.gml', stringizer=stringizer)

На выходе оба узла 'a' и 'b' получают метку 'a'.

graph [
  node [
    id 0
    label "a"
  ]
  node [
    id 1
    label "a"
  ]
  node [
    id 2
    label "c"
  ]
  edge [
    source 0
    target 1
  ]
  edge [
    source 1
    target 2
  ]
]

Одним из способов сделать это на практике было бысоздать словарь D[node], который дает метку, а затем определить

def stringizer(node):
    return D[node]
...