我在python中从http://www.dis.uniroma1.it/challenge9/download.shtml读取http://www.dis.uniroma1.it/challenge9/data/rome/rome99.gr等图形 . 例如,使用此代码 .
#!/usr/bin/python
from igraph import *
fname = "rome99.gr"
g = Graph.Read_DIMACS(fname, directed=True )
(我需要将“p sp 3353 8870”“更改为”p max 3353 8870“以使用igraph来实现此功能 . )
我想将图形转换为所有节点都具有1度(除了允许添加的额外零权重边缘除外)但仍保留所有最短路径的图形 . 这是原始图中两个节点之间的路径应该是新图中的最短路径,当且仅当它是转换图中的最短路径时 . 我会在一个例子后再详细解释一下 .
一种方法,我想是用v.outdegree(mode = OUT)节点用一个小的线性子图替换每个节点v . 在子图中,节点通过零权重边缘依次连接 . 然后,我们将子图中的节点连接到我们创建的其他小子图中的第一个节点 .
我不介意使用igraph或networkx执行此任务,但我仍然坚持使用如何执行此操作的语法 .
例如,如果我们从图G开始:
我想将其转换为图H:
由于第二个图比第一个图有更多的节点,我们需要通过它具有与第一个图相同的最短路径来定义我们的意思 . 我只考虑用标记为X1的节点的简单字母标记的节点之间的路径 . 换句话说,在此示例中,路径不能在A2或B2中开始或结束 . 我们还在考虑路径时合并节点的所有版本 . 因此,H中的路径A1-> A2-> D被认为与G中的A-> D相同 .
这是我有多远 . 首先,我将零权重边添加到新图中
h = Graph(g.ecount(), directed=True)
#Connect the nodes with zero weight edges
gtoh = [0]*g.vcount()
i=0
for v in g.vs:
gtoh[v.index] = i
if (v.degree(mode=OUT) > 1):
for j in xrange(v.degree(mode=OUT)-1):
h.add_edge(i,i+1, weight = 0)
i = i+1
i = i + 1
然后我添加主边
#Now connect the nodes to the relevant "head" nodes.
for v in g.vs:
h_v_index = gtoh[v.index]
i = 0
for neighbour in g.neighbors(v, mode=OUT):
h.add_edge(gtoh[v.index]+i,gtoh[neighbour], weight = g.es[g.get_eid(v.index, neighbour)]["weight"])
i = i +1
这样做有更好/更好的方法吗?我觉得一定有 .
1 回答
以下代码应该在
igraph
和Python 2.x中工作;基本上它完成你提出的建议:它为图中的每个单个节点创建一个"linear subgraph",并将一个外出边连接到与旧节点对应的线性子图中的每个节点 .