Structures_Graph
[ class tree: Structures_Graph ] [ index: Structures_Graph ] [ all elements ]

Source for file Node.php

Documentation is available at Node.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
  3. // +-----------------------------------------------------------------------------+
  4. // | Copyright (c) 2003 Sérgio Gonçalves Carvalho                                |
  5. // +-----------------------------------------------------------------------------+
  6. // | This file is part of Structures_Graph.                                      |
  7. // |                                                                             |
  8. // | Structures_Graph is free software; you can redistribute it and/or modify    |
  9. // | it under the terms of the GNU Lesser General Public License as published by |
  10. // | the Free Software Foundation; either version 2.1 of the License, or         |
  11. // | (at your option) any later version.                                         |
  12. // |                                                                             |
  13. // | Structures_Graph is distributed in the hope that it will be useful,         |
  14. // | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
  15. // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
  16. // | GNU Lesser General Public License for more details.                         |
  17. // |                                                                             |
  18. // | You should have received a copy of the GNU Lesser General Public License    |
  19. // | along with Structures_Graph; if not, write to the Free Software             |
  20. // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                    |
  21. // | 02111-1307 USA                                                              |
  22. // +-----------------------------------------------------------------------------+
  23. // | Author: Sérgio Carvalho <sergio.carvalho@portugalmail.com>                  |
  24. // +-----------------------------------------------------------------------------+
  25. //
  26. /**
  27.  * This file contains the definition of the Structures_Graph_Node class
  28.  * 
  29.  * @see Structures_Graph_Node
  30.  * @package Structures_Graph
  31.  */
  32.  
  33. /* dependencies {{{ */
  34. /** */
  35. require_once 'PEAR.php';
  36. /** */
  37. require_once 'Structures/Graph.php';
  38. /* }}} */
  39.  
  40. /* class Structures_Graph_Node {{{ */
  41. /**
  42.  * The Structures_Graph_Node class represents a Node that can be member of a
  43.  * graph node set.
  44.  *
  45.  * A graph node can contain data. Under this API, the node contains default data,
  46.  * and key index data. It behaves, thus, both as a regular data node, and as a
  47.  * dictionary (or associative array) node.
  48.  * 
  49.  * Regular data is accessed via getData and setData. Key indexed data is accessed
  50.  * via getMetadata and setMetadata.
  51.  *
  52.  * @author        Sérgio Carvalho <sergio.carvalho@portugalmail.com>
  53.  * @copyright    (c) 2004 by Sérgio Carvalho
  54.  * @package Structures_Graph
  55.  */
  56. /* }}} */
  57.     /* fields {{{ */
  58.     /** 
  59.      * @access private
  60.      */
  61.     var $_data = null;
  62.     /** @access private */
  63.     var $_metadata = array();
  64.     /** @access private */
  65.     var $_arcs = array();
  66.     /** @access private */
  67.     var $_graph = null;
  68.     /* }}} */
  69.  
  70.     /* Constructor {{{ */
  71.     /**
  72.     *
  73.     * Constructor
  74.     *
  75.     * @access    public
  76.     */
  77.     function Structures_Graph_Node({
  78.     }
  79.     /* }}} */
  80.  
  81.     /* getGraph {{{ */
  82.     /**
  83.     *
  84.     * Node graph getter
  85.     *
  86.     * @return    Structures_Graph    Graph where node is stored
  87.     * @access    public
  88.     */
  89.     function &getGraph({
  90.         return $this->_graph;
  91.     }
  92.     /* }}} */
  93.  
  94.     /* setGraph {{{ */
  95.     /**
  96.     *
  97.     * Node graph setter. This method should not be called directly. Use Graph::addNode instead.
  98.     *
  99.     * @param    Structures_Graph   Set the graph for this node.
  100.     * @see      Structures_Graph::addNode()
  101.     * @access    public
  102.     */
  103.     function setGraph(&$graph{
  104.         $this->_graph =$graph;
  105.     }
  106.     /* }}} */
  107.  
  108.     /* getData {{{ */
  109.     /**
  110.     *
  111.     * Node data getter.
  112.     * 
  113.     * Each graph node can contain a reference to one variable. This is the getter for that reference.
  114.     *
  115.     * @return    mixed    Data stored in node
  116.     * @access    public
  117.     */
  118.     function &getData({
  119.         return $this->_data;
  120.     }
  121.     /* }}} */
  122.  
  123.     /* setData {{{ */
  124.     /**
  125.     *
  126.     * Node data setter
  127.     *
  128.     * Each graph node can contain a reference to one variable. This is the setter for that reference.
  129.     *
  130.     * @return    mixed    Data to store in node
  131.     * @access    public
  132.     */
  133.     function setData($data{
  134.         $this->_data =$data;
  135.     }
  136.     /* }}} */
  137.  
  138.     /* metadataKeyExists {{{ */
  139.     /**
  140.     *
  141.     * Test for existence of metadata under a given key.
  142.     *
  143.     * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an
  144.     * associative array or in a dictionary. This method tests whether a given metadata key exists for this node.
  145.     *
  146.     * @param    string    Key to test
  147.     * @return    boolean 
  148.     * @access    public
  149.     */
  150.     function metadataKeyExists($key{
  151.         return array_key_exists($key$this->_metadata);
  152.     }
  153.     /* }}} */
  154.  
  155.     /* getMetadata {{{ */
  156.     /**
  157.     *
  158.     * Node metadata getter
  159.     *
  160.     * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an
  161.     * associative array or in a dictionary. This method gets the data under the given key. If the key does
  162.     * not exist, an error will be thrown, so testing using metadataKeyExists might be needed.
  163.     *
  164.     * @param    string  Key
  165.     * @param    boolean nullIfNonexistent (defaults to false).
  166.     * @return    mixed    Metadata Data stored in node under given key
  167.     * @see      metadataKeyExists
  168.     * @access    public
  169.     */
  170.     function &getMetadata($key$nullIfNonexistent = false{
  171.         if (array_key_exists($key$this->_metadata)) {
  172.             return $this->_metadata[$key];
  173.         else {
  174.             if ($nullIfNonexistent{
  175.                 $a = null;
  176.                 return $a;
  177.             else {
  178.                 $a = Pear::raiseError('Structures_Graph_Node::getMetadata: Requested key does not exist'STRUCTURES_GRAPH_ERROR_GENERIC);
  179.                 return $a;
  180.             }
  181.         }
  182.     }
  183.     /* }}} */
  184.  
  185.     /* unsetMetadata {{{ */
  186.     /**
  187.     *
  188.     * Delete metadata by key
  189.     *
  190.     * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an
  191.     * associative array or in a dictionary. This method removes any data that might be stored under the provided key.
  192.     * If the key does not exist, no error is thrown, so it is safe using this method without testing for key existence.
  193.     *
  194.     * @param    string  Key
  195.     * @access    public
  196.     */
  197.     function unsetMetadata($key{
  198.         if (array_key_exists($key$this->_metadata)) unset($this->_metadata[$key]);
  199.     }
  200.     /* }}} */
  201.  
  202.     /* setMetadata {{{ */
  203.     /**
  204.     *
  205.     * Node metadata setter
  206.     *
  207.     * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an
  208.     * associative array or in a dictionary. This method stores data under the given key. If the key already exists,
  209.     * previously stored data is discarded.
  210.     *
  211.     * @param    string  Key
  212.     * @param    mixed   Data
  213.     * @access    public
  214.     */
  215.     function setMetadata($key$data{
  216.         $this->_metadata[$key=$data;
  217.     }
  218.     /* }}} */
  219.  
  220.     /* _connectTo {{{ */
  221.     /** @access private */
  222.     function _connectTo(&$destinationNode{
  223.         $this->_arcs[=$destinationNode;
  224.     }
  225.     /* }}} */
  226.  
  227.     /* connectTo {{{ */
  228.     /**
  229.     *
  230.     * Connect this node to another one.
  231.     * 
  232.     * If the graph is not directed, the reverse arc, connecting $destinationNode to $this is also created.
  233.     *
  234.     * @param    Structures_Graph Node to connect to
  235.     * @access    public
  236.     */
  237.     function connectTo(&$destinationNode{
  238.         // We only connect to nodes
  239.         if (!is_a($destinationNode'Structures_Graph_Node')) return Pear::raiseError('Structures_Graph_Node::connectTo received an object that is not a Structures_Graph_Node'STRUCTURES_GRAPH_ERROR_GENERIC);
  240.         // Nodes must already be in graphs to be connected
  241.         if ($this->_graph == nullreturn Pear::raiseError('Structures_Graph_Node::connectTo Tried to connect a node that is not in a graph'STRUCTURES_GRAPH_ERROR_GENERIC);
  242.         if ($destinationNode->getGraph(== nullreturn Pear::raiseError('Structures_Graph_Node::connectTo Tried to connect to a node that is not in a graph'STRUCTURES_GRAPH_ERROR_GENERIC);
  243.         // Connect here
  244.         $this->_connectTo($destinationNode);
  245.         // If graph is undirected, connect back
  246.         if (!$this->_graph->isDirected()) {
  247.             $destinationNode->_connectTo($this);
  248.         }
  249.     }
  250.     /* }}} */
  251.  
  252.     /* getNeighbours {{{ */
  253.     /**
  254.     *
  255.     * Return nodes connected to this one.
  256.     * 
  257.     * @return   array   Array of nodes
  258.     * @access    public
  259.     */
  260.     function getNeighbours({
  261.         return $this->_arcs;
  262.     }
  263.     /* }}} */
  264.  
  265.     /* connectsTo {{{ */
  266.     /**
  267.     *
  268.     * Test wether this node has an arc to the target node
  269.     *
  270.     * @return    boolean   True if the two nodes are connected
  271.     * @access    public
  272.     */
  273.     function connectsTo(&$target{
  274.         $copy $target;
  275.         $arcKeys array_keys($this->_arcs);
  276.         foreach($arcKeys as $key{
  277.             /* ZE1 chokes on this expression:
  278.                 if ($target === $arc) return true;
  279.               so, we'll use more convoluted stuff
  280.             */
  281.             $arc =$this->_arcs[$key];
  282.             $target = true;
  283.             if ($arc === true{
  284.                 $target = false;
  285.                 if ($arc === false{
  286.                     $target $copy;
  287.                     return true;
  288.                 }
  289.             }
  290.         }
  291.         $target $copy;
  292.         return false;
  293.     }
  294.     /* }}} */
  295.  
  296.     /* inDegree {{{ */
  297.     /**
  298.     *
  299.     * Calculate the in degree of the node.
  300.     * 
  301.     * The indegree for a node is the number of arcs entering the node. For non directed graphs,
  302.     * the indegree is equal to the outdegree.
  303.     *
  304.     * @return    integer     In degree of the node
  305.     * @access    public
  306.     */
  307.     function inDegree({
  308.         if ($this->_graph == nullreturn 0;
  309.         if (!$this->_graph->isDirected()) return $this->outDegree();
  310.         $result = 0;
  311.         $graphNodes =$this->_graph->getNodes();
  312.         foreach (array_keys($graphNodesas $key{
  313.             if ($graphNodes[$key]->connectsTo($this)) $result++;
  314.         }
  315.         return $result;
  316.         
  317.     }
  318.     /* }}} */
  319.  
  320.     /* outDegree {{{ */
  321.     /**
  322.     *
  323.     * Calculate the out degree of the node.
  324.     *
  325.     * The outdegree for a node is the number of arcs exiting the node. For non directed graphs,
  326.     * the outdegree is always equal to the indegree.
  327.     * 
  328.     * @return    integer     Out degree of the node
  329.     * @access    public
  330.     */
  331.     function outDegree({
  332.         if ($this->_graph == nullreturn 0;
  333.         return sizeof($this->_arcs);
  334.     }
  335.     /* }}} */
  336. }
  337. ?>

Documentation generated on Thu, 08 May 2008 18:00:06 -0400 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.