Completed
Push — master ( 391c2e...e5e5ec )
by Ventaquil
02:20
created

Graph   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 3
dl 0
loc 159
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 3
A addConnection() 0 12 2
A addNode() 0 8 2
A getConnections() 0 8 2
A getDistances() 0 14 2
A getNearestConnection() 0 19 4
A getNearestDistance() 0 10 2
A getNeighbour() 0 16 4
1
<?php
2
3
namespace PHPAlgorithms\GraphTools;
4
5
use PHPAlgorithms\GraphTools\Abstracts\BuildableAbstract;
6
use PHPAlgorithms\GraphTools\Graph\Connection;
7
use PHPAlgorithms\GraphTools\Graph\Node;
8
9
/**
10
 * Class Graph
11
 * @package PHPAlgorithms\GraphTools
12
 * @method Node[] getNodes()
13
 * @property-read Node[] $nodes
14
 */
15
class Graph extends BuildableAbstract
16
{
17
    /**
18
     * @var string[] $allowedGet
19
     */
20
    protected $allowedGet = array('nodes');
21
22
    /**
23
     * @var Connection[] $connections
24
     */
25
    protected $connections;
26
27
    /**
28
     * @var Node[] $nodes
29
     */
30
    protected $nodes;
31
32
    /**
33
     * Graph constructor.
34
     * @param Node[] $nodes
35
     * @param Connection[] $connections
36
     */
37
    public function __construct(array $nodes, array $connections)
38
    {
39
        foreach ($nodes as $node) {
40
            $this->addNode($node);
41
        }
42
43
        foreach ($connections as $connection) {
44
            $this->addConnection($connection);
45
        }
46
    }
47
48
    /**
49
     * @param Connection $connection
50
     * @return Graph
51
     */
52
    protected function addConnection(Connection $connection) : Graph
53
    {
54
        $this->addNode($connection->from)->addNode($connection->to);
55
56
        if (!isset($this->connections[$connection->from->id][$connection->to->id])) {
57
            $this->connections[$connection->from->id][$connection->to->id] = array();
58
        }
59
60
        $this->connections[$connection->from->id][$connection->to->id][] = $connection;
61
62
        return $this;
63
    }
64
65
    /**
66
     * @param Node $node
67
     * @return Graph
68
     */
69
    protected function addNode(Node $node) : Graph
70
    {
71
        if (!isset($this->nodes[$node->id])) {
72
            $this->nodes[$node->id] = $node;
73
        }
74
75
        return $this;
76
    }
77
78
    /**
79
     * @param Node $from
80
     * @param Node $to
81
     * @return Connection[]
82
     */
83
    public function getConnections(Node $from, Node $to) : array
84
    {
85
        if (isset($this->connections[$from->id][$to->id])) {
86
            return $this->connections[$from->id][$to->id];
87
        }
88
89
        return array();
90
    }
91
92
    /**
93
     * @param Node $from
94
     * @param Node $to
95
     * @return (float|null)[]
96
     */
97
    public function getDistances(Node $from, Node $to) : array
98
    {
99
        $distances = array();
100
101
        foreach ($this->getConnections($from, $to) as $connection) {
102
            /**
103
             * @var Connection $connection
104
             */
105
106
            $distances[] = $connection->getWeight();
107
        }
108
109
        return $distances;
110
    }
111
112
    /**
113
     * @param Node $from
114
     * @param Node $to
115
     * @return null|Connection
116
     */
117
    public function getNearestConnection(Node $from, Node $to) : ?Connection
118
    {
119
        /**
120
         * @var null|Connection $nearest
121
         */
122
        $nearest = null;
123
124
        foreach ($this->getConnections($from, $to) as $connection) {
125
            /**
126
             * @var Connection $connection
127
             */
128
129
            if (is_null($nearest) || ($nearest->getWeight() > $connection->getWeight())) {
130
                $nearest = $connection;
131
            }
132
        }
133
134
        return $nearest;
135
    }
136
137
    /**
138
     * @param Node $from
139
     * @param Node $to
140
     * @return null|float
141
     */
142
    public function getNearestDistance(Node $from, Node $to) : ?float
143
    {
144
        $nearest = $this->getNearestConnection($from, $to);
145
146
        if (is_null($nearest)) {
147
            return null;
148
        }
149
150
        return $nearest->getWeight();
151
    }
152
153
    /**
154
     * @param Node $node
155
     * @return Node[]
156
     */
157
    public function getNeighbour(Node $node) : array
158
    {
159
        $neighbour = array();
160
161
        if (isset($this->connections[$node->id])) {
162
            $ids = array_keys($this->connections[$node->id]);
163
164
            foreach ($this->nodes as $node) {
165
                if (in_array($node->id, $ids)) {
166
                    $neighbour[] = $node;
167
                }
168
            }
169
        }
170
171
        return $neighbour;
172
    }
173
}
174