6 * $Date: 2012-07-07 17:14:54 +0200 (Sa, 07. Jul 2012) $
7 ***************************************************************/
10 * \brief Implementation of st-numbering algorithm
12 * \author Sebastian Leipert
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
44 #include <ogdf/basic/simple_graph_alg.h>
45 #include <ogdf/basic/Stack.h>
46 #include <ogdf/basic/EdgeArray.h>
47 #include <ogdf/basic/NodeArray.h>
51 // Needed by the function stNumber
58 NodeArray
<edge
> &dfsInEdge
,
59 NodeArray
<edge
> &followLowPath
);
61 // Needed by the function stNumber
63 StackPure
<node
> &path
,
66 NodeArray
<bool> &markedNode
,
67 EdgeArray
<bool> &markedEdge
,
69 NodeArray
<edge
> &dfsInEdge
,
70 NodeArray
<edge
> &followLowPath
);
72 // Computes an st-Numbering.
73 // Precondition: G must be biconnected and simple.
74 // Exception: the Graph is allowed to have isolated nodes.
75 // The st-numbers are stored in NodeArray. Return value is
76 // the number t. It is 0, if the computation was unsuccessful.
77 // The nodes s and t may be specified. In this case
78 // s and t have to be adjacent.
79 // If s and t are set 0 and parameter randomized is set to true,
80 // the st edge is chosen to be a random edge in G.
82 int stNumber(const Graph
&G
,
83 NodeArray
<int> &numbering
,
91 // Stores for every vertex its LOW number
92 NodeArray
<int> low(G
,0);
93 // Stores for every vertex ist DFN number
94 NodeArray
<int> dfn(G
,0);
96 // Stores for every vertex if it has been visited dsuring the st-numbering
97 NodeArray
<bool> markedNode(G
,false);
98 // Stores for every edge if it has been visited dsuring the st-numbering
99 EdgeArray
<bool> markedEdge(G
,false);
101 // Stores for every node its ingoing edge of the dfs tree.
102 NodeArray
<edge
> dfsInEdge(G
,0);
104 // Stores a path of vertices that have not been visited.
105 StackPure
<node
> path
;
107 //Stores for every node the outgoing, first edge on the
108 // path that defines the low number of the node.
109 NodeArray
<edge
> followLowPath(G
,0);
117 forall_adj_edges(st
,s
)
118 if (st
->opposite(s
) == t
)
128 st
= s
->firstAdj()->theEdge();
133 st
= t
->firstAdj()->theEdge();
139 // chose a random edge in G
141 if(!st
) // graph is empty?
151 st
= s
->firstAdj()->theEdge();
161 // Compute the DFN and LOW numbers
165 stSearch(G
,s
,count
,low
,dfn
,dfsInEdge
,followLowPath
);
169 markedNode
[s
] = true;
170 markedNode
[t
] = true;
171 markedEdge
[st
] = true;
173 StackPure
<node
> nodeStack
; // nodeStack stores the vertices during the
174 // computation of the st-numbering.
182 if (!stPath(path
,v
,adj
,markedNode
,markedEdge
,dfn
,dfsInEdge
,followLowPath
))
184 numbering
[v
] = count
;
190 while (!path
.empty())
191 nodeStack
.push(path
.pop());
195 numbering
[t
] = count
;
200 // Computes the DFN and LOW numbers of a biconnected component
208 NodeArray
<edge
> &dfsInEdge
,
209 NodeArray
<edge
> &followLowPath
)
217 forall_adj_edges(e
,v
)
219 adj
= e
->opposite(v
);
221 if(!dfn
[adj
]) // node not visited yet
224 stSearch(G
,adj
,count
,low
,dfn
,dfsInEdge
,followLowPath
);
225 if (low
[v
] > low
[adj
])
228 followLowPath
[v
] = e
;
231 else if (low
[v
] > dfn
[adj
])
234 followLowPath
[v
] = e
;
240 bool stPath(StackPure
<node
> &path
,
243 NodeArray
<bool> &markedNode
,
244 EdgeArray
<bool> &markedEdge
,
246 NodeArray
<edge
> &dfsInEdge
,
247 NodeArray
<edge
> &followLowPath
)
254 adj
= v
->firstAdj(); // no edge has been visited yet
260 markedEdge
[e
] = true;
264 if (dfsInEdge
[w
] == e
)
267 while (!markedNode
[w
])
269 e
= followLowPath
[w
];
271 markedNode
[w
] = true;
272 markedEdge
[e
] = true;
277 else if (dfn
[v
] < dfn
[w
])
280 while (!markedNode
[w
])
284 markedNode
[w
] = true;
285 markedEdge
[e
] = true;
297 bool testSTnumber(const Graph
&G
, NodeArray
<int> &st_no
,int max
)
299 bool foundLow
= false;
300 bool foundHigh
= false;
306 if (v
->degree() == 0)
309 foundHigh
= foundLow
= 0;
315 if (st_no
[adj
->theEdge()->opposite(v
)] == max
)
316 foundLow
= foundHigh
= 1;
320 else if (st_no
[v
] == max
)
325 if (st_no
[adj
->theEdge()->opposite(v
)] == 1)
326 foundLow
= foundHigh
= 1;
335 if (st_no
[adj
->theEdge()->opposite(v
)] < st_no
[v
])
337 else if (st_no
[adj
->theEdge()->opposite(v
)] > st_no
[v
])
341 if (!foundLow
|| !foundHigh
)