ConnectedComponent   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
eloc 27
c 1
b 0
f 0
dl 0
loc 153
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A marked() 0 8 1
A __construct() 0 22 3
A connected() 0 8 1
A id() 0 6 1
A size() 0 6 1
A count() 0 4 1
1
<?php
2
3
namespace TemplesOfCode\NodesAndEdges\DFS;
4
5
use InvalidArgumentException;
6
use TemplesOfCode\NodesAndEdges\Graph;
7
8
/**
9
 * Class ConnectedComponent
10
 * @package TemplesOfCode\NodesAndEdges\DFS
11
 */
12
abstract class ConnectedComponent
13
{
14
    /**
15
     * id[v] = id of connected component containing v
16
     *
17
     * @var int[]
18
     */
19
    protected $id;
20
21
    /**
22
     * marked[v] = has vertex v been marked?
23
     *
24
     * @var bool[]
25
     */
26
    protected $marked;
27
28
    /**
29
     * size[id] = number of vertices in given component
30
     *
31
     * @var int[]
32
     */
33
    protected $size;
34
35
    /**
36
     * number of connected components
37
     *
38
     * @var int
39
     */
40
    protected $count;
41
42
    /**
43
     * @var Graph
44
     */
45
    protected $graph;
46
47
    /**
48
     * Computes the connected components of the graph g.
49
     *
50
     * @param Graph $g the graph
51
     */
52
    public function __construct(Graph $g)
53
    {
54
        // set
55
        $this->graph = $g;
56
        // get vertices
57
        $vertices = $g->getVertices();
58
        // init
59
        $this->marked = array_fill(0, $vertices, false);
60
        // init
61
        $this->id = array_fill(0, $vertices, 0);
62
        // init
63
        $this->size = array_fill(0, $vertices, 0);
64
        // init
65
        $this->count = 0;
66
        // iterate over the set
67
        for ($vertex = 0; $vertex < $vertices; $vertex++) {
68
            // check if we have touched this vertex
69
            if (!$this->marked[$vertex]) {
70
                // we haven't, lets explore
71
                $this->dfs($vertex);
72
                // increment the count for components
73
                $this->count++;
74
            }
75
        }
76
    }
77
78
    /**
79
     * Returns the component id of the connected component containing vertex $v.
80
     *
81
     * @param int $v the vertex
82
     * @return int the component id of the connected component containing vertex $v
83
     * @throws InvalidArgumentException unless 0 <= $v < V
84
     */
85
    public function id(int $v)
86
    {
87
        // validate
88
        Graph::validateVertex($v, $this->graph->getVertices());
89
        // fetch and return
90
        return $this->id[$v];
91
    }
92
93
94
    /**
95
     * Returns the number of vertices in the connected component containing $v
96
     *
97
     * @param int $v the vertex
98
     * @return int the number of vertices in the connected component containing $v
99
     * @throws InvalidArgumentException unless 0 <= v < V
100
     */
101
    public function size(int $v)
102
    {
103
        // validate
104
        Graph::validateVertex($v, $this->graph->getVertices());
105
        // fetch and return
106
        return $this->size[$this->id($v)];
107
    }
108
109
110
    /**
111
     * Returns the number of connected components in the graph
112
     *
113
     * @return int the number of connected components in the graph
114
     */
115
    public function count()
116
    {
117
        // fetch and return
118
        return $this->count;
119
    }
120
121
    /**
122
     * Returns true if vertices $v and $w are in the same
123
     * connected component.
124
     *
125
     * @param  int $v one vertex
126
     * @param  int $w the other vertex
127
     * @return bool true if vertices v and w are in the same
128
     *         connected component; false otherwise
129
     * @throws InvalidArgumentException unless 0 <= v < V
130
     * @throws InvalidArgumentException unless  0 <= w < V
131
     */
132
    public function connected(int $v, int $w)
133
    {
134
        // validate
135
        Graph::validateVertex($v, $this->graph->getVertices());
136
        // validate
137
        Graph::validateVertex($w, $this->graph->getVertices());
138
        // evaluate
139
        return $this->id($v) == $this->id($w);
140
    }
141
142
143
    /**
144
     * Is there a path between the source vertex and vertex v
145
     *
146
     * @param int $vertex
147
     * @return bool true if there is a path, false otherwise
148
     * @throws InvalidArgumentException unless 0 <= $vertex < $vertices
149
     */
150
    public function marked(int $vertex)
151
    {
152
        // convenience var
153
        $vertices = $this->graph->getVertices();
154
        // validate this vertex in the context of the given graph
155
        Graph::validateVertex($vertex, $vertices);
156
        // return the flag
157
        return $this->marked[$vertex];
158
    }
159
160
    /**
161
     * @param int $vertex
162
     * @return mixed
163
     */
164
    abstract protected function dfs(int $vertex);
165
}
166