首先要了解的概念是有向图和无向图。有向图的节点之间的边是有方向的,类似于向量,无向图节点之间的边没有方向,可以理解为有一条从A指向B的边,同时也有一条从B到A的边。

然后我们要解决的是如何表示图,这里的重点是如何表示多对多的关系。

class Graph{
    protected $_nodes = [];
    protected $_edges = [];
    function __construct(){

    }

    function insert($node){
        if(!($node instanceof Graph_node)){
            $node = new Graph_node($node);
        }
        $index = $this->length();
        $node->set_index($index);
        $this->insert_indexed_node($node);
    }

    function insert_indexed_node($node){
        $index = $node->get_index();
        $this->_nodes[$index] = $node;
    }

    function length(){
        return count($this->nodes);
    }

    function set_edge($from,$to,$weight=1){
        if(!isset($this->_edges[$from])){
            $this->_edges[$from] = [];
        }
        $this->_edges[$from][$to] = $weight;
    }

    function get_node_by_index($index){
        return $this->_nodes[$index];
    }

}

我们用一个Graph类表示图,其中$nodes用来存储节点,用$_edges表示边。$_edges的键为节点的索引,值是一个array的形式,这个array的键表示相邻节点的索引,array的值表示边的权重。上面的set_edge方法就是建立边的方法。

对于有向图来说,上面的set_edge方法已经足够了,对于无向图来说,当建立一条从A到B的边,我们同时需要建立从B到A的边。

class Graph_undirected extends Graph{
    function __construct(){
        parent::__construct();
    }

    function set_edge($from,$to,$weight=1){
        parent::set_edge($from,$to,$weight);
        parent::set_edge($to,$from,$weight);
    }
}

对于图的基本表示其实有很多方法,这里只是根据自己的理解对应的一种实现。

results matching ""

    No results matching ""