Passed
Push — master ( 8dab02...d67164 )
by Pierre
03:08
created

Min::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace App\Component\Math\Graph\Path;
4
5
/**
6
 * Find least number of hops between nodes collection.
7
 * Graph should be considered as oriented.
8
 */
9
class Min
10
{
11
    /**
12
     * graph
13
     *
14
     * @var array
15
     */
16
    protected $graph;
17
18
    /**
19
     * visited
20
     *
21
     * @var array
22
     */
23
    protected $visited = [];
24
25
    /**
26
     * instanciate
27
     *
28
     * @param array $graph
29
     */
30 2
    public function __construct(array $graph)
31
    {
32 2
        $this->graph = $graph;
33
    }
34
35
    /**
36
     * return path search as array
37
     *
38
     * @param string  $origin
39
     * @param string  $destination
40
     * @return array
41
     */
42 1
    public function path(string $origin, string  $destination): array
43
    {
44
        // check exists origin destination
45 1
        if (!isset($this->graph[$origin]) || !isset($this->graph[$destination])) {
46 1
            return [];
47
        }
48
        // mark all nodes as unvisited
49 1
        foreach ($this->graph as $vertex => $adj) {
50 1
            $this->visited[$vertex] = false;
51
        }
52
        // create an empty queue
53 1
        $q = new \SplQueue();
54
        // enqueue the origin vertex and mark as visited
55 1
        $q->enqueue($origin);
56 1
        $this->visited[$origin] = true;
57
        // this is used to track the path back from each node
58 1
        $path = [];
59 1
        $path[$origin] = new \SplDoublyLinkedList();
60 1
        $path[$origin]->setIteratorMode(
61 1
            \SplDoublyLinkedList::IT_MODE_FIFO | \SplDoublyLinkedList::IT_MODE_KEEP
62
        );
63 1
        $path[$origin]->push($origin);
64
        // while queue is not empty and destination not found
65 1
        while (!$q->isEmpty() && $q->bottom() != $destination) {
66 1
            $t = $q->dequeue();
67 1
            if (!empty($this->graph[$t])) {
68
                // for each adjacent neighbor
69 1
                foreach ($this->graph[$t] as $vertex) {
70 1
                    if (!$this->visited[$vertex]) {
71
                        // if not yet visited, enqueue vertex and mark
72
                        // as visited
73 1
                        $q->enqueue($vertex);
74 1
                        $this->visited[$vertex] = true;
75
                        // add vertex to current path
76 1
                        $path[$vertex] = clone $path[$t];
77 1
                        $path[$vertex]->push($vertex);
78
                    }
79
                }
80
            }
81
        }
82 1
        return (isset($path[$destination])) ? iterator_to_array($path[$destination]) : [];
83
    }
84
}
85