Bearsampp
2026.9.23
Toggle main menu visibility
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
32
require_once
'PEAR.php'
;
33
require_once
'Structures/Graph.php'
;
34
require_once
'Structures/Graph/Node.php'
;
35
require_once
'Structures/Graph/Manipulator/AcyclicTest.php'
;
36
50
class
Structures_Graph_Manipulator_TopologicalSorter
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'
,
146
STRUCTURES_GRAPH_ERROR_GENERIC
147
);
148
}
149
if
(!
Structures_Graph_Manipulator_AcyclicTest::isAcyclic
($graph)) {
150
return
Pear::raiseError(
151
'Structures_Graph_Manipulator_TopologicalSorter::sort'
152
.
' received an graph that has cycles'
,
153
STRUCTURES_GRAPH_ERROR_GENERIC
154
);
155
}
156
157
Structures_Graph_Manipulator_TopologicalSorter::_sort
($graph);
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
?>
STRUCTURES_GRAPH_ERROR_GENERIC
const STRUCTURES_GRAPH_ERROR_GENERIC
Definition
Graph.php:37
$result
$result
Definition
ajax.apache.php:19
Structures_Graph_Manipulator_AcyclicTest\isAcyclic
static isAcyclic(&$graph)
Definition
AcyclicTest.php:124
Structures_Graph_Manipulator_TopologicalSorter
Definition
TopologicalSorter.php:51
Structures_Graph_Manipulator_TopologicalSorter\_sort
static _sort(&$graph)
Definition
TopologicalSorter.php:82
Structures_Graph_Manipulator_TopologicalSorter\_nonVisitedInDegree
static _nonVisitedInDegree(&$node)
Definition
TopologicalSorter.php:60
Structures_Graph_Manipulator_TopologicalSorter\sort
static sort(&$graph)
Definition
TopologicalSorter.php:139
sandbox
core
libs
php
pear
pear
Structures
Graph
Manipulator
TopologicalSorter.php
Generated by
1.17.0