迪克斯特拉(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'));
?>
生命只有一次。

浙公网安备 33010602011771号