DirectedCycle.__init__()   B
last analyzed

Complexity

Conditions 5

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
c 1
b 0
f 0
dl 0
loc 15
rs 8.5454
1
from pyalgs.data_structures.commons.stack import Stack
2
from pyalgs.data_structures.graphs.graph import DirectedEdgeWeightedGraph, Digraph
3
4
5
class DirectedCycle(object):
6
7
    marked = None
8
    onStack = None
9
    cycle = None
10
    edgeTo = None
11
12
    def __init__(self, G):
13
        if isinstance(G, DirectedEdgeWeightedGraph):
14
            G = G.to_digraph()
15
16
        if not isinstance(G, Digraph):
17
            raise ValueError('Graph must be unweighted digraph')
18
19
        vertex_count = G.vertex_count()
20
        self.marked = [False] * vertex_count
21
        self.onStack = [False] * vertex_count
22
        self.edgeTo = [-1] * vertex_count
23
24
        for v in range(vertex_count):
25
            if not self.marked[v]:
26
                self.dfs(G, v)
27
28
    def dfs(self, G, v):
29
        self.marked[v] = True
30
        self.onStack[v] = True
31
32
        for w in G.adj(v):
33
            if not self.marked[w]:
34
                self.edgeTo[w] = v
35
                self.dfs(G, w)
36
            elif self.cycle is not None:
37
                break
38
            elif self.onStack[w]:
39
                self.cycle = Stack.create()
40
                x = v
41
                while x != w:
42
                    self.cycle.push(x)
43
                    x = self.edgeTo[x]
44
                self.cycle.push(w)
45
                self.cycle.push(v)
46
                break
47
48
        self.onStack[v] = False
49
50
    def hasCycle(self):
51
        return self.cycle is not None
52
53
    def get_cycle(self):
54
        return self.cycle.iterate()
55