201 typedef typename _Traits::Graph Graph; |
201 typedef typename _Traits::Graph Graph; |
202 |
202 |
203 typedef typename Graph::Node Node; |
203 typedef typename Graph::Node Node; |
204 typedef typename Graph::NodeIt NodeIt; |
204 typedef typename Graph::NodeIt NodeIt; |
205 typedef typename Graph::Edge Edge; |
205 typedef typename Graph::Edge Edge; |
206 typedef typename Graph::EdgeIt EdgeIt; |
206 typedef typename Graph::OutEdgeIt OutEdgeIt; |
207 |
207 |
208 /// \brief The type of the length of the edges. |
208 /// \brief The type of the length of the edges. |
209 typedef typename _Traits::LengthMap::Value Value; |
209 typedef typename _Traits::LengthMap::Value Value; |
210 /// \brief The type of the map that stores the edge lengths. |
210 /// \brief The type of the map that stores the edge lengths. |
211 typedef typename _Traits::LengthMap LengthMap; |
211 typedef typename _Traits::LengthMap LengthMap; |
386 create_maps(); |
393 create_maps(); |
387 for (NodeIt it(*graph); it != INVALID; ++it) { |
394 for (NodeIt it(*graph); it != INVALID; ++it) { |
388 _pred->set(it, INVALID); |
395 _pred->set(it, INVALID); |
389 _dist->set(it, value); |
396 _dist->set(it, value); |
390 } |
397 } |
|
398 _process.clear(); |
|
399 if (OperationTraits::less(value, OperationTraits::infinity())) { |
|
400 for (NodeIt it(*graph); it != INVALID; ++it) { |
|
401 _process.push_back(it); |
|
402 } |
|
403 } |
391 } |
404 } |
392 |
405 |
393 /// \brief Adds a new source node. |
406 /// \brief Adds a new source node. |
394 /// |
407 /// |
395 /// The optional second parameter is the initial distance of the node. |
408 /// The optional second parameter is the initial distance of the node. |
396 /// It just sets the distance of the node to the given value. |
409 /// It just sets the distance of the node to the given value. |
397 void addSource(Node source, Value dst = OperationTraits::zero()) { |
410 void addSource(Node source, Value dst = OperationTraits::zero()) { |
398 _dist->set(source, dst); |
411 _dist->set(source, dst); |
|
412 if (!(*_mask)[source]) { |
|
413 _process.push_back(source); |
|
414 _mask->set(source, true); |
|
415 } |
|
416 } |
|
417 |
|
418 /// \brief Executes one round from the belmann ford algorithm. |
|
419 /// |
|
420 /// If the algoritm calculated the distances in the previous round |
|
421 /// strictly for all at most k length pathes then it will calculate the |
|
422 /// distances strictly for all at most k + 1 length pathes. With k |
|
423 /// iteration this function calculates the at most k length pathes. |
|
424 bool processNextRound() { |
|
425 for (int i = 0; i < (int)_process.size(); ++i) { |
|
426 _mask->set(_process[i], false); |
|
427 } |
|
428 std::vector<Node> nextProcess; |
|
429 std::vector<Value> values(_process.size()); |
|
430 for (int i = 0; i < (int)_process.size(); ++i) { |
|
431 values[i] = _dist[_process[i]]; |
|
432 } |
|
433 for (int i = 0; i < (int)_process.size(); ++i) { |
|
434 for (OutEdgeIt it(*graph, _process[i]); it != INVALID; ++it) { |
|
435 Node target = graph->target(it); |
|
436 Value relaxed = OperationTraits::plus(values[i], (*length)[it]); |
|
437 if (OperationTraits::less(relaxed, (*_dist)[target])) { |
|
438 _pred->set(target, it); |
|
439 _dist->set(target, relaxed); |
|
440 if (!(*_mask)[target]) { |
|
441 _mask->set(target, true); |
|
442 nextProcess.push_back(target); |
|
443 } |
|
444 } |
|
445 } |
|
446 } |
|
447 _process.swap(nextProcess); |
|
448 return _process.empty(); |
|
449 } |
|
450 |
|
451 /// \brief Executes one weak round from the belmann ford algorithm. |
|
452 /// |
|
453 /// If the algorithm calculated the distances in the |
|
454 /// previous round at least for all at most k length pathes then it will |
|
455 /// calculate the distances at least for all at most k + 1 length pathes. |
|
456 /// This function does not make possible to calculate strictly the |
|
457 /// at most k length minimal pathes, this way it called just weak round. |
|
458 bool processNextWeakRound() { |
|
459 for (int i = 0; i < (int)_process.size(); ++i) { |
|
460 _mask->set(_process[i], false); |
|
461 } |
|
462 std::vector<Node> nextProcess; |
|
463 for (int i = 0; i < (int)_process.size(); ++i) { |
|
464 for (OutEdgeIt it(*graph, _process[i]); it != INVALID; ++it) { |
|
465 Node target = graph->target(it); |
|
466 Value relaxed = |
|
467 OperationTraits::plus((*_dist)[_process[i]], (*length)[it]); |
|
468 if (OperationTraits::less(relaxed, (*_dist)[target])) { |
|
469 _pred->set(target, it); |
|
470 _dist->set(target, relaxed); |
|
471 if (!(*_mask)[target]) { |
|
472 _mask->set(target, true); |
|
473 nextProcess.push_back(target); |
|
474 } |
|
475 } |
|
476 } |
|
477 } |
|
478 for (int i = 0; i < (int)nextProcess.size(); ++i) { |
|
479 _mask->set(nextProcess[i], false); |
|
480 } |
|
481 _process.swap(nextProcess); |
|
482 return _process.empty(); |
399 } |
483 } |
400 |
484 |
401 /// \brief Executes the algorithm. |
485 /// \brief Executes the algorithm. |
402 /// |
486 /// |
403 /// \pre init() must be called and at least one node should be added |
487 /// \pre init() must be called and at least one node should be added |
409 /// - The shortest path tree. |
493 /// - The shortest path tree. |
410 /// - The distance of each node from the root(s). |
494 /// - The distance of each node from the root(s). |
411 void start() { |
495 void start() { |
412 int num = countNodes(*graph) - 1; |
496 int num = countNodes(*graph) - 1; |
413 for (int i = 0; i < num; ++i) { |
497 for (int i = 0; i < num; ++i) { |
414 bool done = true; |
498 if (processNextWeakRound()) break; |
415 for (EdgeIt it(*graph); it != INVALID; ++it) { |
|
416 Node source = graph->source(it); |
|
417 Node target = graph->target(it); |
|
418 Value relaxed = |
|
419 OperationTraits::plus((*_dist)[source], (*length)[it]); |
|
420 if (OperationTraits::less(relaxed, (*_dist)[target])) { |
|
421 _pred->set(target, it); |
|
422 _dist->set(target, relaxed); |
|
423 done = false; |
|
424 } |
|
425 } |
|
426 if (done) return; |
|
427 } |
499 } |
428 } |
500 } |
429 |
501 |
430 /// \brief Executes the algorithm and checks the negative cycles. |
502 /// \brief Executes the algorithm and checks the negative cycles. |
431 /// |
503 /// |
439 /// - The shortest path tree. |
511 /// - The shortest path tree. |
440 /// - The distance of each node from the root(s). |
512 /// - The distance of each node from the root(s). |
441 bool checkedStart() { |
513 bool checkedStart() { |
442 int num = countNodes(*graph); |
514 int num = countNodes(*graph); |
443 for (int i = 0; i < num; ++i) { |
515 for (int i = 0; i < num; ++i) { |
444 bool done = true; |
516 if (processNextWeakRound()) return true; |
445 for (EdgeIt it(*graph); it != INVALID; ++it) { |
|
446 Node source = graph->source(it); |
|
447 Node target = graph->target(it); |
|
448 Value relaxed = |
|
449 OperationTraits::plus((*_dist)[source], (*length)[it]); |
|
450 if (OperationTraits::less(relaxed, (*_dist)[target])) { |
|
451 _pred->set(target, it); |
|
452 _dist->set(target, relaxed); |
|
453 done = false; |
|
454 } |
|
455 } |
|
456 if (done) return true; |
|
457 } |
517 } |
458 return false; |
518 return false; |
|
519 } |
|
520 |
|
521 /// \brief Executes the algorithm with path length limit. |
|
522 /// |
|
523 /// \pre init() must be called and at least one node should be added |
|
524 /// with addSource() before using this function. |
|
525 /// |
|
526 /// This method runs the %BelmannFord algorithm from the root node(s) |
|
527 /// in order to compute the shortest path with at most \c length edge |
|
528 /// long pathes to each node. The algorithm computes |
|
529 /// - The shortest path tree. |
|
530 /// - The limited distance of each node from the root(s). |
|
531 void limitedStart(int length) { |
|
532 for (int i = 0; i < length; ++i) { |
|
533 if (processNextRound()) break; |
|
534 } |
459 } |
535 } |
460 |
536 |
461 /// \brief Runs %BelmannFord algorithm from node \c s. |
537 /// \brief Runs %BelmannFord algorithm from node \c s. |
462 /// |
538 /// |
463 /// This method runs the %BelmannFord algorithm from a root node \c s |
539 /// This method runs the %BelmannFord algorithm from a root node \c s |