优先级队列(小顶堆)的dijkstra算法
Posted shqhdmr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优先级队列(小顶堆)的dijkstra算法相关的知识,希望对你有一定的参考价值。
php实现迪杰斯特拉算法,并由小顶堆优化
1 <?php 2 3 class DEdge 4 5 public $nextIndex, $length; 6 7 public function __construct($nextIndex, $length) 8 9 $this->nextIndex = $nextIndex; 10 $this->length = $length; 11 12 13 14 class DNode 15 16 public $index, $distance, $edges = []; 17 18 public function __construct($index, $distance) 19 20 $this->index = $index; 21 $this->distance = $distance; 22 23 24 public function addEdge(DEdge $edge) 25 26 $this->edges[] = $edge; 27 28 29 30 class Dijkstra 31 32 protected $origin; 33 protected $graph = [], $dGraph = [], $heap = [], $visited = [], $heapVisited = []; 34 35 public function __construct(array $graph, $origin) 36 37 $this->graph = $graph; 38 $this->origin = $origin; 39 $this->visited[$origin] = true; 40 $this->initializeGraph(); 41 $this->initializeHeap(); 42 $this->calculateDistance(); 43 44 45 public function printDistance() 46 47 foreach ($this->dGraph as $dNodes) 48 var_dump([$dNodes->index, $dNodes->distance]); 49 50 51 52 protected function initializeGraph() 53 54 foreach ($this->graph as $index => $edges) 55 $dNode = new DNode($index, $edges[$this->origin]); 56 foreach ($edges as $toIndex => $edge) 57 $dNode->addEdge(new DEdge($toIndex, $edge)); 58 59 $this->dGraph[$dNode->index] = $dNode; 60 61 62 63 protected function initializeHeap() 64 65 foreach ($this->dGraph as $index => $node) 66 if ($index != $this->origin && $node->distance != INF) 67 $this->addToHeap($node); 68 69 70 71 72 protected function calculateDistance() 73 74 while (($nearestNode = $this->heapPop()) != null) 75 foreach ($nearestNode->edges as $edge) 76 if ($this->dGraph[$edge->nextIndex]->distance > 77 $nearestNode->distance + $edge->length) 78 $this->dGraph[$edge->nextIndex]->distance = 79 $nearestNode->distance + $edge->length; 80 if (!isset($this->heapVisited[$edge->nextIndex])) 81 $this->addToHeap($this->dGraph[$edge->nextIndex]); 82 else 83 $this->keepHeap($this->heapVisited[$edge->nextIndex]); 84 85 86 87 88 89 90 protected function heapPop() 91 92 $heapCount = count($this->heap); 93 if ($heapCount > 0) 94 $this->swap(0, $heapCount - 1); 95 96 $pop = array_pop($this->heap); 97 $this->keepHeap(0, false); 98 return $pop; 99 100 101 protected function keepHeap($startAt, $up = true) 102 103 if ($up) 104 while ($startAt > 0) 105 $parentIndex = intval(($startAt - 1) / 2); 106 if ($this->heap[$parentIndex]->distance > $this->heap[$startAt]->distance) 107 $this->swap($parentIndex, $startAt); 108 $startAt = $parentIndex; 109 $this->heapVisited[$this->heap[$startAt]->index] = $startAt; 110 else 111 break; 112 113 114 else 115 $lastIndex = count($this->heap) - 1; 116 while ($startAt < $lastIndex) 117 $lIndex = 2 * $startAt + 1; 118 $rIndex = $lIndex + 1; 119 if (isset($this->heap[$rIndex])) 120 $minIndex = $this->heap[$lIndex]->distance < 121 $this->heap[$rIndex]->distance ? $lIndex : $rIndex; 122 else if (isset($this->heap[$lIndex])) 123 $minIndex = $lIndex; 124 else 125 break; 126 127 if ($this->heap[$startAt]->distance > $this->heap[$minIndex]->distance) 128 $this->swap($minIndex, $startAt); 129 $startAt = $minIndex; 130 $this->heapVisited[$this->heap[$startAt]->index] = $startAt; 131 else 132 break; 133 134 135 136 137 138 protected function addToHeap(DNode $dNode) 139 140 $this->heap[] = $dNode; 141 $this->keepHeap(count($this->heap) - 1); 142 143 144 protected function swap($index1, $index2) 145 146 list($this->heap[$index1], $this->heap[$index2]) = 147 [$this->heap[$index2], $this->heap[$index1]]; 148 149 150 151 $graph = [ 152 [0, 4, INF, 2, INF], 153 [4, 0, 4, 1, INF], 154 [INF, 4, 0, 1, 3,], 155 [2, 1, 1, 0, 7], 156 [INF, INF, 3, 7, 0], 157 ]; 158 159 $start = 0; 160 161 $dijkstra = new Dijkstra($graph, $start); 162 163 $dijkstra->printDistance();
以上是关于优先级队列(小顶堆)的dijkstra算法的主要内容,如果未能解决你的问题,请参考以下文章