Adjacency Matrix Representation of PHP Realization Graph and Analysis of Several Simple Traversal Algorithms
- 2021-08-16 23:22:58
- OfStack
In this paper, an example is given to describe the adjacency matrix representation of PHP implementation graph and several simple traversal algorithms. Share it for your reference, as follows:
In the development of web, the application of graph data structure is much less than tree, but it often appears in 1 business. The following introduces several graph routing algorithms and realizes them with PHP.
Freud algorithm, mainly in the vertex set, traverses according to the weight of points and adjacent edges of points. If two points are not connected, the weight is infinite, so that the shortest path from point to point can be obtained through multiple traversals, which is logically best understood and simpler to implement, and the time complexity is O (n ^ 3);
Dijiestra algorithm, The essence of djisktra algorithm is greedy algorithm, which continuously traverses and expands the vertex path set S. Once a shorter point-to-point path is found, the original shortest path in S is replaced, and S is the shortest path set of all vertices after all traversals are completed. The time complexity of Dijstra algorithm is O (n 2);
Kruskal algorithm, in the graph to construct a minimum spanning tree, all vertices in the graph to connect, so as to get the shortest path. The time complexity is O (N*logN);
<?php
/**
* PHP Implementation graph adjacency matrix
*/
class MGraph{
private $vexs; // Vertex array
private $arc; // Edge adjacency matrix , I.e. 2 Dimensional array
private $arcData; // Array information of edges
private $direct; // Type of graph ( Undirected or directed )
private $hasList; // Storing traversed nodes when trying to traverse
private $queue; // Queues for storing child nodes during breadth-first traversal , Imitate with arrays
private $infinity = 65535;// Represents infinity , That is, there is no connection between two points , Used in building graphs with weights , This example does not take weights
private $primVexs; //prim Save vertices in algorithm
private $primArc; //prim Save edges in algorithm
private $krus;//kruscal Save the information of edges when algorithm
public function MGraph($vexs, $arc, $direct = 0){
$this->vexs = $vexs;
$this->arcData = $arc;
$this->direct = $direct;
$this->initalizeArc();
$this->createArc();
}
private function initalizeArc(){
foreach($this->vexs as $value){
foreach($this->vexs as $cValue){
$this->arc[$value][$cValue] = ($value == $cValue ? 0 : $this->infinity);
}
}
}
// Create a diagram $direct:0 Representing an undirected graph ,1 Representing a directed graph
private function createArc(){
foreach($this->arcData as $key=>$value){
$strArr = str_split($key);
$first = $strArr[0];
$last = $strArr[1];
$this->arc[$first][$last] = $value;
if(!$this->direct){
$this->arc[$last][$first] = $value;
}
}
}
//floyd Algorithm
public function floyd(){
$path = array();// Path array
$distance = array();// Distance array
foreach($this->arc as $key=>$value){
foreach($value as $k=>$v){
$path[$key][$k] = $k;
$distance[$key][$k] = $v;
}
}
for($j = 0; $j < count($this->vexs); $j ++){
for($i = 0; $i < count($this->vexs); $i ++){
for($k = 0; $k < count($this->vexs); $k ++){
if($distance[$this->vexs[$i]][$this->vexs[$k]] > $distance[$this->vexs[$i]][$this->vexs[$j]] + $distance[$this->vexs[$j]][$this->vexs[$k]]){
$path[$this->vexs[$i]][$this->vexs[$k]] = $path[$this->vexs[$i]][$this->vexs[$j]];
$distance[$this->vexs[$i]][$this->vexs[$k]] = $distance[$this->vexs[$i]][$this->vexs[$j]] + $distance[$this->vexs[$j]][$this->vexs[$k]];
}
}
}
}
return array($path, $distance);
}
//djikstra Algorithm
public function dijkstra(){
$final = array();
$pre = array();// Prefix of the node to find 1 Array of nodes
$weight = array();// Weights and arrays
foreach($this->arc[$this->vexs[0]] as $k=>$v){
$final[$k] = 0;
$pre[$k] = $this->vexs[0];
$weight[$k] = $v;
}
$final[$this->vexs[0]] = 1;
for($i = 0; $i < count($this->vexs); $i ++){
$key = 0;
$min = $this->infinity;
for($j = 1; $j < count($this->vexs); $j ++){
$temp = $this->vexs[$j];
if($final[$temp] != 1 && $weight[$temp] < $min){
$key = $temp;
$min = $weight[$temp];
}
}
$final[$key] = 1;
for($j = 0; $j < count($this->vexs); $j ++){
$temp = $this->vexs[$j];
if($final[$temp] != 1 && ($min + $this->arc[$key][$temp]) < $weight[$temp]){
$pre[$temp] = $key;
$weight[$temp] = $min + $this->arc[$key][$temp];
}
}
}
return $pre;
}
//kruscal Algorithm
private function kruscal(){
$this->krus = array();
foreach($this->vexs as $value){
$krus[$value] = 0;
}
foreach($this->arc as $key=>$value){
$begin = $this->findRoot($key);
foreach($value as $k=>$v){
$end = $this->findRoot($k);
if($begin != $end){
$this->krus[$begin] = $end;
}
}
}
}
// Find the tail node of a subtree
private function findRoot($node){
while($this->krus[$node] > 0){
$node = $this->krus[$node];
}
return $node;
}
//prim Algorithm , Generate minimum spanning tree
public function prim(){
$this->primVexs = array();
$this->primArc = array($this->vexs[0]=>0);
for($i = 1; $i < count($this->vexs); $i ++){
$this->primArc[$this->vexs[$i]] = $this->arc[$this->vexs[0]][$this->vexs[$i]];
$this->primVexs[$this->vexs[$i]] = $this->vexs[0];
}
for($i = 0; $i < count($this->vexs); $i ++){
$min = $this->infinity;
$key;
foreach($this->vexs as $k=>$v){
if($this->primArc[$v] != 0 && $this->primArc[$v] < $min){
$key = $v;
$min = $this->primArc[$v];
}
}
$this->primArc[$key] = 0;
foreach($this->arc[$key] as $k=>$v){
if($this->primArc[$k] != 0 && $v < $this->primArc[$k]){
$this->primArc[$k] = $v;
$this->primVexs[$k] = $key;
}
}
}
return $this->primVexs;
}
//1 General algorithm , Generate minimum spanning tree
public function bst(){
$this->primVexs = array($this->vexs[0]);
$this->primArc = array();
next($this->arc[key($this->arc)]);
$key = NULL;
$current = NULL;
while(count($this->primVexs) < count($this->vexs)){
foreach($this->primVexs as $value){
foreach($this->arc[$value] as $k=>$v){
if(!in_array($k, $this->primVexs) && $v != 0 && $v != $this->infinity){
if($key == NULL || $v < current($current)){
$key = $k;
$current = array($value . $k=>$v);
}
}
}
}
$this->primVexs[] = $key;
$this->primArc[key($current)] = current($current);
$key = NULL;
$current = NULL;
}
return array('vexs'=>$this->primVexs, 'arc'=>$this->primArc);
}
//1 General traversal
public function reserve(){
$this->hasList = array();
foreach($this->arc as $key=>$value){
if(!in_array($key, $this->hasList)){
$this->hasList[] = $key;
}
foreach($value as $k=>$v){
if($v == 1 && !in_array($k, $this->hasList)){
$this->hasList[] = $k;
}
}
}
foreach($this->vexs as $v){
if(!in_array($v, $this->hasList))
$this->hasList[] = $v;
}
return implode($this->hasList);
}
// Breadth-first traversal
public function bfs(){
$this->hasList = array();
$this->queue = array();
foreach($this->arc as $key=>$value){
if(!in_array($key, $this->hasList)){
$this->hasList[] = $key;
$this->queue[] = $value;
while(!empty($this->queue)){
$child = array_shift($this->queue);
foreach($child as $k=>$v){
if($v == 1 && !in_array($k, $this->hasList)){
$this->hasList[] = $k;
$this->queue[] = $this->arc[$k];
}
}
}
}
}
return implode($this->hasList);
}
// Perform depth-first traversal
public function excuteDfs($key){
$this->hasList[] = $key;
foreach($this->arc[$key] as $k=>$v){
if($v == 1 && !in_array($k, $this->hasList))
$this->excuteDfs($k);
}
}
// Depth first traversal
public function dfs(){
$this->hasList = array();
foreach($this->vexs as $key){
if(!in_array($key, $this->hasList))
$this->excuteDfs($key);
}
return implode($this->hasList);
}
// Returns the of the graph 2 Dimensional array representation
public function getArc(){
return $this->arc;
}
// Returns the number of nodes
public function getVexCount(){
return count($this->vexs);
}
}
$a = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
$b = array('ab'=>'10', 'af'=>'11', 'bg'=>'16', 'fg'=>'17', 'bc'=>'18', 'bi'=>'12', 'ci'=>'8', 'cd'=>'22', 'di'=>'21', 'dg'=>'24', 'gh'=>'19', 'dh'=>'16', 'de'=>'20', 'eh'=>'7','fe'=>'26');// Keys are edges , Value weight
$test = new MGraph($a, $b);
print_r($test->bst());
Run results:
Array
(
[vexs] => Array
(
[0] => a
[1] => b
[2] => f
[3] => i
[4] => c
[5] => g
[6] => h
[7] => e
[8] => d
)
[arc] => Array
(
[ab] => 10
[af] => 11
[bi] => 12
[ic] => 8
[bg] => 16
[gh] => 19
[he] => 7
[hd] => 16
)
)
For more readers interested in PHP related contents, please check the topics of this site: "PHP Data Structure and Algorithm Tutorial", "php Programming Algorithm Summary", "php String (string) Usage Summary", "PHP Array (Array) Operation Skills Complete Book", "PHP Common Traversal Algorithms and Skills Summary" and "PHP Mathematical Operation Skills Summary"
I hope this article is helpful to everyone's PHP programming.