如何在Snap.py中复制Graph对象?

时间:2014-04-17 12:39:42

标签: python snappy

我尝试使用copy.deepcopy(graph),但收到错误:

我的代码:

new_graph = TNEANet.New()
....
# some define for new_graph
....
copy_graph = copy.deepcopy(new_graph)

执行错误:

TypeError: object.__new__(SwigPyObject) is not safe, use SwigPyObject.__new__()

我还发现API有一个定义API Document。所以我尝试使用TNEANet(Graph)来执行该任务:

new_graph = TNEANet.New()
....
# some define for new_graph
....
copy_graph = TNEANet(new_graph)

执行错误:

TypeError: in method 'new_TNEANet', argument 1 of type 'TSIn &'

2 个答案:

答案 0 :(得分:2)

简短回答

最好的办法是自己复制节点,边缘和属性。我发现转储到文件并重新加载也很有效,尽管如果你使用PNEANet它不会复制你的属性。这是我用来复制图形的一个方便的函数(比迭代更快):

def copy_graph(graph):
    tmpfile = '.copy.bin'

    # Saving to tmp file
    FOut = snap.TFOut(tmpfile)
    graph.Save(FOut)
    FOut.Flush()

    # Loading to new graph
    FIn = snap.TFIn(tmpfile)
    graphtype = type(graph)
    new_graph = graphtype.New()
    new_graph = new_graph.Load(FIn)

    return new_graph

答案很长

有一种方法可以深度复制图表:

import snap
new_graph = snap.TNEANet.New()
....
# some define for new_graph
....
copy_graph = snap.TNEANet(new_graph())

(适用于任何类型的图表) 问题是,当我们需要snap.TNEANet时,它会返回snap.PNEANet。后者只是C ++实现中指向前者的指针,但是我们无法在Python中创建这个指针。因此,copy_graph的功能将少于new_graph

<强>解释相关

SNAP正在使用python的代理表示,这在某种程度上使深层复制过程变得复杂。复制构造函数期望非代理类型,并且您将为其提供python代理类型。 引发TypeError,显示第一个构造函数的签名,其中包含一个它知道的参数(这与此完全无关)。

要解决这个问题,我们需要为构造函数提供使用self.__call__()方法获得的基础C ++类型。

但由于C ++(不好?)实现,snap.TNEANet(new_graph())输出snap.TNEANet。这意味着此函数的输出将是非代理类型。因此,它无法使用大多数SNAP功能......

答案 1 :(得分:1)

您可以使用ConvertGraph方法复制图表。只需使用相同类型的图表作为目标类型:

graph = snap.TNEANet.New()

graph.AddNode(1)
graph.AddNode(2)
graph.AddEdge(1,2)

copy_graph = snap.ConvertGraph(type(graph), graph)