206 : public MinCostArborescence<Graph, CostMap, |
253 : public MinCostArborescence<Graph, CostMap, |
207 DefArborescenceMapTraits<T> > { |
254 DefArborescenceMapTraits<T> > { |
208 typedef MinCostArborescence<Graph, CostMap, |
255 typedef MinCostArborescence<Graph, CostMap, |
209 DefArborescenceMapTraits<T> > Create; |
256 DefArborescenceMapTraits<T> > Create; |
210 }; |
257 }; |
|
258 |
|
259 template <class T> |
|
260 struct DefPredMapTraits : public Traits { |
|
261 typedef T PredMap; |
|
262 static PredMap *createPredMap(const Graph &) |
|
263 { |
|
264 throw UninitializedParameter(); |
|
265 } |
|
266 }; |
|
267 |
|
268 /// \brief \ref named-templ-param "Named parameter" for |
|
269 /// setting PredMap type |
|
270 /// |
|
271 /// \ref named-templ-param "Named parameter" for setting |
|
272 /// PredMap type |
|
273 template <class T> |
|
274 struct DefPredMap |
|
275 : public MinCostArborescence<Graph, CostMap, DefPredMapTraits<T> > { |
|
276 typedef MinCostArborescence<Graph, CostMap, DefPredMapTraits<T> > Create; |
|
277 }; |
211 |
278 |
212 /// @} |
279 /// @} |
213 |
280 |
214 /// \brief Constructor. |
281 /// \brief Constructor. |
215 /// |
282 /// |
216 /// \param _graph The graph the algorithm will run on. |
283 /// \param _graph The graph the algorithm will run on. |
217 /// \param _cost The cost map used by the algorithm. |
284 /// \param _cost The cost map used by the algorithm. |
218 MinCostArborescence(const Graph& _graph, const CostMap& _cost) |
285 MinCostArborescence(const Graph& _graph, const CostMap& _cost) |
219 : graph(&_graph), cost(&_cost), |
286 : graph(&_graph), cost(&_cost), _pred(0), local_pred(false), |
220 _arborescence_map(0), local_arborescence_map(false), |
287 _arborescence(0), local_arborescence(false), |
221 _level(0), _cost_edges(0) {} |
288 _edge_order(0), _node_order(0), _cost_edges(0), |
|
289 _heap_cross_ref(0), _heap(0) {} |
222 |
290 |
223 /// \brief Destructor. |
291 /// \brief Destructor. |
224 ~MinCostArborescence() { |
292 ~MinCostArborescence() { |
225 destroyStructures(); |
293 destroyStructures(); |
226 } |
294 } |
244 |
329 |
245 /// \brief Returns a reference to the arborescence map. |
330 /// \brief Returns a reference to the arborescence map. |
246 /// |
331 /// |
247 /// Returns a reference to the arborescence map. |
332 /// Returns a reference to the arborescence map. |
248 const ArborescenceMap& arborescenceMap() const { |
333 const ArborescenceMap& arborescenceMap() const { |
249 return *_arborescence_map; |
334 return *_arborescence; |
250 } |
335 } |
251 |
336 |
252 /// \brief Returns true if the edge is in the arborescence. |
337 /// \brief Returns true if the edge is in the arborescence. |
253 /// |
338 /// |
254 /// Returns true if the edge is in the arborescence. |
339 /// Returns true if the edge is in the arborescence. |
255 /// \param edge The edge of the graph. |
340 /// \param edge The edge of the graph. |
256 /// \pre \ref run() must be called before using this function. |
341 /// \pre \ref run() must be called before using this function. |
257 bool arborescenceEdge(Edge edge) const { |
342 bool arborescence(Edge edge) const { |
258 return (*_arborescence_map)[edge]; |
343 return (*_pred)[graph->target(edge)] == edge; |
|
344 } |
|
345 |
|
346 /// \brief Returns a reference to the pred map. |
|
347 /// |
|
348 /// Returns a reference to the pred map. |
|
349 const PredMap& predMap() const { |
|
350 return *_pred; |
|
351 } |
|
352 |
|
353 /// \brief Returns the predecessor edge of the given node. |
|
354 /// |
|
355 /// Returns the predecessor edge of the given node. |
|
356 bool pred(Node node) const { |
|
357 return (*_pred)[node]; |
259 } |
358 } |
260 |
359 |
261 /// \brief Returns the cost of the arborescence. |
360 /// \brief Returns the cost of the arborescence. |
262 /// |
361 /// |
263 /// Returns the cost of the arborescence. |
362 /// Returns the cost of the arborescence. |
264 Value arborescenceCost() const { |
363 Value arborescenceValue() const { |
265 Value sum = 0; |
364 Value sum = 0; |
266 for (EdgeIt it(*graph); it != INVALID; ++it) { |
365 for (EdgeIt it(*graph); it != INVALID; ++it) { |
267 if (arborescenceEdge(it)) { |
366 if (arborescence(it)) { |
268 sum += (*cost)[it]; |
367 sum += (*cost)[it]; |
269 } |
368 } |
270 } |
369 } |
271 return sum; |
370 return sum; |
272 } |
371 } |
|
372 |
|
373 /// \brief Indicates that a node is reachable from the sources. |
|
374 /// |
|
375 /// Indicates that a node is reachable from the sources. |
|
376 bool reached(Node node) const { |
|
377 return (*_node_order)[node] != -3; |
|
378 } |
|
379 |
|
380 /// \brief Indicates that a node is processed. |
|
381 /// |
|
382 /// Indicates that a node is processed. The arborescence path exists |
|
383 /// from the source to the given node. |
|
384 bool processed(Node node) const { |
|
385 return (*_node_order)[node] == -1; |
|
386 } |
|
387 |
|
388 /// \brief Returns the number of the dual variables in basis. |
|
389 /// |
|
390 /// Returns the number of the dual variables in basis. |
|
391 int dualSize() const { |
|
392 return _dual_variables.size(); |
|
393 } |
|
394 |
|
395 /// \brief Returns the value of the dual solution. |
|
396 /// |
|
397 /// Returns the value of the dual solution. It should be |
|
398 /// equal to the arborescence value. |
|
399 Value dualValue() const { |
|
400 Value sum = 0; |
|
401 for (int i = 0; i < (int)_dual_variables.size(); ++i) { |
|
402 sum += _dual_variables[i].value; |
|
403 } |
|
404 return sum; |
|
405 } |
|
406 |
|
407 /// \brief Returns the number of the nodes in the dual variable. |
|
408 /// |
|
409 /// Returns the number of the nodes in the dual variable. |
|
410 int dualSize(int k) const { |
|
411 return _dual_variables[k].end - _dual_variables[k].begin; |
|
412 } |
|
413 |
|
414 /// \brief Returns the value of the dual variable. |
|
415 /// |
|
416 /// Returns the the value of the dual variable. |
|
417 const Value& dualValue(int k) const { |
|
418 return _dual_variables[k].value; |
|
419 } |
|
420 |
|
421 /// \brief Lemon iterator for get a dual variable. |
|
422 /// |
|
423 /// Lemon iterator for get a dual variable. This class provides |
|
424 /// a common style lemon iterator which gives back a subset of |
|
425 /// the nodes. |
|
426 class DualIt { |
|
427 public: |
|
428 |
|
429 /// \brief Constructor. |
|
430 /// |
|
431 /// Constructor for get the nodeset of the variable. |
|
432 DualIt(const MinCostArborescence& algorithm, int variable) |
|
433 : _algorithm(&algorithm), _variable(variable) |
|
434 { |
|
435 _index = _algorithm->_dual_variables[_variable].begin; |
|
436 } |
|
437 |
|
438 /// \brief Invalid constructor. |
|
439 /// |
|
440 /// Invalid constructor. |
|
441 DualIt(Invalid) : _algorithm(0) {} |
|
442 |
|
443 /// \brief Conversion to node. |
|
444 /// |
|
445 /// Conversion to node. |
|
446 operator Node() const { |
|
447 return _algorithm ? _algorithm->_dual_node_list[_index] : INVALID; |
|
448 } |
|
449 |
|
450 /// \brief Increment operator. |
|
451 /// |
|
452 /// Increment operator. |
|
453 DualIt& operator++() { |
|
454 ++_index; |
|
455 if (_algorithm->_dual_variables[_variable].end == _index) { |
|
456 _algorithm = 0; |
|
457 } |
|
458 return *this; |
|
459 } |
|
460 |
|
461 bool operator==(const DualIt& it) const { |
|
462 return (Node)(*this) == (Node)it; |
|
463 } |
|
464 bool operator!=(const DualIt& it) const { |
|
465 return (Node)(*this) != (Node)it; |
|
466 } |
|
467 bool operator<(const DualIt& it) const { |
|
468 return (Node)(*this) < (Node)it; |
|
469 } |
|
470 |
|
471 private: |
|
472 const MinCostArborescence* _algorithm; |
|
473 int _variable; |
|
474 int _index; |
|
475 }; |
273 |
476 |
274 /// @} |
477 /// @} |
275 |
478 |
276 /// \name Execution control |
479 /// \name Execution control |
277 /// The simplest way to execute the algorithm is to use |
480 /// The simplest way to execute the algorithm is to use |
278 /// one of the member functions called \c run(...). \n |
481 /// one of the member functions called \c run(...). \n |
279 /// If you need more control on the execution, |
482 /// If you need more control on the execution, |
280 /// first you must call \ref init(), then you can add several |
483 /// first you must call \ref init(), then you can add several |
281 /// source nodes with \ref addSource(). |
484 /// source nodes with \ref addSource(). |
282 /// Finally \ref start() will perform the actual path |
485 /// Finally \ref start() will perform the arborescence |
283 /// computation. |
486 /// computation. |
284 |
487 |
285 ///@{ |
488 ///@{ |
286 |
489 |
287 /// \brief Initializes the internal data structures. |
490 /// \brief Initializes the internal data structures. |
288 /// |
491 /// |
289 /// Initializes the internal data structures. |
492 /// Initializes the internal data structures. |
290 /// |
493 /// |
291 void init() { |
494 void init() { |
292 initStructures(); |
495 initStructures(); |
|
496 _heap->clear(); |
293 for (NodeIt it(*graph); it != INVALID; ++it) { |
497 for (NodeIt it(*graph); it != INVALID; ++it) { |
294 (*_cost_edges)[it].edge = INVALID; |
498 (*_cost_edges)[it].edge = INVALID; |
295 (*_level)[it] = -3; |
499 _node_order->set(it, -3); |
|
500 _heap_cross_ref->set(it, Heap::PRE_HEAP); |
296 } |
501 } |
297 for (EdgeIt it(*graph); it != INVALID; ++it) { |
502 for (EdgeIt it(*graph); it != INVALID; ++it) { |
298 _arborescence_map->set(it, false); |
503 _arborescence->set(it, false); |
299 } |
504 _edge_order->set(it, -1); |
|
505 } |
|
506 _dual_node_list.clear(); |
|
507 _dual_variables.clear(); |
300 } |
508 } |
301 |
509 |
302 /// \brief Adds a new source node. |
510 /// \brief Adds a new source node. |
303 /// |
511 /// |
304 /// Adds a new source node to the algorithm. |
512 /// Adds a new source node to the algorithm. |
307 nodes.push_back(source); |
515 nodes.push_back(source); |
308 while (!nodes.empty()) { |
516 while (!nodes.empty()) { |
309 Node node = nodes.back(); |
517 Node node = nodes.back(); |
310 nodes.pop_back(); |
518 nodes.pop_back(); |
311 for (OutEdgeIt it(*graph, node); it != INVALID; ++it) { |
519 for (OutEdgeIt it(*graph, node); it != INVALID; ++it) { |
312 if ((*_level)[graph->target(it)] == -3) { |
520 Node target = graph->target(it); |
313 (*_level)[graph->target(it)] = -2; |
521 if ((*_node_order)[target] == -3) { |
314 nodes.push_back(graph->target(it)); |
522 (*_node_order)[target] = -2; |
315 queue.push_back(graph->target(it)); |
523 nodes.push_back(target); |
|
524 queue.push_back(target); |
316 } |
525 } |
317 } |
526 } |
318 } |
527 } |
319 (*_level)[source] = -1; |
528 (*_node_order)[source] = -1; |
320 } |
529 } |
321 |
530 |
322 /// \brief Processes the next node in the priority queue. |
531 /// \brief Processes the next node in the priority queue. |
323 /// |
532 /// |
324 /// Processes the next node in the priority queue. |
533 /// Processes the next node in the priority queue. |
325 /// |
534 /// |
326 /// \return The processed node. |
535 /// \return The processed node. |
327 /// |
536 /// |
328 /// \warning The queue must not be empty! |
537 /// \warning The queue must not be empty! |
329 Node processNextNode() { |
538 Node processNextNode() { |
330 node_counter = 0; |
|
331 Node node = queue.back(); |
539 Node node = queue.back(); |
332 queue.pop_back(); |
540 queue.pop_back(); |
333 if ((*_level)[node] == -2) { |
541 if ((*_node_order)[node] == -2) { |
334 Edge edge = prepare(node); |
542 Edge edge = prepare(node); |
335 while ((*_level)[graph->source(edge)] != -1) { |
543 Node source = graph->source(edge); |
336 if ((*_level)[graph->source(edge)] >= 0) { |
544 while ((*_node_order)[source] != -1) { |
337 edge = contract(bottom((*_level)[graph->source(edge)])); |
545 if ((*_node_order)[source] >= 0) { |
|
546 edge = contract(source); |
338 } else { |
547 } else { |
339 edge = prepare(graph->source(edge)); |
548 edge = prepare(source); |
340 } |
549 } |
|
550 source = graph->source(edge); |
341 } |
551 } |
342 finalize(graph->target(edge)); |
552 finalize(edge); |
343 level_stack.clear(); |
553 level_stack.clear(); |
344 } |
554 } |
345 return node; |
555 return node; |
346 } |
556 } |
347 |
557 |
398 ///@} |
608 ///@} |
399 |
609 |
400 protected: |
610 protected: |
401 |
611 |
402 void initStructures() { |
612 void initStructures() { |
403 if (!_arborescence_map) { |
613 if (!_pred) { |
404 local_arborescence_map = true; |
614 local_pred = true; |
405 _arborescence_map = Traits::createArborescenceMap(*graph); |
615 _pred = Traits::createPredMap(*graph); |
406 } |
616 } |
407 if (!_level) { |
617 if (!_arborescence) { |
408 _level = new LevelMap(*graph); |
618 local_arborescence = true; |
|
619 _arborescence = Traits::createArborescenceMap(*graph); |
|
620 } |
|
621 if (!_edge_order) { |
|
622 _edge_order = new EdgeOrder(*graph); |
|
623 } |
|
624 if (!_node_order) { |
|
625 _node_order = new NodeOrder(*graph); |
409 } |
626 } |
410 if (!_cost_edges) { |
627 if (!_cost_edges) { |
411 _cost_edges = new CostEdgeMap(*graph); |
628 _cost_edges = new CostEdgeMap(*graph); |
412 } |
629 } |
|
630 if (!_heap_cross_ref) { |
|
631 _heap_cross_ref = new HeapCrossRef(*graph, -1); |
|
632 } |
|
633 if (!_heap) { |
|
634 _heap = new Heap(*_heap_cross_ref); |
|
635 } |
413 } |
636 } |
414 |
637 |
415 void destroyStructures() { |
638 void destroyStructures() { |
416 if (_level) { |
639 if (local_arborescence) { |
417 delete _level; |
640 delete _arborescence; |
|
641 } |
|
642 if (local_pred) { |
|
643 delete _pred; |
|
644 } |
|
645 if (!_edge_order) { |
|
646 delete _edge_order; |
|
647 } |
|
648 if (_node_order) { |
|
649 delete _node_order; |
418 } |
650 } |
419 if (!_cost_edges) { |
651 if (!_cost_edges) { |
420 delete _cost_edges; |
652 delete _cost_edges; |
421 } |
653 } |
422 if (local_arborescence_map) { |
654 if (!_heap) { |
423 delete _arborescence_map; |
655 delete _heap; |
|
656 } |
|
657 if (!_heap_cross_ref) { |
|
658 delete _heap_cross_ref; |
424 } |
659 } |
425 } |
660 } |
426 |
661 |
427 Edge prepare(Node node) { |
662 Edge prepare(Node node) { |
428 std::vector<Node> nodes; |
663 std::vector<Node> nodes; |
429 (*_level)[node] = node_counter; |
664 (*_node_order)[node] = _dual_node_list.size(); |
|
665 StackLevel level; |
|
666 level.node_level = _dual_node_list.size(); |
|
667 _dual_node_list.push_back(node); |
430 for (InEdgeIt it(*graph, node); it != INVALID; ++it) { |
668 for (InEdgeIt it(*graph, node); it != INVALID; ++it) { |
431 Edge edge = it; |
669 Edge edge = it; |
|
670 Node source = graph->source(edge); |
432 Value value = (*cost)[it]; |
671 Value value = (*cost)[it]; |
433 if (graph->source(edge) == node || |
672 if (source == node || (*_node_order)[source] == -3) continue; |
434 (*_level)[graph->source(edge)] == -3) continue; |
673 if ((*_cost_edges)[source].edge == INVALID) { |
435 if ((*_cost_edges)[graph->source(edge)].edge == INVALID) { |
674 (*_cost_edges)[source].edge = edge; |
436 (*_cost_edges)[graph->source(edge)].edge = edge; |
675 (*_cost_edges)[source].value = value; |
437 (*_cost_edges)[graph->source(edge)].value = value; |
676 nodes.push_back(source); |
438 nodes.push_back(graph->source(edge)); |
|
439 } else { |
677 } else { |
440 if ((*_cost_edges)[graph->source(edge)].value > value) { |
678 if ((*_cost_edges)[source].value > value) { |
441 (*_cost_edges)[graph->source(edge)].edge = edge; |
679 (*_cost_edges)[source].edge = edge; |
442 (*_cost_edges)[graph->source(edge)].value = value; |
680 (*_cost_edges)[source].value = value; |
443 } |
681 } |
444 } |
682 } |
445 } |
683 } |
446 CostEdge minimum = (*_cost_edges)[nodes[0]]; |
684 CostEdge minimum = (*_cost_edges)[nodes[0]]; |
447 for (int i = 1; i < (int)nodes.size(); ++i) { |
685 for (int i = 1; i < (int)nodes.size(); ++i) { |
448 if ((*_cost_edges)[nodes[i]].value < minimum.value) { |
686 if ((*_cost_edges)[nodes[i]].value < minimum.value) { |
449 minimum = (*_cost_edges)[nodes[i]]; |
687 minimum = (*_cost_edges)[nodes[i]]; |
450 } |
688 } |
451 } |
689 } |
452 StackLevel level; |
690 _edge_order->set(minimum.edge, _dual_variables.size()); |
453 level.node_level = node_counter; |
691 DualVariable var(_dual_node_list.size() - 1, |
|
692 _dual_node_list.size(), minimum.value); |
|
693 _dual_variables.push_back(var); |
454 for (int i = 0; i < (int)nodes.size(); ++i) { |
694 for (int i = 0; i < (int)nodes.size(); ++i) { |
455 (*_cost_edges)[nodes[i]].value -= minimum.value; |
695 (*_cost_edges)[nodes[i]].value -= minimum.value; |
456 level.edges.push_back((*_cost_edges)[nodes[i]]); |
696 level.edges.push_back((*_cost_edges)[nodes[i]]); |
457 (*_cost_edges)[nodes[i]].edge = INVALID; |
697 (*_cost_edges)[nodes[i]].edge = INVALID; |
458 } |
698 } |
459 level_stack.push_back(level); |
699 level_stack.push_back(level); |
460 ++node_counter; |
|
461 _arborescence_map->set(minimum.edge, true); |
|
462 return minimum.edge; |
700 return minimum.edge; |
463 } |
701 } |
464 |
702 |
465 Edge contract(int node_bottom) { |
703 Edge contract(Node node) { |
|
704 int node_bottom = bottom(node); |
466 std::vector<Node> nodes; |
705 std::vector<Node> nodes; |
467 while (!level_stack.empty() && |
706 while (!level_stack.empty() && |
468 level_stack.back().node_level >= node_bottom) { |
707 level_stack.back().node_level >= node_bottom) { |
469 for (int i = 0; i < (int)level_stack.back().edges.size(); ++i) { |
708 for (int i = 0; i < (int)level_stack.back().edges.size(); ++i) { |
470 Edge edge = level_stack.back().edges[i].edge; |
709 Edge edge = level_stack.back().edges[i].edge; |
|
710 Node source = graph->source(edge); |
471 Value value = level_stack.back().edges[i].value; |
711 Value value = level_stack.back().edges[i].value; |
472 if ((*_level)[graph->source(edge)] >= node_bottom) continue; |
712 if ((*_node_order)[source] >= node_bottom) continue; |
473 if ((*_cost_edges)[graph->source(edge)].edge == INVALID) { |
713 if ((*_cost_edges)[source].edge == INVALID) { |
474 (*_cost_edges)[graph->source(edge)].edge = edge; |
714 (*_cost_edges)[source].edge = edge; |
475 (*_cost_edges)[graph->source(edge)].value = value; |
715 (*_cost_edges)[source].value = value; |
476 nodes.push_back(graph->source(edge)); |
716 nodes.push_back(source); |
477 } else { |
717 } else { |
478 if ((*_cost_edges)[graph->source(edge)].value > value) { |
718 if ((*_cost_edges)[source].value > value) { |
479 (*_cost_edges)[graph->source(edge)].edge = edge; |
719 (*_cost_edges)[source].edge = edge; |
480 (*_cost_edges)[graph->source(edge)].value = value; |
720 (*_cost_edges)[source].value = value; |
481 } |
721 } |
482 } |
722 } |
483 } |
723 } |
484 level_stack.pop_back(); |
724 level_stack.pop_back(); |
485 } |
725 } |
487 for (int i = 1; i < (int)nodes.size(); ++i) { |
727 for (int i = 1; i < (int)nodes.size(); ++i) { |
488 if ((*_cost_edges)[nodes[i]].value < minimum.value) { |
728 if ((*_cost_edges)[nodes[i]].value < minimum.value) { |
489 minimum = (*_cost_edges)[nodes[i]]; |
729 minimum = (*_cost_edges)[nodes[i]]; |
490 } |
730 } |
491 } |
731 } |
|
732 _edge_order->set(minimum.edge, _dual_variables.size()); |
|
733 DualVariable var(node_bottom, _dual_node_list.size(), minimum.value); |
|
734 _dual_variables.push_back(var); |
492 StackLevel level; |
735 StackLevel level; |
493 level.node_level = node_bottom; |
736 level.node_level = node_bottom; |
494 for (int i = 0; i < (int)nodes.size(); ++i) { |
737 for (int i = 0; i < (int)nodes.size(); ++i) { |
495 (*_cost_edges)[nodes[i]].value -= minimum.value; |
738 (*_cost_edges)[nodes[i]].value -= minimum.value; |
496 level.edges.push_back((*_cost_edges)[nodes[i]]); |
739 level.edges.push_back((*_cost_edges)[nodes[i]]); |
497 (*_cost_edges)[nodes[i]].edge = INVALID; |
740 (*_cost_edges)[nodes[i]].edge = INVALID; |
498 } |
741 } |
499 level_stack.push_back(level); |
742 level_stack.push_back(level); |
500 _arborescence_map->set(minimum.edge, true); |
|
501 return minimum.edge; |
743 return minimum.edge; |
502 } |
744 } |
503 |
745 |
504 int bottom(int level) { |
746 int bottom(Node node) { |
505 int k = level_stack.size() - 1; |
747 int k = level_stack.size() - 1; |
506 while (level_stack[k].node_level > level) { |
748 while (level_stack[k].node_level > (*_node_order)[node]) { |
507 --k; |
749 --k; |
508 } |
750 } |
509 return level_stack[k].node_level; |
751 return level_stack[k].node_level; |
510 } |
752 } |
511 |
753 |
512 void finalize(Node source) { |
754 void finalize(Edge edge) { |
513 std::vector<Node> nodes; |
755 Node node = graph->target(edge); |
514 nodes.push_back(source); |
756 _heap->push(node, (*_edge_order)[edge]); |
515 while (!nodes.empty()) { |
757 _pred->set(node, edge); |
516 Node node = nodes.back(); |
758 while (!_heap->empty()) { |
517 nodes.pop_back(); |
759 Node source = _heap->top(); |
518 for (OutEdgeIt it(*graph, node); it != INVALID; ++it) { |
760 _heap->pop(); |
519 if ((*_level)[graph->target(it)] >= 0 && (*_arborescence_map)[it]) { |
761 _node_order->set(source, -1); |
520 (*_level)[graph->target(it)] = -1; |
762 for (OutEdgeIt it(*graph, source); it != INVALID; ++it) { |
521 nodes.push_back(graph->target(it)); |
763 if ((*_edge_order)[it] < 0) continue; |
522 } else { |
764 Node target = graph->target(it); |
523 _arborescence_map->set(it, false); |
765 switch(_heap->state(target)) { |
|
766 case Heap::PRE_HEAP: |
|
767 _heap->push(target, (*_edge_order)[it]); |
|
768 _pred->set(target, it); |
|
769 break; |
|
770 case Heap::IN_HEAP: |
|
771 if ((*_edge_order)[it] < (*_heap)[target]) { |
|
772 _heap->decrease(target, (*_edge_order)[it]); |
|
773 _pred->set(target, it); |
|
774 } |
|
775 break; |
|
776 case Heap::POST_HEAP: |
|
777 break; |
524 } |
778 } |
525 } |
779 } |
526 } |
780 _arborescence->set((*_pred)[source], true); |
527 (*_level)[source] = -1; |
781 } |
528 } |
782 } |
529 |
783 |
530 }; |
784 }; |
531 |
785 |
532 /// \ingroup spantree |
786 /// \ingroup spantree |