DepthFirstPath::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TemplesOfCode\NodesAndEdges\DFS;
4
5
use TemplesOfCode\NodesAndEdges\Graph;
6
7
/**
8
 * Class DepthFirstPath
9
 * @package TemplesOfCode\NodesAndEdges\DFS
10
 */
11
class DepthFirstPath
12
{
13
    /**
14
     * @var Graph
15
     */
16
    private $graph;
17
18
    /**
19
     * @var bool[]
20
     */
21
    private $marked;
22
23
    /**
24
     * @var int[]
25
     */
26
    private $edgeTo;
27
28
    /**
29
     * @var int
30
     */
31
    private $sourceVertex;
32
33
    /**
34
     * DepthFirstPath constructor.
35
     * @param Graph $graph
36
     * @param int $sourceVertex
37
     */
38
    public function __construct(Graph $graph, int $sourceVertex)
39
    {
40
        // validate this vertex in the context of the given graph
41
        Graph::validateVertex($sourceVertex, $graph->getVertices());
42
        // init
43
        $this->marked = array_fill(0, $graph->getVertices(), false);
44
        // set
45
        $this->graph = $graph;
46
        // set
47
        $this->sourceVertex = $sourceVertex;
48
        // execute DFS logic
49
        $this->dfs($sourceVertex);
50
    }
51
52
    /**
53
     * Depth first search from $vertex
54
     *
55
     * @param int $vertex
56
     */
57
    private function dfs(int $vertex)
58
    {
59
        // set this vertex as marked
60
        $this->marked[$vertex] = true;
61
        // iterate over the the vertices incident to $vertex
62
        foreach ($this->graph->adjacent($vertex) as $w) {
63
            // if we have not visited this vertex yet..
64
            if (!$this->marked[$w]) {
65
                // set
66
                $this->edgeTo[$w] = $vertex;
67
                // lets visit
68
                $this->dfs($w);
69
            }
70
        }
71
    }
72
73
    /**
74
     * @param int $vertex
75
     * @return bool
76
     */
77
    public function hasPathTo(int $vertex)
78
    {
79
        // validate this vertex in the context of the given graph
80
        Graph::validateVertex($vertex, $this->graph->getVertices());
81
        // return 
82
        return $this->marked[$vertex];
83
    }
84
85
    /**
86
     * @param int $vertex
87
     * @return array
88
     */
89
    public function pathTo(int $vertex)
90
    {
91
        // validate this vertex in the context of the given graph
92
        Graph::validateVertex($vertex, $this->graph->getVertices());
93
        // check if there is a path
94
        if (!$this->hasPathTo($vertex)) {
95
            // empty case
96
            return null;
97
        }
98
        // init
99
        $path = [];
100
        // pop into the stack
101
        for ($x = $vertex; $x != $this->sourceVertex; $x = $this->edgeTo[$x]) {
102
            // pop into stack
103
            array_unshift($path, $x);
104
        }
105
        // pop the source into the stack
106
        array_unshift($path, $this->sourceVertex);
107
        // return the stack
108
        return $path;
109
    }
110
}
111