迪克斯特拉(Dijkstra)算法php 实现
<?php class Graph{ private $data = []; const INFINITY = -1; public function addDirection( $fromNode, $toNode,$cost ){ if( !isset($this->data[$fromNode]) ){ $this->data[$fromNode] = []; } $this->data[$fromNode][$toNode] = $cost; } public function getNeighters( $node ){ return $this->data[$node] ?? []; } public function printData(){ print_r( $this->data ); } } class DK{ public $graph = null; private $costs = []; private $parents = []; public $processedNodes = []; public function getGraph() : Graph{ if( $this->graph == null ){ $this->graph = new Graph(); } return $this->graph; } public function printGraph(){ return $this->getGraph()->printData(); } public function addDirection($fromNode,$toNode,$cost){ $this->getGraph()->addDirection( $fromNode,$toNode,$cost ); } public function getCosts( $fromNode, $toNode ){ $this->initCosts( $fromNode, $toNode ); $node = $this->getLowestNode(); while ( $node ){ $cost = $this->getCost( $node ); foreach ( $this->getGraph()->getNeighters($node) as $neighterNode => $neighterCost ){ $newCost = $cost + $neighterCost; if( $this->costs[$neighterNode] == Graph::INFINITY || !isset($this->costs[$neighterNode]) || $newCost < $cost ){ $this->costs[$neighterNode] = $newCost; $this->parents[$neighterNode] = $node; } } array_push($this->processedNodes, $node); $node = $this->getLowestNode(); } return $this->costs; } public function initCosts($fromNode, $toNode){ $nodes = $this->getGraph()->getNeighters($fromNode); foreach ($nodes as $_node => $cost ){ $this->costs[$_node] = $cost; } if( !isset( $this->costs[$toNode] ) ){ $this->costs[$toNode] = Graph::INFINITY; } } public function getCost( $toNode ){ return $this->costs[$toNode] ?? Graph::INFINITY; } private function getLowestNode(){ $lowestNode = null; $lowestCost = Graph::INFINITY; foreach ( $this->costs as $node =>$cost ){ if( $cost == Graph::INFINITY || in_array($node, $this->processedNodes) ){ continue; } if( $lowestCost == Graph::INFINITY || $cost < $lowestCost ){ $lowestCost = $cost; $lowestNode = $node; } } return $lowestNode; } } $dk = new DK(); $dk->addDirection('shenyang','liaoyang', 5 ); $dk->addDirection('shenyang', 'anshan', 1); $dk->addDirection('anshan','dalian',5); $dk->addDirection('liaoyang','dalian', 2 ); $dk->addDirection('dalian','panjin', 7 ); $dk->printGraph(); var_dump($dk->getCosts('shenyang','panjin')); ?>
生命只有一次。