【问题标题】:how to add float typed weights to an retworkx digraph如何将浮点类型的权重添加到 retworkx 有向图
【发布时间】:2022-01-06 13:55:27
【问题描述】:

在追求 python 的快速图形库的过程中,我偶然发现了retworkx, 我正在尝试达到与使用networkx 相同的(期望的)结果。

在我的 networkx 代码中,我用一组加权边实例化了一个有向图对象, 激活它的内置 shortest_path(基于 dijkstra),并接收该路径。我通过使用以下代码来做到这一点:

graph = nx.DiGraph()
in_out_weight_triplets = np.concatenate((in_node_indices, out_node_indices,
                                         np.abs(weights_matrix)), axis=1)
graph.add_weighted_edges_from(in_out_weight_triplets)
shortest_path = nx.algorithms.shortest_path(graph, source=n_nodes, target=n_nodes + 1,
                                            weight='weight')

当尝试使用 reworkx 重现相同的最短路径时:

graph = rx.PyDiGraph(multigraph=False)
in_out_weight_triplets = np.concatenate((in_node_indices.astype(int), 
                                         out_node_indices.astype(int),
                                         np.abs(weights_matrix)), axis=1)
unique_nodes = np.unique([in_node_indices.astype(int), out_node_indices.astype(int)])
graph.add_nodes_from(unique_nodes)
graph.extend_from_weighted_edge_list(list(map(tuple, in_out_weight_triplets)))
shortest_path = rx.digraph_dijkstra_shortest_paths(graph, source=n_nodes,
                                                   target=n_nodes + 1)

但是对于使用带有浮动权重的三元组,我得到了错误:

"C:\Users\tomer.d\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py",
line 3437, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)   File "<ipython-input-23-752a42ce79d7>", line 1, in <module>
    graph.extend_from_weighted_edge_list(list(map(tuple, in_out_weight_triplets))) TypeError: argument 'edge_list':
'numpy.float64' object cannot be interpreted as an integer ```

当我尝试将权重乘以 10^4 并将它们转换为整数的解决方法时:

np.concatenate((in_node_indices.astype(int), out_node_indices.astype(int),
               (np.abs(weights_matrix) * 10000).astype(int), axis=1)

所以我应该不会减轻体重的微妙之处 - 不会引发错误, 但是最短路径的输出与我使用networkx时得到的不同。

我知道权重不一定是这里的问题, 但他们目前是我的主要嫌疑人。

任何其他建议都会被接受。

【问题讨论】:

    标签: python python-3.x networkx shortest-path digraphs


    【解决方案1】:

    如果不知道 in_node_indicesout_node_indicesweights_matrix 在代码 sn-ps 中包含什么,很难为您的用例提供一个准确的工作示例。但是,我可以根据错误消息进行猜测。我认为您在这里遇到的问题很可能是因为您尝试使用 in_node_indicesout_node_indices 中的值作为 retworkx 索引,但不一定是 1:1 映射。节点的 reworkx 索引是在添加节点时分配的,是返回值。因此,如果您执行graph.add_node(3) 之类的操作,则返回的不一定是3,它将是分配给3 实例的节点索引,当它作为节点添加到图中时。如果你运行graph.add_nodes_from([3, 3]),你会得到两个不同的索引返回。这与 networkx 将数据有效负载视为图中的查找键不同(因此 graph.add_node(3) 将节点 3 添加到您通过 3 查找的图中,但是您只能有一个节点有效载荷3)。您可以在此处参考有关 networkx 用户的 reworkx 文档以获取更多详细信息:https://qiskit.org/documentation/retworkx/networkx.html

    因此,当您调用add_nodes_from() 时,您需要将输入数组中某个位置的值映射到同一位置的方法返回的索引,以识别图中的该节点。我想如果你这样做:

    import retworkx as rx
    graph = rx.PyDiGraph(multigraph=False)
    unique_indices = np.unique([in_node_indices, out_node_indices])
    rx_indices = graph.add_nodes_from(unique_indices)
    index_map = dict(zip(unique_indices, rx_indices))
    in_out_weight_triplets = np.concatenate((in_node_indices, out_node_indices,
                                             np.abs(weights_matrix)), axis=1)
    graph.add_nodes_from([(index_map[in], index_map[out], weight) for in, out, weight in in_out_weight_triplets])
    

    我没有测试过上面的sn-p(所以可能有错别字或其他问题)因为我不知道in_node_indicesout_node_indicesweight_matrix的内容是什么。但它应该能让您更好地了解我上面描述的内容。

    话虽如此,我确实想知道weight_matrix 是否是adjacency matrix,如果是,那么这样做可能更容易:

    import retworkx
    
    graph = retworkx.PyDiGraph.from_adjacency_matrix(weight_matrix)
    

    这通常也更快(假设您已经拥有矩阵),因为它使用 numpy C api 并避免了 python 和 rust 之间的类型转换以及所有预处理步骤。

    最近在 retworkx 问题跟踪器中还打开了一个与此类似的问题:https://github.com/Qiskit/retworkx/issues/546。我的回复包含有关 reworkx 内部的更多详细信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多