![](/img/trans.png)
[英]NetworkX DiGraph() to Graph() with edge weights not summed, how to sum weights?
[英]how to add float typed weights to an retworkx digraph
在我追求 python 的快速圖形庫之后,我偶然發現了reworkx ,我正在嘗試實現與使用networkx相同的(期望的)結果。
在我的networkx代碼中,我用一組加權邊實例化了一個有向圖object,激活它的內置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)
所以我應該不會失去重量的細微之處 - 沒有引發錯誤,但最短路徑的 output 與我使用 networkx 時得到的不同。
我知道權重不一定是這里的問題,但它們目前是我的主要嫌疑人。
謝天謝地,任何其他建議都會被接受。
在不知道代碼片段中包含的in_node_indices
、 out_node_indices
和weights_matrix
的情況下,很難為您的用例提供准確的工作示例。 但是,我可以根據錯誤消息進行猜測。 我認為您在這里遇到的問題很可能是因為您嘗試使用in_node_indices
和out_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()
時,您需要 map 輸入數組中 position 的值到從同一 position 的方法返回的索引,以識別圖中的節點。 我想如果你這樣做:
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])
我沒有測試上面的代碼片段(所以可能有錯別字或其他問題),因為我不知道in_node_indices
、 out_node_indices
和weight_matrix
的內容是什么。 但它應該讓您更好地了解我上面描述的內容。
話雖如此,我確實想知道weight_matrix
是否是鄰接矩陣,如果是,那么這樣做可能更容易:
import retworkx
graph = retworkx.PyDiGraph.from_adjacency_matrix(weight_matrix)
this is also typically faster (assuming you already have the matrix) because it uses the numpy C api and avoids the type conversion going between python and rust and all the pre-processing steps.
最近在 retworkx 問題跟蹤器中還打開了一個類似的問題: https://github.com/Qiskit/retworkx/issues/546 。 我的回復包含有關 reworkx 內部的更多詳細信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.