国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > PHP > 正文

PHP實現圖的鄰接矩陣表示及幾種簡單遍歷算法分析

2024-05-05 00:01:14
字體:
來源:轉載
供稿:網友

本文實例講述了PHP實現圖的鄰接矩陣表示及幾種簡單遍歷算法。分享給大家供大家參考,具體如下:

在web開發中圖這種數據結構的應用比樹要少很多,但在一些業務中也常有出現,下面介紹幾種圖的尋徑算法,并用PHP加以實現.

佛洛依德算法,主要是在頂點集內,按點與點相鄰邊的權重做遍歷,如果兩點不相連則權重無窮大,這樣通過多次遍歷可以得到點到點的最短路徑,邏輯上最好理解,實現也較為簡單,時間復雜度為O(n^3);

迪杰斯特拉算法,OSPF中實現最短路由所用到的經典算法,djisktra算法的本質是貪心算法,不斷的遍歷擴充頂點路徑集合S,一旦發現更短的點到點路徑就替換S中原有的最短路徑,完成所有遍歷后S便是所有頂點的最短路徑集合了.迪杰斯特拉算法的時間復雜度為O(n^2);

克魯斯卡爾算法,在圖內構造最小生成樹,達到圖中所有頂點聯通.從而得到最短路徑.時間復雜度為O(N*logN);

<?php/** * PHP 實現圖鄰接矩陣 */class MGraph{  private $vexs; //頂點數組  private $arc; //邊鄰接矩陣,即二維數組  private $arcData; //邊的數組信息  private $direct; //圖的類型(無向或有向)  private $hasList; //嘗試遍歷時存儲遍歷過的結點  private $queue; //廣度優先遍歷時存儲孩子結點的隊列,用數組模仿  private $infinity = 65535;//代表無窮,即兩點無連接,建帶權值的圖時用,本示例不帶權值  private $primVexs; //prim算法時保存頂點  private $primArc; //prim算法時保存邊  private $krus;//kruscal算法時保存邊的信息  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);      }    }  }  //創建圖 $direct:0表示無向圖,1表示有向圖  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算法  public function floyd(){    $path = 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算法  public function dijkstra(){    $final = array();    $pre = array();//要查找的結點的前一個結點數組    $weight = array();//權值和數組    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算法  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;        }      }    }  }  //查找子樹的尾結點  private function findRoot($node){    while($this->krus[$node] > 0){      $node = $this->krus[$node];    }    return $node;  }  //prim算法,生成最小生成樹  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;  }  //一般算法,生成最小生成樹  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);  }  //一般遍歷  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);  }  //廣度優先遍歷  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);  }  //執行深度優先遍歷  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);    }  }  //深度優先遍歷  public function dfs(){    $this->hasList = array();    foreach($this->vexs as $key){      if(!in_array($key, $this->hasList))        $this->excuteDfs($key);    }    return implode($this->hasList);  }  //返回圖的二維數組表示  public function getArc(){    return $this->arc;  }  //返回結點個數  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');//鍵為邊,值權值$test = new MGraph($a, $b);print_r($test->bst());

運行結果:

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    ))

希望本文所述對大家PHP程序設計有所幫助。


注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 水城县| 繁昌县| 诸城市| 揭东县| 澄迈县| 通州区| 奇台县| 泊头市| 中牟县| 凌源市| 深圳市| 涿州市| 肃宁县| 藁城市| 苏尼特右旗| 板桥市| 辛集市| 伊吾县| 德庆县| 红安县| 民权县| 巴里| 青海省| 盐池县| 荃湾区| 安义县| 准格尔旗| 公安县| 塔城市| 新竹县| 千阳县| 华阴市| 珠海市| 永丰县| 饶河县| 岫岩| 武邑县| 长垣县| 鹤山市| 安新县| 阿尔山市|