从向量中高效提取同类节点的算法

时间:2019-03-26 21:07:47

标签: python algorithm

我有一个向量(它是分类的结果) 这意味着i和s [i]属于同一类

例如:

S=(2,1,1,3,6,7,5,9,6,13,12,14,12,11)

((   `s[1]=2 `so node 1 and 2 are in same class
and    `s[2]=1`  same information
s[3]=1` so all 1,2,3 are in same class))

现在我必须找到一种方法来从s获取成员向量: 看看哪些节点在同一个类中

mVC=[1,1,1,1,2,2,2,2,2,3,3,3,3,3]

(here 1,2,3,4 are in one class)

2 个答案:

答案 0 :(得分:1)

这是一个connected components问题。这是一种方法:

S=(2,1,1,3,6,7,5,9,6,13,12,14,12,11)

建立一个元组列表,每个元组代表图中的边,并由S中给定值的索引和值本身组成:

edges = [(ix+1, i) for ix, i in enumerate(S)]
# [(1, 2), (2, 1), (3, 1), (4, 3), (5, 6), (6, 7), (7, 5), (8,....

使用networkx建立网络并提取其connected_components。这会将“同一类”中的节点分组在一起:

import networkx as nx
G=nx.Graph()
G.add_edges_from(edges)
list(nx.connected_components(G))

输出

[{1, 2, 3, 4}, {5, 6, 7, 8, 9}, {10, 11, 12, 13, 14}]

答案 1 :(得分:0)

向量S看起来好像代表父级关系,尽管它可能包含循环。因此,如果您将此向量视为它是有向图的邻接列表,并在此数据结构上进行了深度优先搜索(DFS),则会发现该的关联组件,根据您的术语,每个分类都属于同一类。您还可以在运行DFS时填充mVC,并以所需的格式获取数据。

与默认DFS相反,您需要注意后边缘交叉边缘,并更新用于每当遇到这些类型的边缘之一时,我们都将对其进行探索。

下面是一个示例实现。当遇到后边缘或交叉边缘时,该算法将停止递归并将该边缘目标的组成部分(即分类信息)起泡到当前正在探索的顶点。< / p>

def dfs(S, u, mVC, currentComponent):
    mVC[u] = currentComponent
    if mVC[ S[u] ] == 0:
        mVC[u] = dfs(S, S[u], mVC, currentComponent)
    else:
        mVC[u] = mVC[S[u]]
    return mVC[u]

S = [0] + list(S) # to handle the 1-indexing of the content in S
mVC = [0] * len(S)
currentComponent = 1
for i in range(1, len(S)):
    if mVC[ i ] == 0:
        componentAssigned = dfs(S, i, mVC, currentComponent)
        if componentAssigned == currentComponent:
            currentComponent += 1
mVC = mVC[1:] # Gets rid of the dummy 0th element added above
# at this point, mVC contains the class relationship in the desired format