class ToplogicGraph{
protected $vertexArr = array();
protected $arcArr = array();
public $digraph = array();
protected $time = 0;
protected $detect = array();
// 建立 有向图领接表 数组表示
public function buildDigraph()
{
foreach ($this->vertexArr as $key => $vertex) {
$this->digraph[$vertex] = array('name'=>$vertex,'d'=>null,'f'=>null,'tails'=>array(),'color'=>'WHITE','PI'=>null);
}
foreach ($this->arcArr as $key => $arc) {
$this->digraph[$arc[0]]['tails'][] = $arc[1];
}
}
public function setArcArr($arcArr)
{
$this->arcArr = $arcArr;
}
public function setVertexArr($vertexArr)
{
$this->vertexArr = $vertexArr;
}
public function DFS()
{
//检测是否存在环 并输出环路径
foreach ($this->vertexArr as $key => $vertex) {
$graph = $this->digraph;
$this->detect = array($vertex);
$G = &$graph;
$this->DFS_Visit_Detected($vertex,$graph);
}
$this->time = 0;
//深度优先遍历图
foreach ($this->vertexArr as $key => $vertex) {
if($this->digraph[$vertex]['color']=='WHITE'){
$graph = &$this->digraph;
$this->DFS_Visit($vertex,$graph);
}
}
}
protected function DFS_Visit($vertexKey,&$graph)
{
$this->time = ($this->time + 1);
$graph[$vertexKey]['d'] = $this->time;
foreach ($graph[$vertexKey]['tails'] as $key => $vertex) {
if($graph[$vertex]['color']=='WHITE'){
$graph[$vertex]['PI'] = $vertexKey;
$this->DFS_Visit($vertex,$graph);
}
}
$graph[$vertexKey]['color'] = 'BLACK';
$this->time = ($this->time + 1);
$graph[$vertexKey]['f'] = $this->time;
}
protected function DFS_Visit_Detected($vertexKey,&$graph)
{
$graph[$vertexKey]['color'] = 'GREY';
foreach ($graph[$vertexKey]['tails'] as $key => $vertex) {
$this->detect[] = $vertex;
if($graph[$vertex]['color']=='WHITE'){
$graph[$vertex]['PI'] = $vertexKey;
$graph[$vertex]['color'] = 'GREY';
$this->DFS_Visit_Detected($vertex,$graph);
} else {
echo 'there is a loop:';
var_dump($this->detect);
exit();
}
}
$graph[$vertexKey]['color'] = 'BLACK';
array_pop($this->detect);
}
//拓扑排序
public function toplogicSort()
{
$sort = array();
foreach ($this->digraph as $key => $value) {
$sort[$key] = $value['f'];
}
arsort($sort);
return array_keys($sort);
}
}
$Graph = new ToplogicGraph();
$arcArr = array(
array('A','C'),
array('A','B'),
array('C','F'),
array('B','G'),
array('C','G'),
array('M','N'),
array('G','A'), //测试 环 数据
);
$vertexArr = array('A','B','C','D','E','F','G','M','N');
$Graph->setArcArr($arcArr);
$Graph->setVertexArr($vertexArr);
$Graph->buildDigraph();
$Graph->DFS();
$sort = $Graph->toplogicSort();
var_dump($sort); // 输出最后的拓扑排序结果