StronglyConnectedComponents   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 40
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 40
rs 10
wmc 12

5 Methods

Rating   Name   Duplication   Size   Complexity  
A dfs() 0 6 3
A connected() 0 2 1
B __init__() 0 19 6
A count() 0 2 1
A id() 0 2 1
1
from abc import ABCMeta, abstractmethod
2
3
from pyalgs.algorithms.graphs.topological_sort import DepthFirstOrder
4
from pyalgs.data_structures.graphs.graph import EdgeWeightedGraph, Digraph, DirectedEdgeWeightedGraph
5
6
7
class ConnectedComponents(object):
8
    marked = None
9
    _id = None
10
    _count = 0
11
12
    def __init__(self, G):
13
        if isinstance(G, EdgeWeightedGraph):
14
            G = G.to_graph()
15
16
        vertex_count = G.vertex_count()
17
        self.marked = [False] * vertex_count
18
        self._id = [-1] * vertex_count
19
        for v in range(vertex_count):
20
            if not self.marked[v]:
21
                self.dfs(G, v)
22
                self._count += 1
23
24
    def dfs(self, G, v):
25
        self.marked[v] = True
26
        self._id[v] = self._count
27
        for w in G.adj(v):
28
            if not self.marked[w]:
29
                self.dfs(G, w)
30
31
    def connected(self, v, w):
32
        return self._id[v] == self._id[w]
33
34
    def count(self):
35
        return self._count
36
37
    def id(self, v):
38
        return self._id[v]
39
40
41
class StronglyConnectedComponents(object):
42
    marked = None
43
    _id = None
44
    _count = 0
45
46
    def __init__(self, G):
47
        if isinstance(G, EdgeWeightedGraph):
48
            raise ValueError('Graph must be directed graph for strongly connected components')
49
        if isinstance(G, DirectedEdgeWeightedGraph):
50
            G = G.to_digrah()
51
        if not isinstance(G, Digraph):
52
            raise ValueError('Graph must be directed graph for strongly connected components')
53
54
        vertex_count = G.vertex_count()
55
        self.marked = [False] * vertex_count
56
        self._id = [-1] * vertex_count
57
58
        dfo = DepthFirstOrder(G.reverse())
59
        orders = dfo.postOrder()
60
61
        for v in orders:
62
            if not self.marked[v]:
63
                self.dfs(G, v)
64
                self._count += 1
65
66
    def dfs(self, G, v):
67
        self.marked[v] = True
68
        self._id[v] = self._count
69
        for w in G.adj(v):
70
            if not self.marked[w]:
71
                self.dfs(G, w)
72
73
    def connected(self, v, w):
74
        return self._id[v] == self._id[w]
75
76
    def count(self):
77
        return self._count
78
79
    def id(self, v):
80
        return self._id[v]
81