[英]python graph inversion/reversal
你好,stackoverflowians,
我正在嘗試實現 kosaraju 的算法,這需要反轉 og 定向(在我的情況下是加權)圖。 我已經使用邊緣列表和原始類型成功地處理了這個問題(如果那是 python 的術語,請原諒,如果這在技術上是不正確的)。 但是,我在使用鄰接列表時遇到了問題
嘗試創建具有結構 { node.val : GraphNode } 的字典,並根據需要附加到字典內的 GraphNode 鄰居。 然后,設置 Graph 的節點列表 = dict.values()
可能是我定義結構的方式,可能會忽略代碼中明顯的內容,可能是我的 python 無能顯示,idk。 雖然我很接近發脾氣
我想我涵蓋了我的所有基礎並在下面提供了代碼,但如果需要更多細節,請聯系我。 提前感謝,非常感謝
class GraphNode:
def __init__(self,val,neighbors=[]) -> None:
self.val = val
self.neighbors = neighbors
class Graph:
def __init__(self, nodes=[]) -> None:
self.nodes = nodes
def invert_graph(self):
visited_edge_set = set()
node_map = {}
def dfs(node: GraphNode):
if node.val not in node_map:
node_map[node.val] = GraphNode(node.val)
new_end_node = node_map[node.val]
for (neigh,weight) in node.neighbors:
if (neigh.val,node.val) in visited_edge_set or (node.val,neigh.val) in visited_edge_set:
continue
visited_edge_set.add((neigh.val,node.val))
if neigh.val not in node_map:
node_map[neigh.val] = GraphNode(neigh.val)
new_start_node = node_map[neigh.val]
new_start_node.neighbors.append((new_end_node, weight))
dfs(neigh)
for node in self.nodes:
node.val not in node_map and dfs(node)
self.nodes = node_map.values()
if __name__ == "__main__":
zero = GraphNode(0)
one = GraphNode(1)
two = GraphNode(2)
three = GraphNode(3)
four = GraphNode(4)
five = GraphNode(5)
six = GraphNode(6)
zero.neighbors = [(two, 2), (four, 3)]
one.neighbors = [(three, 1)]
two.neighbors = [(six, 6)]
three.neighbors = [(four, 4)]
four.neighbors = [(one, 1), (six, 4)]
six.neighbors = [(five, 2)]
arr = [zero,one,two,three,four,five,six]
g = Graph(arr)
g.invert_graph()
通常,不需要 DFS 來反轉圖形。 相反,在偽代碼中,將G
轉換為H
:
for every vertex v in G:
for every edge (to, len) from v in G:
add edge (v, len) from to in H
最初, H
將具有與G
相同的所有頂點,但沒有邊。
也許構造一個新的圖H
比改變現有的圖G
意義。
兩個問題:
你得到錯誤的原因是結果是你的構造函數的neighbors
默認值發生了變化。 這是Python 中的一個典型“功能” ,其中參數的默認值只計算一次,而不是在實際調用時。 因此,將該構造函數更改為:
class GraphNode: def __init__(self,val,neighbors=None) -> None: self.val = val self.neighbors = neighbors or []
該算法過於復雜。 無需對圖進行深度優先遍歷。 可以按任何順序訪問邊,因此不需要遞歸,也不需要“已訪問”的概念。 您甚至可以不創建新節點,只需在neighbors
列表中添加一個分隔符,然后在該分隔符之后添加新邊,最終刪除該列表中的所有邊直到分隔符。
def invert_graph(self): for node in self.nodes: node.neighbors.append((None, 0)) # separator for node in self.nodes: for i, (neighbor, weight) in enumerate(node.neighbors): if neighbor is None: # Separator del node.neighbors[:i + 1] # Remove original edges break neighbor.neighbors.append((node, weight))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.