簡體   English   中英

在 python 圖形數據結構中找到所有可能的路徑而不使用遞歸 function

[英]Find all possible paths in a python graph data structure without using recursive function

在我的 csv 文件中查找所有可能的路徑時遇到一個嚴重的問題,如下所示:

資源 目標 源代碼庫 目標倉庫
來源1 目標2 回購-1 回購-2
來源5 目標3 回購5 回購3
來源8 目標5 回購8 回購5

數據集中有大量的行,超過 5000 行。 我想像這樣生成所有可能的路徑並返回一個列表(Target5 等於 SOURCE5):

  • 源 1 目標 2
  • SOURCE8 目標 5 目標 3

我想在不使用遞歸函數的情況下實現此解決方案,因為會導致問題(超出最大遞歸深度)。

這是當前的代碼示例:

def attach_co_changing_components(base_component):
    co_changes = df_depends_on.loc[df_depends_on["Source_repo"] ==
                                   base_component, "Target_repo"].values
    result = {base_component: list(co_changes)}
    return result


def dfs(data, path, paths):
    datum = path[-1]
    if datum in data:
        for val in data[datum]:
            new_path = path + [val]
            paths = dfs(data, new_path, paths)
    else:
        paths += [path]
    return paths



def enumerate_paths(graph, nodes=[]):
    nodes = graph.keys()
    all_paths = []
    for node in nodes:
        node_paths = dfs(graph, [node], [])
        all_paths += node_paths
    return all_paths


if __name__ == "__main__":

    df = pd.read_csv("clean_openstack_evolution.csv")

    co_changing_components = df[["Source"]].copy()

    co_changing_components = co_changing_components.drop_duplicates(
    ).reset_index(drop=True)

    co_changing_components = co_changing_components["Source"].map(
        attach_co_changing_components)

    co_changing_components = co_changing_components.rename("Path")

    co_changing_components = co_changing_components.reset_index(drop=True)

    newdict = {}
    for k, v in [(key, d[key]) for d in co_changing_components for key in d]:
        if k not in newdict: newdict[k] = v
        else: newdict[k].append(v)

    graph_keys = df_depends_on["Source_repo"].drop_duplicates().to_dict(
    ).values()
    graph_keys = {*graph_keys}
    graph_keys = set([
        k for k in graph_keys
        if len(df_depends_on[df_depends_on["Target"] == k]) > 0
    ])

    result = enumerate_paths(new_dict)

執行上述代碼后的 output 如下:

前面代碼的結果

這是谷歌驅動器的數據鏈接

我嘗試使用遞歸function來解決問題,但是代碼失敗,出現了超出深度的問題。 我的目標是在沒有遞歸函數的情況下解決它。

我不確定您是否想要所有路徑或專門從節點到另一個節點的路徑。 無論哪種方式,這看起來都像是networkx的工作。

設置( nx.from_pandas_edgelist

import networkx as nx
import pandas as pd


df = pd.read_csv("...")

graph = nx.from_pandas_edgelist(df, create_using=nx.DiGraph)

所有路徑 ( nx.all_simple_paths )

from itertools import chain, product, starmap
from functools import partial


roots = (node for node, d in graph.in_degree if d == 0)

leaves = (node for node, d in graph.out_degree if d == 0)

all_paths = partial(nx.all_simple_paths, graph)

paths = list(chain.from_iterable(starmap(all_paths, product(roots, leaves))))

從一個節點到另一個節點

source_node = "some_node_in_graph"
target_node = "some_other_node_in_graph"
list(nx.all_simple_paths(graph, source=source_node, target=target_node))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM