查找关节点组

时间:2018-07-19 11:13:51

标签: algorithm graph graph-algorithm

我有一些无向图,我试图找到清晰的点。有例子

img1

它有一个关节-顶点#2。

但是我也想找到#4和#5作为发音组点。由于#4的联合移除,#5还将图切成未连接的子图。我将示例图想象成3个相连的子图。

img2

如何找到指定的切点?

2 个答案:

答案 0 :(得分:1)

我认为除了遍历所有组合之外,没有其他更快的方法,因为您没有任何限制。 (我什至认为该测试没有意义。)

虽然未指定编程语言,但请允许我以python为例。

在进行关节点搜索时,最著名的方法是Tarjan的算法。我想所有人都知道这一点,所以如果您不介意,我会在https://www.geeksforgeeks.org/articulation-points-or-cut-vertices-in-a-graph/的位置上跳过它。

class Graph:
   #From www.geeksforgeeks.org
def worker(g, prefix, arr, u):

    container = g.graph[u]
    if u in g.AP():
        print prefix
        arr.append([prefix])
        del g
    else:
        for i in container:
            if str(i) not in prefix.split(' '):
                new_prefix = prefix + ' ' + str(i)
                new_g = copy.deepcopy(g)
                new_g.combineNode(u, i)
                if len(new_g.graph) > 1:
                    worker(new_g, new_prefix, arr, i)

struct = {
    0:[1,12,13,14,15],
    1:[2,12,14,15],
    2:[3,4,5,14],
    3:[4],
    4:[5,6],
    5:[6,9],
    6:[7,8,9],
    7:[8,10,11],
    8:[9,10,11],
    9:[10],
    10:[11],
    12:[15],
    13:[14,15]
} 
g1 = Graph (total)

for key,value in struct.iteritems():
    for child in value:
        g1.addEdge(key, child)

result = []
for i in range(0, total):
    print 'Remove root ' + str(i)
    worker(g1, str(i), result, i)
print result

如果只有最短组长来划分图,我会写它。假设(4,5),如果已经是AP,则连接到它们的任何点也应该是AP。

以防万一,任何人都需要完整的测试代码。 https://gist.github.com/MichaelKHTai/c438fd0911d0584be1e37f1fd1599b7e

此外,应该通过跳过重复的节点组(例如(4,5)和(5,4))来优化它。

答案 1 :(得分:1)

一种方法是找到图形的“ 2连通分量”。

2连通图是指已连接不包含任何关节点的图。

任何简单图的边都可以划分为2个相连的子图。

第一个示例:

a sample graph

在上图中,以下是两个连接的组件:

  • 4–2 3–4 3–1 2–3 1–2
  • 8–9
  • 8–5 7–8 5–7
  • 6–0 5–6 1–5 0–1
  • 10-11

第二个示例:

a sample graph

每种颜色对应于2个连接的组件。多色顶点是切割的顶点(关节点),因此属于多个2连接的组件。

我认为每个组件都是您问题的答案。 您可以使用Tarjan算法查找这些组件。其时间复杂度为O(| V | + | E |)或O(n + m)。

time = 0
function DFS(vertex, adj[][], low[], disc[], parent[], visited[], V, stack)
    disc[vertex]=low[vertex]=time+1
    time = time + 1
    visited[vertex]=true
    child = 0
    for i = 0 to V
        if adj[vertex][i] == true
            if visited[i] == false
                child = child + 1
                push edge(u,v) to stack
                parent[i] = vertex
                DFS(i, adj, low, disc, visited, V, time, stack)
                low[vertex] = minimum(low[vertex], low[i])
                if parent[vertex] == nil AND child > 1
                    while last element of stack != (u,v)
                        print last element of stack
                        pop from stack
                    print last element of stack
                    pop from stack
                if parent[vertex] != nil AND low[i] >= disc[vertex]
                    while last element of stack != (u,v)
                        print last element of stack
                        pop from stack
                    print last element of stack
                    pop from stack
            else if parent[vertex] != i AND disc[i] < low[vertex]
                low[vertex] = disc[i]
                push edge(u,v) to stack

fuction biconnected_components(adj[][], V)
    for i = 0 to V
        if visited[i] == false
            DFS(i, adj, low, disc, parent, visited, V, time, stack)
            while stack is not empty
                print last element of stack
                pop from stack 

来源:

https://www.geeksforgeeks.org/biconnected-components/

https://en.wikipedia.org/wiki/Biconnected_component

https://www.hackerearth.com/practice/algorithms/graphs/biconnected-components/tutorial/