FloydWarshallIndexer   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 32
c 1
b 0
f 0
dl 0
loc 61
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A operatingIn() 0 3 1
A allShortestPaths() 0 6 2
A heuristic() 0 6 2
B calculateIndex() 0 29 7
A __construct() 0 3 1
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\Pathfinder;
4
5
use Stratadox\Pathfinder\Estimate\Indexed;
6
use Stratadox\Pathfinder\Graph\GeometricView;
7
8
final class FloydWarshallIndexer implements Indexer
9
{
10
    private $graph;
11
    private $shortestPaths;
12
    private $distances;
13
14
    public function __construct(Network $network)
15
    {
16
        $this->graph = $network;
17
    }
18
19
    public static function operatingIn(Network $network): Indexer
20
    {
21
        return new self($network);
22
    }
23
24
    public function allShortestPaths(): ShortestPathForest
25
    {
26
        if (!$this->shortestPaths) {
27
            $this->calculateIndex();
28
        }
29
        return Index::of($this->shortestPaths);
30
    }
31
32
    public function heuristic(): Heuristic
33
    {
34
        if (!$this->distances) {
35
            $this->calculateIndex();
36
        }
37
        return Indexed::heuristic($this->distances, GeometricView::of($this->graph));
38
    }
39
40
    private function calculateIndex(): void
41
    {
42
        $dist = [];
43
        $next = [];
44
        foreach ($this->graph->all() as $node) {
45
            $dist[$node][$node] = 0;
46
            foreach ($this->graph->neighboursOf($node) as $neighbour) {
47
                $dist[$node][$neighbour] = $this->graph->movementCostBetween($node, $neighbour);
48
                $next[$node][$neighbour] = $neighbour;
49
            }
50
        }
51
        $all = $this->graph->all()->items();
52
        foreach ($all as $node) {
53
            foreach ($all as $start) {
54
                $begin = ($dist[$start][$node] ?? INF);
55
                foreach ($all as $goal) {
56
                    $end = ($dist[$node][$goal] ?? INF);
57
                    $proposition = $begin + $end;
58
                    $current = ($dist[$start][$goal] ?? INF);
59
60
                    if ($proposition < $current) {
61
                        $dist[$start][$goal] = $dist[$start][$node] + $dist[$node][$goal];
62
                        $next[$start][$goal] = $next[$start][$node] ?? null;
63
                    }
64
                }
65
            }
66
        }
67
        $this->distances = $dist;
68
        $this->shortestPaths = $next;
69
    }
70
}
71