PHP實現圖的鄰接矩陣表示及遍曆演算法

來源:互聯網
上載者:User
這篇文章主要介紹了PHP實現圖的鄰接矩陣表示及幾種簡單遍曆演算法,結合執行個體形式分析了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實現二叉樹深度與廣度優先遍曆演算法步驟詳解

JavaScript關於多叉樹的遞迴遍曆和非遞迴遍曆演算法分享

PHP遍曆演算法的總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.