Bearsampp 2026.9.23
Loading...
Searching...
No Matches
TopologicalSorter.php
Go to the documentation of this file.
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//
31
32require_once 'PEAR.php';
33require_once 'Structures/Graph.php';
34require_once 'Structures/Graph/Node.php';
35require_once 'Structures/Graph/Manipulator/AcyclicTest.php';
36
51{
60 protected static function _nonVisitedInDegree(&$node)
61 {
62 $result = 0;
63 $graphNodes =& $node->_graph->getNodes();
64 foreach (array_keys($graphNodes) as $key) {
65 if ((!$graphNodes[$key]->getMetadata('topological-sort-visited'))
66 && $graphNodes[$key]->connectsTo($node)
67 ) {
68 $result++;
69 }
70 }
71 return $result;
72
73 }
74
82 protected static function _sort(&$graph)
83 {
84 // Mark every node as not visited
85 $nodes =& $graph->getNodes();
86 $nodeKeys = array_keys($nodes);
87 $refGenerator = array();
88 foreach ($nodeKeys as $key) {
89 $refGenerator[] = false;
90 $nodes[$key]->setMetadata(
91 'topological-sort-visited',
92 $refGenerator[sizeof($refGenerator) - 1]
93 );
94 }
95
96 // Iteratively peel off leaf nodes
97 $topologicalLevel = 0;
98 do {
99 // Find out which nodes are leafs (excluding visited nodes)
100 $leafNodes = array();
101 foreach ($nodeKeys as $key) {
102 if ((!$nodes[$key]->getMetadata('topological-sort-visited'))
103 && static::_nonVisitedInDegree($nodes[$key]) == 0
104 ) {
105 $leafNodes[] =& $nodes[$key];
106 }
107 }
108 // Mark leafs as visited
109 $refGenerator[] = $topologicalLevel;
110 for ($i = sizeof($leafNodes) - 1; $i>=0; $i--) {
111 $visited =& $leafNodes[$i]->getMetadata('topological-sort-visited');
112 $visited = true;
113 $leafNodes[$i]->setMetadata('topological-sort-visited', $visited);
114 $leafNodes[$i]->setMetadata(
115 'topological-sort-level',
116 $refGenerator[sizeof($refGenerator) - 1]
117 );
118 }
119 $topologicalLevel++;
120 } while (sizeof($leafNodes) > 0);
121
122 // Cleanup visited marks
123 foreach ($nodeKeys as $key) {
124 $nodes[$key]->unsetMetadata('topological-sort-visited');
125 }
126 }
127
139 public static function sort(&$graph)
140 {
141 // We only sort graphs
142 if (!is_a($graph, 'Structures_Graph')) {
143 return Pear::raiseError(
144 'Structures_Graph_Manipulator_TopologicalSorter::sort received'
145 . ' an object that is not a Structures_Graph',
147 );
148 }
150 return Pear::raiseError(
151 'Structures_Graph_Manipulator_TopologicalSorter::sort'
152 . ' received an graph that has cycles',
154 );
155 }
156
158 $result = array();
159
160 // Fill out result array
161 $nodes =& $graph->getNodes();
162 $nodeKeys = array_keys($nodes);
163 foreach ($nodeKeys as $key) {
164 if (!array_key_exists($nodes[$key]->getMetadata('topological-sort-level'), $result)) {
165 $result[$nodes[$key]->getMetadata('topological-sort-level')]
166 = array();
167 }
168 $result[$nodes[$key]->getMetadata('topological-sort-level')][]
169 =& $nodes[$key];
170 $nodes[$key]->unsetMetadata('topological-sort-level');
171 }
172
173 return $result;
174 }
175}
176?>
const STRUCTURES_GRAPH_ERROR_GENERIC
Definition Graph.php:37
$result