0
3
0
| ... | ... |
@@ -1219,193 +1219,193 @@ |
| 1219 | 1219 |
/// \brief Called when an arc is examined but its target node is |
| 1220 | 1220 |
/// already discovered. |
| 1221 | 1221 |
/// |
| 1222 | 1222 |
/// This function is called when an arc is examined but its target node is |
| 1223 | 1223 |
/// already discovered. |
| 1224 | 1224 |
void examine(const Arc& arc) {}
|
| 1225 | 1225 |
}; |
| 1226 | 1226 |
#else |
| 1227 | 1227 |
template <typename _Digraph> |
| 1228 | 1228 |
struct BfsVisitor {
|
| 1229 | 1229 |
typedef _Digraph Digraph; |
| 1230 | 1230 |
typedef typename Digraph::Arc Arc; |
| 1231 | 1231 |
typedef typename Digraph::Node Node; |
| 1232 | 1232 |
void start(const Node&) {}
|
| 1233 | 1233 |
void reach(const Node&) {}
|
| 1234 | 1234 |
void process(const Node&) {}
|
| 1235 | 1235 |
void discover(const Arc&) {}
|
| 1236 | 1236 |
void examine(const Arc&) {}
|
| 1237 | 1237 |
|
| 1238 | 1238 |
template <typename _Visitor> |
| 1239 | 1239 |
struct Constraints {
|
| 1240 | 1240 |
void constraints() {
|
| 1241 | 1241 |
Arc arc; |
| 1242 | 1242 |
Node node; |
| 1243 | 1243 |
visitor.start(node); |
| 1244 | 1244 |
visitor.reach(node); |
| 1245 | 1245 |
visitor.process(node); |
| 1246 | 1246 |
visitor.discover(arc); |
| 1247 | 1247 |
visitor.examine(arc); |
| 1248 | 1248 |
} |
| 1249 | 1249 |
_Visitor& visitor; |
| 1250 | 1250 |
}; |
| 1251 | 1251 |
}; |
| 1252 | 1252 |
#endif |
| 1253 | 1253 |
|
| 1254 | 1254 |
/// \brief Default traits class of BfsVisit class. |
| 1255 | 1255 |
/// |
| 1256 | 1256 |
/// Default traits class of BfsVisit class. |
| 1257 | 1257 |
/// \tparam _Digraph The type of the digraph the algorithm runs on. |
| 1258 | 1258 |
template<class _Digraph> |
| 1259 | 1259 |
struct BfsVisitDefaultTraits {
|
| 1260 | 1260 |
|
| 1261 | 1261 |
/// \brief The type of the digraph the algorithm runs on. |
| 1262 | 1262 |
typedef _Digraph Digraph; |
| 1263 | 1263 |
|
| 1264 | 1264 |
/// \brief The type of the map that indicates which nodes are reached. |
| 1265 | 1265 |
/// |
| 1266 | 1266 |
/// The type of the map that indicates which nodes are reached. |
| 1267 | 1267 |
/// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept. |
| 1268 | 1268 |
typedef typename Digraph::template NodeMap<bool> ReachedMap; |
| 1269 | 1269 |
|
| 1270 | 1270 |
/// \brief Instantiates a \ref ReachedMap. |
| 1271 | 1271 |
/// |
| 1272 | 1272 |
/// This function instantiates a \ref ReachedMap. |
| 1273 | 1273 |
/// \param digraph is the digraph, to which |
| 1274 | 1274 |
/// we would like to define the \ref ReachedMap. |
| 1275 | 1275 |
static ReachedMap *createReachedMap(const Digraph &digraph) {
|
| 1276 | 1276 |
return new ReachedMap(digraph); |
| 1277 | 1277 |
} |
| 1278 | 1278 |
|
| 1279 | 1279 |
}; |
| 1280 | 1280 |
|
| 1281 | 1281 |
/// \ingroup search |
| 1282 | 1282 |
/// |
| 1283 | 1283 |
/// \brief %BFS algorithm class with visitor interface. |
| 1284 | 1284 |
/// |
| 1285 | 1285 |
/// This class provides an efficient implementation of the %BFS algorithm |
| 1286 | 1286 |
/// with visitor interface. |
| 1287 | 1287 |
/// |
| 1288 | 1288 |
/// The %BfsVisit class provides an alternative interface to the Bfs |
| 1289 | 1289 |
/// class. It works with callback mechanism, the BfsVisit object calls |
| 1290 | 1290 |
/// the member functions of the \c Visitor class on every BFS event. |
| 1291 | 1291 |
/// |
| 1292 | 1292 |
/// This interface of the BFS algorithm should be used in special cases |
| 1293 | 1293 |
/// when extra actions have to be performed in connection with certain |
| 1294 | 1294 |
/// events of the BFS algorithm. Otherwise consider to use Bfs or bfs() |
| 1295 | 1295 |
/// instead. |
| 1296 | 1296 |
/// |
| 1297 | 1297 |
/// \tparam _Digraph The type of the digraph the algorithm runs on. |
| 1298 | 1298 |
/// The default value is |
| 1299 | 1299 |
/// \ref ListDigraph. The value of _Digraph is not used directly by |
| 1300 | 1300 |
/// \ref BfsVisit, it is only passed to \ref BfsVisitDefaultTraits. |
| 1301 | 1301 |
/// \tparam _Visitor The Visitor type that is used by the algorithm. |
| 1302 | 1302 |
/// \ref BfsVisitor "BfsVisitor<_Digraph>" is an empty visitor, which |
| 1303 | 1303 |
/// does not observe the BFS events. If you want to observe the BFS |
| 1304 | 1304 |
/// events, you should implement your own visitor class. |
| 1305 | 1305 |
/// \tparam _Traits Traits class to set various data types used by the |
| 1306 | 1306 |
/// algorithm. The default traits class is |
| 1307 | 1307 |
/// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>". |
| 1308 | 1308 |
/// See \ref BfsVisitDefaultTraits for the documentation of |
| 1309 | 1309 |
/// a BFS visit traits class. |
| 1310 | 1310 |
#ifdef DOXYGEN |
| 1311 | 1311 |
template <typename _Digraph, typename _Visitor, typename _Traits> |
| 1312 | 1312 |
#else |
| 1313 | 1313 |
template <typename _Digraph = ListDigraph, |
| 1314 | 1314 |
typename _Visitor = BfsVisitor<_Digraph>, |
| 1315 |
typename _Traits = |
|
| 1315 |
typename _Traits = BfsVisitDefaultTraits<_Digraph> > |
|
| 1316 | 1316 |
#endif |
| 1317 | 1317 |
class BfsVisit {
|
| 1318 | 1318 |
public: |
| 1319 | 1319 |
|
| 1320 | 1320 |
///The traits class. |
| 1321 | 1321 |
typedef _Traits Traits; |
| 1322 | 1322 |
|
| 1323 | 1323 |
///The type of the digraph the algorithm runs on. |
| 1324 | 1324 |
typedef typename Traits::Digraph Digraph; |
| 1325 | 1325 |
|
| 1326 | 1326 |
///The visitor type used by the algorithm. |
| 1327 | 1327 |
typedef _Visitor Visitor; |
| 1328 | 1328 |
|
| 1329 | 1329 |
///The type of the map that indicates which nodes are reached. |
| 1330 | 1330 |
typedef typename Traits::ReachedMap ReachedMap; |
| 1331 | 1331 |
|
| 1332 | 1332 |
private: |
| 1333 | 1333 |
|
| 1334 | 1334 |
typedef typename Digraph::Node Node; |
| 1335 | 1335 |
typedef typename Digraph::NodeIt NodeIt; |
| 1336 | 1336 |
typedef typename Digraph::Arc Arc; |
| 1337 | 1337 |
typedef typename Digraph::OutArcIt OutArcIt; |
| 1338 | 1338 |
|
| 1339 | 1339 |
//Pointer to the underlying digraph. |
| 1340 | 1340 |
const Digraph *_digraph; |
| 1341 | 1341 |
//Pointer to the visitor object. |
| 1342 | 1342 |
Visitor *_visitor; |
| 1343 | 1343 |
//Pointer to the map of reached status of the nodes. |
| 1344 | 1344 |
ReachedMap *_reached; |
| 1345 | 1345 |
//Indicates if _reached is locally allocated (true) or not. |
| 1346 | 1346 |
bool local_reached; |
| 1347 | 1347 |
|
| 1348 | 1348 |
std::vector<typename Digraph::Node> _list; |
| 1349 | 1349 |
int _list_front, _list_back; |
| 1350 | 1350 |
|
| 1351 | 1351 |
//Creates the maps if necessary. |
| 1352 | 1352 |
void create_maps() {
|
| 1353 | 1353 |
if(!_reached) {
|
| 1354 | 1354 |
local_reached = true; |
| 1355 | 1355 |
_reached = Traits::createReachedMap(*_digraph); |
| 1356 | 1356 |
} |
| 1357 | 1357 |
} |
| 1358 | 1358 |
|
| 1359 | 1359 |
protected: |
| 1360 | 1360 |
|
| 1361 | 1361 |
BfsVisit() {}
|
| 1362 | 1362 |
|
| 1363 | 1363 |
public: |
| 1364 | 1364 |
|
| 1365 | 1365 |
typedef BfsVisit Create; |
| 1366 | 1366 |
|
| 1367 | 1367 |
/// \name Named template parameters |
| 1368 | 1368 |
|
| 1369 | 1369 |
///@{
|
| 1370 | 1370 |
template <class T> |
| 1371 | 1371 |
struct SetReachedMapTraits : public Traits {
|
| 1372 | 1372 |
typedef T ReachedMap; |
| 1373 | 1373 |
static ReachedMap *createReachedMap(const Digraph &digraph) {
|
| 1374 | 1374 |
LEMON_ASSERT(false, "ReachedMap is not initialized"); |
| 1375 | 1375 |
return 0; // ignore warnings |
| 1376 | 1376 |
} |
| 1377 | 1377 |
}; |
| 1378 | 1378 |
/// \brief \ref named-templ-param "Named parameter" for setting |
| 1379 | 1379 |
/// ReachedMap type. |
| 1380 | 1380 |
/// |
| 1381 | 1381 |
/// \ref named-templ-param "Named parameter" for setting ReachedMap type. |
| 1382 | 1382 |
template <class T> |
| 1383 | 1383 |
struct SetReachedMap : public BfsVisit< Digraph, Visitor, |
| 1384 | 1384 |
SetReachedMapTraits<T> > {
|
| 1385 | 1385 |
typedef BfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create; |
| 1386 | 1386 |
}; |
| 1387 | 1387 |
///@} |
| 1388 | 1388 |
|
| 1389 | 1389 |
public: |
| 1390 | 1390 |
|
| 1391 | 1391 |
/// \brief Constructor. |
| 1392 | 1392 |
/// |
| 1393 | 1393 |
/// Constructor. |
| 1394 | 1394 |
/// |
| 1395 | 1395 |
/// \param digraph The digraph the algorithm runs on. |
| 1396 | 1396 |
/// \param visitor The visitor object of the algorithm. |
| 1397 | 1397 |
BfsVisit(const Digraph& digraph, Visitor& visitor) |
| 1398 | 1398 |
: _digraph(&digraph), _visitor(&visitor), |
| 1399 | 1399 |
_reached(0), local_reached(false) {}
|
| 1400 | 1400 |
|
| 1401 | 1401 |
/// \brief Destructor. |
| 1402 | 1402 |
~BfsVisit() {
|
| 1403 | 1403 |
if(local_reached) delete _reached; |
| 1404 | 1404 |
} |
| 1405 | 1405 |
|
| 1406 | 1406 |
/// \brief Sets the map that indicates which nodes are reached. |
| 1407 | 1407 |
/// |
| 1408 | 1408 |
/// Sets the map that indicates which nodes are reached. |
| 1409 | 1409 |
/// If you don't use this function before calling \ref run(), |
| 1410 | 1410 |
/// it will allocate one. The destructor deallocates this |
| 1411 | 1411 |
/// automatically allocated map, of course. |
| ... | ... |
@@ -205,230 +205,230 @@ |
| 205 | 205 |
return Parent::arcFromId(ix); |
| 206 | 206 |
} |
| 207 | 207 |
|
| 208 | 208 |
int id(const Node &n) const {
|
| 209 | 209 |
return Parent::id(n); |
| 210 | 210 |
} |
| 211 | 211 |
|
| 212 | 212 |
int id(const Edge &e) const {
|
| 213 | 213 |
return Parent::id(e); |
| 214 | 214 |
} |
| 215 | 215 |
|
| 216 | 216 |
int id(const Arc &e) const {
|
| 217 | 217 |
return 2 * Parent::id(e) + int(e.forward); |
| 218 | 218 |
} |
| 219 | 219 |
|
| 220 | 220 |
int maxNodeId() const {
|
| 221 | 221 |
return Parent::maxNodeId(); |
| 222 | 222 |
} |
| 223 | 223 |
|
| 224 | 224 |
int maxArcId() const {
|
| 225 | 225 |
return 2 * Parent::maxArcId() + 1; |
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 | 228 |
int maxEdgeId() const {
|
| 229 | 229 |
return Parent::maxArcId(); |
| 230 | 230 |
} |
| 231 | 231 |
|
| 232 | 232 |
int arcNum() const {
|
| 233 | 233 |
return 2 * Parent::arcNum(); |
| 234 | 234 |
} |
| 235 | 235 |
|
| 236 | 236 |
int edgeNum() const {
|
| 237 | 237 |
return Parent::arcNum(); |
| 238 | 238 |
} |
| 239 | 239 |
|
| 240 | 240 |
Arc findArc(Node s, Node t, Arc p = INVALID) const {
|
| 241 | 241 |
if (p == INVALID) {
|
| 242 | 242 |
Edge arc = Parent::findArc(s, t); |
| 243 | 243 |
if (arc != INVALID) return direct(arc, true); |
| 244 | 244 |
arc = Parent::findArc(t, s); |
| 245 | 245 |
if (arc != INVALID) return direct(arc, false); |
| 246 | 246 |
} else if (direction(p)) {
|
| 247 | 247 |
Edge arc = Parent::findArc(s, t, p); |
| 248 | 248 |
if (arc != INVALID) return direct(arc, true); |
| 249 | 249 |
arc = Parent::findArc(t, s); |
| 250 | 250 |
if (arc != INVALID) return direct(arc, false); |
| 251 | 251 |
} else {
|
| 252 | 252 |
Edge arc = Parent::findArc(t, s, p); |
| 253 | 253 |
if (arc != INVALID) return direct(arc, false); |
| 254 | 254 |
} |
| 255 | 255 |
return INVALID; |
| 256 | 256 |
} |
| 257 | 257 |
|
| 258 | 258 |
Edge findEdge(Node s, Node t, Edge p = INVALID) const {
|
| 259 | 259 |
if (s != t) {
|
| 260 | 260 |
if (p == INVALID) {
|
| 261 | 261 |
Edge arc = Parent::findArc(s, t); |
| 262 | 262 |
if (arc != INVALID) return arc; |
| 263 | 263 |
arc = Parent::findArc(t, s); |
| 264 | 264 |
if (arc != INVALID) return arc; |
| 265 | 265 |
} else if (Parent::s(p) == s) {
|
| 266 | 266 |
Edge arc = Parent::findArc(s, t, p); |
| 267 | 267 |
if (arc != INVALID) return arc; |
| 268 | 268 |
arc = Parent::findArc(t, s); |
| 269 | 269 |
if (arc != INVALID) return arc; |
| 270 | 270 |
} else {
|
| 271 | 271 |
Edge arc = Parent::findArc(t, s, p); |
| 272 | 272 |
if (arc != INVALID) return arc; |
| 273 | 273 |
} |
| 274 | 274 |
} else {
|
| 275 | 275 |
return Parent::findArc(s, t, p); |
| 276 | 276 |
} |
| 277 | 277 |
return INVALID; |
| 278 | 278 |
} |
| 279 | 279 |
}; |
| 280 | 280 |
|
| 281 | 281 |
template <typename Base> |
| 282 | 282 |
class BidirBpGraphExtender : public Base {
|
| 283 | 283 |
public: |
| 284 | 284 |
typedef Base Parent; |
| 285 | 285 |
typedef BidirBpGraphExtender Digraph; |
| 286 | 286 |
|
| 287 | 287 |
typedef typename Parent::Node Node; |
| 288 | 288 |
typedef typename Parent::Edge Edge; |
| 289 | 289 |
|
| 290 | 290 |
|
| 291 | 291 |
using Parent::first; |
| 292 | 292 |
using Parent::next; |
| 293 | 293 |
|
| 294 | 294 |
using Parent::id; |
| 295 | 295 |
|
| 296 | 296 |
class Red : public Node {
|
| 297 | 297 |
friend class BidirBpGraphExtender; |
| 298 | 298 |
public: |
| 299 | 299 |
Red() {}
|
| 300 | 300 |
Red(const Node& node) : Node(node) {
|
| 301 |
LEMON_ASSERT(Parent::red(node) || node == INVALID, |
|
| 302 |
typename Parent::NodeSetError()); |
|
| 301 |
LEMON_DEBUG(Parent::red(node) || node == INVALID, |
|
| 302 |
typename Parent::NodeSetError()); |
|
| 303 | 303 |
} |
| 304 | 304 |
Red& operator=(const Node& node) {
|
| 305 |
LEMON_ASSERT(Parent::red(node) || node == INVALID, |
|
| 306 |
typename Parent::NodeSetError()); |
|
| 305 |
LEMON_DEBUG(Parent::red(node) || node == INVALID, |
|
| 306 |
typename Parent::NodeSetError()); |
|
| 307 | 307 |
Node::operator=(node); |
| 308 | 308 |
return *this; |
| 309 | 309 |
} |
| 310 | 310 |
Red(Invalid) : Node(INVALID) {}
|
| 311 | 311 |
Red& operator=(Invalid) {
|
| 312 | 312 |
Node::operator=(INVALID); |
| 313 | 313 |
return *this; |
| 314 | 314 |
} |
| 315 | 315 |
}; |
| 316 | 316 |
|
| 317 | 317 |
void first(Red& node) const {
|
| 318 | 318 |
Parent::firstRed(static_cast<Node&>(node)); |
| 319 | 319 |
} |
| 320 | 320 |
void next(Red& node) const {
|
| 321 | 321 |
Parent::nextRed(static_cast<Node&>(node)); |
| 322 | 322 |
} |
| 323 | 323 |
|
| 324 | 324 |
int id(const Red& node) const {
|
| 325 | 325 |
return Parent::redId(node); |
| 326 | 326 |
} |
| 327 | 327 |
|
| 328 | 328 |
class Blue : public Node {
|
| 329 | 329 |
friend class BidirBpGraphExtender; |
| 330 | 330 |
public: |
| 331 | 331 |
Blue() {}
|
| 332 | 332 |
Blue(const Node& node) : Node(node) {
|
| 333 |
LEMON_ASSERT(Parent::blue(node) || node == INVALID, |
|
| 334 |
typename Parent::NodeSetError()); |
|
| 333 |
LEMON_DEBUG(Parent::blue(node) || node == INVALID, |
|
| 334 |
typename Parent::NodeSetError()); |
|
| 335 | 335 |
} |
| 336 | 336 |
Blue& operator=(const Node& node) {
|
| 337 |
LEMON_ASSERT(Parent::blue(node) || node == INVALID, |
|
| 338 |
typename Parent::NodeSetError()); |
|
| 337 |
LEMON_DEBUG(Parent::blue(node) || node == INVALID, |
|
| 338 |
typename Parent::NodeSetError()); |
|
| 339 | 339 |
Node::operator=(node); |
| 340 | 340 |
return *this; |
| 341 | 341 |
} |
| 342 | 342 |
Blue(Invalid) : Node(INVALID) {}
|
| 343 | 343 |
Blue& operator=(Invalid) {
|
| 344 | 344 |
Node::operator=(INVALID); |
| 345 | 345 |
return *this; |
| 346 | 346 |
} |
| 347 | 347 |
}; |
| 348 | 348 |
|
| 349 | 349 |
void first(Blue& node) const {
|
| 350 | 350 |
Parent::firstBlue(static_cast<Node&>(node)); |
| 351 | 351 |
} |
| 352 | 352 |
void next(Blue& node) const {
|
| 353 | 353 |
Parent::nextBlue(static_cast<Node&>(node)); |
| 354 | 354 |
} |
| 355 | 355 |
|
| 356 | 356 |
int id(const Blue& node) const {
|
| 357 | 357 |
return Parent::redId(node); |
| 358 | 358 |
} |
| 359 | 359 |
|
| 360 | 360 |
Node source(const Edge& arc) const {
|
| 361 | 361 |
return red(arc); |
| 362 | 362 |
} |
| 363 | 363 |
Node target(const Edge& arc) const {
|
| 364 | 364 |
return blue(arc); |
| 365 | 365 |
} |
| 366 | 366 |
|
| 367 | 367 |
void firstInc(Edge& arc, bool& dir, const Node& node) const {
|
| 368 | 368 |
if (Parent::red(node)) {
|
| 369 | 369 |
Parent::firstFromRed(arc, node); |
| 370 | 370 |
dir = true; |
| 371 | 371 |
} else {
|
| 372 | 372 |
Parent::firstFromBlue(arc, node); |
| 373 | 373 |
dir = static_cast<Edge&>(arc) == INVALID; |
| 374 | 374 |
} |
| 375 | 375 |
} |
| 376 | 376 |
void nextInc(Edge& arc, bool& dir) const {
|
| 377 | 377 |
if (dir) {
|
| 378 | 378 |
Parent::nextFromRed(arc); |
| 379 | 379 |
} else {
|
| 380 | 380 |
Parent::nextFromBlue(arc); |
| 381 | 381 |
if (arc == INVALID) dir = true; |
| 382 | 382 |
} |
| 383 | 383 |
} |
| 384 | 384 |
|
| 385 | 385 |
class Arc : public Edge {
|
| 386 | 386 |
friend class BidirBpGraphExtender; |
| 387 | 387 |
protected: |
| 388 | 388 |
bool forward; |
| 389 | 389 |
|
| 390 | 390 |
Arc(const Edge& arc, bool _forward) |
| 391 | 391 |
: Edge(arc), forward(_forward) {}
|
| 392 | 392 |
|
| 393 | 393 |
public: |
| 394 | 394 |
Arc() {}
|
| 395 | 395 |
Arc (Invalid) : Edge(INVALID), forward(true) {}
|
| 396 | 396 |
bool operator==(const Arc& i) const {
|
| 397 | 397 |
return Edge::operator==(i) && forward == i.forward; |
| 398 | 398 |
} |
| 399 | 399 |
bool operator!=(const Arc& i) const {
|
| 400 | 400 |
return Edge::operator!=(i) || forward != i.forward; |
| 401 | 401 |
} |
| 402 | 402 |
bool operator<(const Arc& i) const {
|
| 403 | 403 |
return Edge::operator<(i) || |
| 404 | 404 |
(!(i.forward<forward) && Edge(*this)<Edge(i)); |
| 405 | 405 |
} |
| 406 | 406 |
}; |
| 407 | 407 |
|
| 408 | 408 |
void first(Arc& arc) const {
|
| 409 | 409 |
Parent::first(static_cast<Edge&>(arc)); |
| 410 | 410 |
arc.forward = true; |
| 411 | 411 |
} |
| 412 | 412 |
|
| 413 | 413 |
void next(Arc& arc) const {
|
| 414 | 414 |
if (!arc.forward) {
|
| 415 | 415 |
Parent::next(static_cast<Edge&>(arc)); |
| 416 | 416 |
} |
| 417 | 417 |
arc.forward = !arc.forward; |
| 418 | 418 |
} |
| 419 | 419 |
|
| 420 | 420 |
void firstOut(Arc& arc, const Node& node) const {
|
| 421 | 421 |
if (Parent::red(node)) {
|
| 422 | 422 |
Parent::firstFromRed(arc, node); |
| 423 | 423 |
arc.forward = true; |
| 424 | 424 |
} else {
|
| 425 | 425 |
Parent::firstFromBlue(arc, node); |
| 426 | 426 |
arc.forward = static_cast<Edge&>(arc) == INVALID; |
| 427 | 427 |
} |
| 428 | 428 |
} |
| 429 | 429 |
void nextOut(Arc& arc) const {
|
| 430 | 430 |
if (arc.forward) {
|
| 431 | 431 |
Parent::nextFromRed(arc); |
| 432 | 432 |
} else {
|
| 433 | 433 |
Parent::nextFromBlue(arc); |
| 434 | 434 |
arc.forward = static_cast<Edge&>(arc) == INVALID; |
| ... | ... |
@@ -1165,193 +1165,193 @@ |
| 1165 | 1165 |
/// This function is called when the DFS steps back on an arc. |
| 1166 | 1166 |
void backtrack(const Arc& arc) {}
|
| 1167 | 1167 |
}; |
| 1168 | 1168 |
#else |
| 1169 | 1169 |
template <typename _Digraph> |
| 1170 | 1170 |
struct DfsVisitor {
|
| 1171 | 1171 |
typedef _Digraph Digraph; |
| 1172 | 1172 |
typedef typename Digraph::Arc Arc; |
| 1173 | 1173 |
typedef typename Digraph::Node Node; |
| 1174 | 1174 |
void start(const Node&) {}
|
| 1175 | 1175 |
void stop(const Node&) {}
|
| 1176 | 1176 |
void reach(const Node&) {}
|
| 1177 | 1177 |
void discover(const Arc&) {}
|
| 1178 | 1178 |
void examine(const Arc&) {}
|
| 1179 | 1179 |
void leave(const Node&) {}
|
| 1180 | 1180 |
void backtrack(const Arc&) {}
|
| 1181 | 1181 |
|
| 1182 | 1182 |
template <typename _Visitor> |
| 1183 | 1183 |
struct Constraints {
|
| 1184 | 1184 |
void constraints() {
|
| 1185 | 1185 |
Arc arc; |
| 1186 | 1186 |
Node node; |
| 1187 | 1187 |
visitor.start(node); |
| 1188 | 1188 |
visitor.stop(arc); |
| 1189 | 1189 |
visitor.reach(node); |
| 1190 | 1190 |
visitor.discover(arc); |
| 1191 | 1191 |
visitor.examine(arc); |
| 1192 | 1192 |
visitor.leave(node); |
| 1193 | 1193 |
visitor.backtrack(arc); |
| 1194 | 1194 |
} |
| 1195 | 1195 |
_Visitor& visitor; |
| 1196 | 1196 |
}; |
| 1197 | 1197 |
}; |
| 1198 | 1198 |
#endif |
| 1199 | 1199 |
|
| 1200 | 1200 |
/// \brief Default traits class of DfsVisit class. |
| 1201 | 1201 |
/// |
| 1202 | 1202 |
/// Default traits class of DfsVisit class. |
| 1203 | 1203 |
/// \tparam _Digraph The type of the digraph the algorithm runs on. |
| 1204 | 1204 |
template<class _Digraph> |
| 1205 | 1205 |
struct DfsVisitDefaultTraits {
|
| 1206 | 1206 |
|
| 1207 | 1207 |
/// \brief The type of the digraph the algorithm runs on. |
| 1208 | 1208 |
typedef _Digraph Digraph; |
| 1209 | 1209 |
|
| 1210 | 1210 |
/// \brief The type of the map that indicates which nodes are reached. |
| 1211 | 1211 |
/// |
| 1212 | 1212 |
/// The type of the map that indicates which nodes are reached. |
| 1213 | 1213 |
/// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept. |
| 1214 | 1214 |
typedef typename Digraph::template NodeMap<bool> ReachedMap; |
| 1215 | 1215 |
|
| 1216 | 1216 |
/// \brief Instantiates a \ref ReachedMap. |
| 1217 | 1217 |
/// |
| 1218 | 1218 |
/// This function instantiates a \ref ReachedMap. |
| 1219 | 1219 |
/// \param digraph is the digraph, to which |
| 1220 | 1220 |
/// we would like to define the \ref ReachedMap. |
| 1221 | 1221 |
static ReachedMap *createReachedMap(const Digraph &digraph) {
|
| 1222 | 1222 |
return new ReachedMap(digraph); |
| 1223 | 1223 |
} |
| 1224 | 1224 |
|
| 1225 | 1225 |
}; |
| 1226 | 1226 |
|
| 1227 | 1227 |
/// \ingroup search |
| 1228 | 1228 |
/// |
| 1229 | 1229 |
/// \brief %DFS algorithm class with visitor interface. |
| 1230 | 1230 |
/// |
| 1231 | 1231 |
/// This class provides an efficient implementation of the %DFS algorithm |
| 1232 | 1232 |
/// with visitor interface. |
| 1233 | 1233 |
/// |
| 1234 | 1234 |
/// The %DfsVisit class provides an alternative interface to the Dfs |
| 1235 | 1235 |
/// class. It works with callback mechanism, the DfsVisit object calls |
| 1236 | 1236 |
/// the member functions of the \c Visitor class on every DFS event. |
| 1237 | 1237 |
/// |
| 1238 | 1238 |
/// This interface of the DFS algorithm should be used in special cases |
| 1239 | 1239 |
/// when extra actions have to be performed in connection with certain |
| 1240 | 1240 |
/// events of the DFS algorithm. Otherwise consider to use Dfs or dfs() |
| 1241 | 1241 |
/// instead. |
| 1242 | 1242 |
/// |
| 1243 | 1243 |
/// \tparam _Digraph The type of the digraph the algorithm runs on. |
| 1244 | 1244 |
/// The default value is |
| 1245 | 1245 |
/// \ref ListDigraph. The value of _Digraph is not used directly by |
| 1246 | 1246 |
/// \ref DfsVisit, it is only passed to \ref DfsVisitDefaultTraits. |
| 1247 | 1247 |
/// \tparam _Visitor The Visitor type that is used by the algorithm. |
| 1248 | 1248 |
/// \ref DfsVisitor "DfsVisitor<_Digraph>" is an empty visitor, which |
| 1249 | 1249 |
/// does not observe the DFS events. If you want to observe the DFS |
| 1250 | 1250 |
/// events, you should implement your own visitor class. |
| 1251 | 1251 |
/// \tparam _Traits Traits class to set various data types used by the |
| 1252 | 1252 |
/// algorithm. The default traits class is |
| 1253 | 1253 |
/// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>". |
| 1254 | 1254 |
/// See \ref DfsVisitDefaultTraits for the documentation of |
| 1255 | 1255 |
/// a DFS visit traits class. |
| 1256 | 1256 |
#ifdef DOXYGEN |
| 1257 | 1257 |
template <typename _Digraph, typename _Visitor, typename _Traits> |
| 1258 | 1258 |
#else |
| 1259 | 1259 |
template <typename _Digraph = ListDigraph, |
| 1260 | 1260 |
typename _Visitor = DfsVisitor<_Digraph>, |
| 1261 |
typename _Traits = |
|
| 1261 |
typename _Traits = DfsVisitDefaultTraits<_Digraph> > |
|
| 1262 | 1262 |
#endif |
| 1263 | 1263 |
class DfsVisit {
|
| 1264 | 1264 |
public: |
| 1265 | 1265 |
|
| 1266 | 1266 |
///The traits class. |
| 1267 | 1267 |
typedef _Traits Traits; |
| 1268 | 1268 |
|
| 1269 | 1269 |
///The type of the digraph the algorithm runs on. |
| 1270 | 1270 |
typedef typename Traits::Digraph Digraph; |
| 1271 | 1271 |
|
| 1272 | 1272 |
///The visitor type used by the algorithm. |
| 1273 | 1273 |
typedef _Visitor Visitor; |
| 1274 | 1274 |
|
| 1275 | 1275 |
///The type of the map that indicates which nodes are reached. |
| 1276 | 1276 |
typedef typename Traits::ReachedMap ReachedMap; |
| 1277 | 1277 |
|
| 1278 | 1278 |
private: |
| 1279 | 1279 |
|
| 1280 | 1280 |
typedef typename Digraph::Node Node; |
| 1281 | 1281 |
typedef typename Digraph::NodeIt NodeIt; |
| 1282 | 1282 |
typedef typename Digraph::Arc Arc; |
| 1283 | 1283 |
typedef typename Digraph::OutArcIt OutArcIt; |
| 1284 | 1284 |
|
| 1285 | 1285 |
//Pointer to the underlying digraph. |
| 1286 | 1286 |
const Digraph *_digraph; |
| 1287 | 1287 |
//Pointer to the visitor object. |
| 1288 | 1288 |
Visitor *_visitor; |
| 1289 | 1289 |
//Pointer to the map of reached status of the nodes. |
| 1290 | 1290 |
ReachedMap *_reached; |
| 1291 | 1291 |
//Indicates if _reached is locally allocated (true) or not. |
| 1292 | 1292 |
bool local_reached; |
| 1293 | 1293 |
|
| 1294 | 1294 |
std::vector<typename Digraph::Arc> _stack; |
| 1295 | 1295 |
int _stack_head; |
| 1296 | 1296 |
|
| 1297 | 1297 |
//Creates the maps if necessary. |
| 1298 | 1298 |
void create_maps() {
|
| 1299 | 1299 |
if(!_reached) {
|
| 1300 | 1300 |
local_reached = true; |
| 1301 | 1301 |
_reached = Traits::createReachedMap(*_digraph); |
| 1302 | 1302 |
} |
| 1303 | 1303 |
} |
| 1304 | 1304 |
|
| 1305 | 1305 |
protected: |
| 1306 | 1306 |
|
| 1307 | 1307 |
DfsVisit() {}
|
| 1308 | 1308 |
|
| 1309 | 1309 |
public: |
| 1310 | 1310 |
|
| 1311 | 1311 |
typedef DfsVisit Create; |
| 1312 | 1312 |
|
| 1313 | 1313 |
/// \name Named template parameters |
| 1314 | 1314 |
|
| 1315 | 1315 |
///@{
|
| 1316 | 1316 |
template <class T> |
| 1317 | 1317 |
struct SetReachedMapTraits : public Traits {
|
| 1318 | 1318 |
typedef T ReachedMap; |
| 1319 | 1319 |
static ReachedMap *createReachedMap(const Digraph &digraph) {
|
| 1320 | 1320 |
LEMON_ASSERT(false, "ReachedMap is not initialized"); |
| 1321 | 1321 |
return 0; // ignore warnings |
| 1322 | 1322 |
} |
| 1323 | 1323 |
}; |
| 1324 | 1324 |
/// \brief \ref named-templ-param "Named parameter" for setting |
| 1325 | 1325 |
/// ReachedMap type. |
| 1326 | 1326 |
/// |
| 1327 | 1327 |
/// \ref named-templ-param "Named parameter" for setting ReachedMap type. |
| 1328 | 1328 |
template <class T> |
| 1329 | 1329 |
struct SetReachedMap : public DfsVisit< Digraph, Visitor, |
| 1330 | 1330 |
SetReachedMapTraits<T> > {
|
| 1331 | 1331 |
typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create; |
| 1332 | 1332 |
}; |
| 1333 | 1333 |
///@} |
| 1334 | 1334 |
|
| 1335 | 1335 |
public: |
| 1336 | 1336 |
|
| 1337 | 1337 |
/// \brief Constructor. |
| 1338 | 1338 |
/// |
| 1339 | 1339 |
/// Constructor. |
| 1340 | 1340 |
/// |
| 1341 | 1341 |
/// \param digraph The digraph the algorithm runs on. |
| 1342 | 1342 |
/// \param visitor The visitor object of the algorithm. |
| 1343 | 1343 |
DfsVisit(const Digraph& digraph, Visitor& visitor) |
| 1344 | 1344 |
: _digraph(&digraph), _visitor(&visitor), |
| 1345 | 1345 |
_reached(0), local_reached(false) {}
|
| 1346 | 1346 |
|
| 1347 | 1347 |
/// \brief Destructor. |
| 1348 | 1348 |
~DfsVisit() {
|
| 1349 | 1349 |
if(local_reached) delete _reached; |
| 1350 | 1350 |
} |
| 1351 | 1351 |
|
| 1352 | 1352 |
/// \brief Sets the map that indicates which nodes are reached. |
| 1353 | 1353 |
/// |
| 1354 | 1354 |
/// Sets the map that indicates which nodes are reached. |
| 1355 | 1355 |
/// If you don't use this function before calling \ref run(), |
| 1356 | 1356 |
/// it will allocate one. The destructor deallocates this |
| 1357 | 1357 |
/// automatically allocated map, of course. |
0 comments (0 inline)