gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Modify the interface of MinCostArborescence + improvements (#267) - Rename arborescenceValue() to arborescenceCost(). - Rename DefXyz template named paramaters to SetXyz. - Rearrange public functions (for better doc). - Doc improvements. - Extend the test file with interface checking.
0 2 0
default
2 files changed with 279 insertions and 206 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -27,116 +27,117 @@
27 27

	
28 28
#include <lemon/list_graph.h>
29 29
#include <lemon/bin_heap.h>
30 30
#include <lemon/assert.h>
31 31

	
32 32
namespace lemon {
33 33

	
34 34

	
35 35
  /// \brief Default traits class for MinCostArborescence class.
36 36
  ///
37 37
  /// Default traits class for MinCostArborescence class.
38 38
  /// \param GR Digraph type.
39
  /// \param CM Type of cost map.
39
  /// \param CM Type of the cost map.
40 40
  template <class GR, class CM>
41 41
  struct MinCostArborescenceDefaultTraits{
42 42

	
43 43
    /// \brief The digraph type the algorithm runs on.
44 44
    typedef GR Digraph;
45 45

	
46 46
    /// \brief The type of the map that stores the arc costs.
47 47
    ///
48 48
    /// The type of the map that stores the arc costs.
49
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
49
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
50 50
    typedef CM CostMap;
51 51

	
52 52
    /// \brief The value type of the costs.
53 53
    ///
54 54
    /// The value type of the costs.
55 55
    typedef typename CostMap::Value Value;
56 56

	
57 57
    /// \brief The type of the map that stores which arcs are in the
58 58
    /// arborescence.
59 59
    ///
60 60
    /// The type of the map that stores which arcs are in the
61
    /// arborescence.  It must meet the \ref concepts::WriteMap
62
    /// "WriteMap" concept.  Initially it will be set to false on each
63
    /// arc. After it will set all arborescence arcs once.
61
    /// arborescence.  It must conform to the \ref concepts::WriteMap
62
    /// "WriteMap" concept, and its value type must be \c bool
63
    /// (or convertible). Initially it will be set to \c false on each
64
    /// arc, then it will be set on each arborescence arc once.
64 65
    typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
65 66

	
66 67
    /// \brief Instantiates a \c ArborescenceMap.
67 68
    ///
68 69
    /// This function instantiates a \c ArborescenceMap.
69
    /// \param digraph is the graph, to which we would like to
70
    /// calculate the \c ArborescenceMap.
70
    /// \param digraph The digraph to which we would like to calculate
71
    /// the \c ArborescenceMap.
71 72
    static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
72 73
      return new ArborescenceMap(digraph);
73 74
    }
74 75

	
75 76
    /// \brief The type of the \c PredMap
76 77
    ///
77
    /// The type of the \c PredMap. It is a node map with an arc value type.
78
    /// The type of the \c PredMap. It must confrom to the
79
    /// \ref concepts::WriteMap "WriteMap" concept, and its value type
80
    /// must be the \c Arc type of the digraph.
78 81
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
79 82

	
80 83
    /// \brief Instantiates a \c PredMap.
81 84
    ///
82 85
    /// This function instantiates a \c PredMap.
83 86
    /// \param digraph The digraph to which we would like to define the
84 87
    /// \c PredMap.
85 88
    static PredMap *createPredMap(const Digraph &digraph){
86 89
      return new PredMap(digraph);
87 90
    }
88 91

	
89 92
  };
90 93

	
91 94
  /// \ingroup spantree
92 95
  ///
93 96
  /// \brief Minimum Cost Arborescence algorithm class.
94 97
  ///
95
  /// This class provides an efficient implementation of
98
  /// This class provides an efficient implementation of the
96 99
  /// Minimum Cost Arborescence algorithm. The arborescence is a tree
97 100
  /// which is directed from a given source node of the digraph. One or
98
  /// more sources should be given for the algorithm and it will calculate
99
  /// the minimum cost subgraph which are union of arborescences with the
101
  /// more sources should be given to the algorithm and it will calculate
102
  /// the minimum cost subgraph that is the union of arborescences with the
100 103
  /// given sources and spans all the nodes which are reachable from the
101 104
  /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
102 105
  ///
103
  /// The algorithm provides also an optimal dual solution, therefore
106
  /// The algorithm also provides an optimal dual solution, therefore
104 107
  /// the optimality of the solution can be checked.
105 108
  ///
106
  /// \param GR The digraph type the algorithm runs on. The default value
107
  /// is \ref ListDigraph.
108
  /// \param CM This read-only ArcMap determines the costs of the
109
  /// \param GR The digraph type the algorithm runs on.
110
  /// \param CM A read-only arc map storing the costs of the
109 111
  /// arcs. It is read once for each arc, so the map may involve in
110
  /// relatively time consuming process to compute the arc cost if
112
  /// relatively time consuming process to compute the arc costs if
111 113
  /// it is necessary. The default map type is \ref
112 114
  /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
113 115
  /// \param TR Traits class to set various data types used
114 116
  /// by the algorithm. The default traits class is
115 117
  /// \ref MinCostArborescenceDefaultTraits
116
  /// "MinCostArborescenceDefaultTraits<GR, CM>".  See \ref
117
  /// MinCostArborescenceDefaultTraits for the documentation of a
118
  /// MinCostArborescence traits class.
118
  /// "MinCostArborescenceDefaultTraits<GR, CM>".
119 119
#ifndef DOXYGEN
120
  template <typename GR = ListDigraph,
120
  template <typename GR,
121 121
            typename CM = typename GR::template ArcMap<int>,
122 122
            typename TR =
123 123
              MinCostArborescenceDefaultTraits<GR, CM> >
124 124
#else
125 125
  template <typename GR, typename CM, typedef TR>
126 126
#endif
127 127
  class MinCostArborescence {
128 128
  public:
129 129

	
130
    /// The traits.
130
    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class" 
131
    /// of the algorithm. 
131 132
    typedef TR Traits;
132 133
    /// The type of the underlying digraph.
133 134
    typedef typename Traits::Digraph Digraph;
134 135
    /// The type of the map that stores the arc costs.
135 136
    typedef typename Traits::CostMap CostMap;
136 137
    ///The type of the costs of the arcs.
137 138
    typedef typename Traits::Value Value;
138 139
    ///The type of the predecessor map.
139 140
    typedef typename Traits::PredMap PredMap;
140 141
    ///The type of the map that stores which arcs are in the arborescence.
141 142
    typedef typename Traits::ArborescenceMap ArborescenceMap;
142 143

	
... ...
@@ -386,61 +387,68 @@
386 387
        _arborescence->set((*_pred)[source], true);
387 388
      }
388 389
    }
389 390

	
390 391

	
391 392
  public:
392 393

	
393 394
    /// \name Named Template Parameters
394 395

	
395 396
    /// @{
396 397

	
397 398
    template <class T>
398
    struct DefArborescenceMapTraits : public Traits {
399
    struct SetArborescenceMapTraits : public Traits {
399 400
      typedef T ArborescenceMap;
400 401
      static ArborescenceMap *createArborescenceMap(const Digraph &)
401 402
      {
402 403
        LEMON_ASSERT(false, "ArborescenceMap is not initialized");
403 404
        return 0; // ignore warnings
404 405
      }
405 406
    };
406 407

	
407 408
    /// \brief \ref named-templ-param "Named parameter" for
408
    /// setting ArborescenceMap type
409
    /// setting \c ArborescenceMap type
409 410
    ///
410 411
    /// \ref named-templ-param "Named parameter" for setting
411
    /// ArborescenceMap type
412
    /// \c ArborescenceMap type.
413
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept,
414
    /// and its value type must be \c bool (or convertible).
415
    /// Initially it will be set to \c false on each arc,
416
    /// then it will be set on each arborescence arc once.
412 417
    template <class T>
413
    struct DefArborescenceMap
418
    struct SetArborescenceMap
414 419
      : public MinCostArborescence<Digraph, CostMap,
415
                                   DefArborescenceMapTraits<T> > {
420
                                   SetArborescenceMapTraits<T> > {
416 421
    };
417 422

	
418 423
    template <class T>
419
    struct DefPredMapTraits : public Traits {
424
    struct SetPredMapTraits : public Traits {
420 425
      typedef T PredMap;
421 426
      static PredMap *createPredMap(const Digraph &)
422 427
      {
423 428
        LEMON_ASSERT(false, "PredMap is not initialized");
429
        return 0; // ignore warnings
424 430
      }
425 431
    };
426 432

	
427 433
    /// \brief \ref named-templ-param "Named parameter" for
428
    /// setting PredMap type
434
    /// setting \c PredMap type
429 435
    ///
430 436
    /// \ref named-templ-param "Named parameter" for setting
431
    /// PredMap type
437
    /// \c PredMap type.
438
    /// It must meet the \ref concepts::WriteMap "WriteMap" concept, 
439
    /// and its value type must be the \c Arc type of the digraph.
432 440
    template <class T>
433
    struct DefPredMap
434
      : public MinCostArborescence<Digraph, CostMap, DefPredMapTraits<T> > {
441
    struct SetPredMap
442
      : public MinCostArborescence<Digraph, CostMap, SetPredMapTraits<T> > {
435 443
    };
436 444

	
437 445
    /// @}
438 446

	
439 447
    /// \brief Constructor.
440 448
    ///
441 449
    /// \param digraph The digraph the algorithm will run on.
442 450
    /// \param cost The cost map used by the algorithm.
443 451
    MinCostArborescence(const Digraph& digraph, const CostMap& cost)
444 452
      : _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false),
445 453
        _arborescence(0), local_arborescence(false),
446 454
        _arc_order(0), _node_order(0), _cost_arcs(0),
... ...
@@ -455,190 +463,37 @@
455 463
    ///
456 464
    /// Sets the arborescence map.
457 465
    /// \return <tt>(*this)</tt>
458 466
    MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
459 467
      if (local_arborescence) {
460 468
        delete _arborescence;
461 469
      }
462 470
      local_arborescence = false;
463 471
      _arborescence = &m;
464 472
      return *this;
465 473
    }
466 474

	
467
    /// \brief Sets the arborescence map.
475
    /// \brief Sets the predecessor map.
468 476
    ///
469
    /// Sets the arborescence map.
477
    /// Sets the predecessor map.
470 478
    /// \return <tt>(*this)</tt>
471 479
    MinCostArborescence& predMap(PredMap& m) {
472 480
      if (local_pred) {
473 481
        delete _pred;
474 482
      }
475 483
      local_pred = false;
476 484
      _pred = &m;
477 485
      return *this;
478 486
    }
479 487

	
480
    /// \name Query Functions
481
    /// The result of the %MinCostArborescence algorithm can be obtained
482
    /// using these functions.\n
483
    /// Before the use of these functions,
484
    /// either run() or start() must be called.
485

	
486
    /// @{
487

	
488
    /// \brief Returns a reference to the arborescence map.
489
    ///
490
    /// Returns a reference to the arborescence map.
491
    const ArborescenceMap& arborescenceMap() const {
492
      return *_arborescence;
493
    }
494

	
495
    /// \brief Returns true if the arc is in the arborescence.
496
    ///
497
    /// Returns true if the arc is in the arborescence.
498
    /// \param arc The arc of the digraph.
499
    /// \pre \ref run() must be called before using this function.
500
    bool arborescence(Arc arc) const {
501
      return (*_pred)[_digraph->target(arc)] == arc;
502
    }
503

	
504
    /// \brief Returns a reference to the pred map.
505
    ///
506
    /// Returns a reference to the pred map.
507
    const PredMap& predMap() const {
508
      return *_pred;
509
    }
510

	
511
    /// \brief Returns the predecessor arc of the given node.
512
    ///
513
    /// Returns the predecessor arc of the given node.
514
    Arc pred(Node node) const {
515
      return (*_pred)[node];
516
    }
517

	
518
    /// \brief Returns the cost of the arborescence.
519
    ///
520
    /// Returns the cost of the arborescence.
521
    Value arborescenceValue() const {
522
      Value sum = 0;
523
      for (ArcIt it(*_digraph); it != INVALID; ++it) {
524
        if (arborescence(it)) {
525
          sum += (*_cost)[it];
526
        }
527
      }
528
      return sum;
529
    }
530

	
531
    /// \brief Indicates that a node is reachable from the sources.
532
    ///
533
    /// Indicates that a node is reachable from the sources.
534
    bool reached(Node node) const {
535
      return (*_node_order)[node] != -3;
536
    }
537

	
538
    /// \brief Indicates that a node is processed.
539
    ///
540
    /// Indicates that a node is processed. The arborescence path exists
541
    /// from the source to the given node.
542
    bool processed(Node node) const {
543
      return (*_node_order)[node] == -1;
544
    }
545

	
546
    /// \brief Returns the number of the dual variables in basis.
547
    ///
548
    /// Returns the number of the dual variables in basis.
549
    int dualNum() const {
550
      return _dual_variables.size();
551
    }
552

	
553
    /// \brief Returns the value of the dual solution.
554
    ///
555
    /// Returns the value of the dual solution. It should be
556
    /// equal to the arborescence value.
557
    Value dualValue() const {
558
      Value sum = 0;
559
      for (int i = 0; i < int(_dual_variables.size()); ++i) {
560
        sum += _dual_variables[i].value;
561
      }
562
      return sum;
563
    }
564

	
565
    /// \brief Returns the number of the nodes in the dual variable.
566
    ///
567
    /// Returns the number of the nodes in the dual variable.
568
    int dualSize(int k) const {
569
      return _dual_variables[k].end - _dual_variables[k].begin;
570
    }
571

	
572
    /// \brief Returns the value of the dual variable.
573
    ///
574
    /// Returns the the value of the dual variable.
575
    const Value& dualValue(int k) const {
576
      return _dual_variables[k].value;
577
    }
578

	
579
    /// \brief Lemon iterator for get a dual variable.
580
    ///
581
    /// Lemon iterator for get a dual variable. This class provides
582
    /// a common style lemon iterator which gives back a subset of
583
    /// the nodes.
584
    class DualIt {
585
    public:
586

	
587
      /// \brief Constructor.
588
      ///
589
      /// Constructor for get the nodeset of the variable.
590
      DualIt(const MinCostArborescence& algorithm, int variable)
591
        : _algorithm(&algorithm)
592
      {
593
        _index = _algorithm->_dual_variables[variable].begin;
594
        _last = _algorithm->_dual_variables[variable].end;
595
      }
596

	
597
      /// \brief Conversion to node.
598
      ///
599
      /// Conversion to node.
600
      operator Node() const {
601
        return _algorithm->_dual_node_list[_index];
602
      }
603

	
604
      /// \brief Increment operator.
605
      ///
606
      /// Increment operator.
607
      DualIt& operator++() {
608
        ++_index;
609
        return *this;
610
      }
611

	
612
      /// \brief Validity checking
613
      ///
614
      /// Checks whether the iterator is invalid.
615
      bool operator==(Invalid) const {
616
        return _index == _last;
617
      }
618

	
619
      /// \brief Validity checking
620
      ///
621
      /// Checks whether the iterator is valid.
622
      bool operator!=(Invalid) const {
623
        return _index != _last;
624
      }
625

	
626
    private:
627
      const MinCostArborescence* _algorithm;
628
      int _index, _last;
629
    };
630

	
631
    /// @}
632

	
633 488
    /// \name Execution Control
634 489
    /// The simplest way to execute the algorithm is to use
635 490
    /// one of the member functions called \c run(...). \n
636 491
    /// If you need more control on the execution,
637 492
    /// first you must call \ref init(), then you can add several
638 493
    /// source nodes with \ref addSource().
639 494
    /// Finally \ref start() will perform the arborescence
640 495
    /// computation.
641 496

	
642 497
    ///@{
643 498

	
644 499
    /// \brief Initializes the internal data structures.
... ...
@@ -680,48 +535,49 @@
680 535
          }
681 536
        }
682 537
      }
683 538
      (*_node_order)[source] = -1;
684 539
    }
685 540

	
686 541
    /// \brief Processes the next node in the priority queue.
687 542
    ///
688 543
    /// Processes the next node in the priority queue.
689 544
    ///
690 545
    /// \return The processed node.
691 546
    ///
692
    /// \warning The queue must not be empty!
547
    /// \warning The queue must not be empty.
693 548
    Node processNextNode() {
694 549
      Node node = queue.back();
695 550
      queue.pop_back();
696 551
      if ((*_node_order)[node] == -2) {
697 552
        Arc arc = prepare(node);
698 553
        Node source = _digraph->source(arc);
699 554
        while ((*_node_order)[source] != -1) {
700 555
          if ((*_node_order)[source] >= 0) {
701 556
            arc = contract(source);
702 557
          } else {
703 558
            arc = prepare(source);
704 559
          }
705 560
          source = _digraph->source(arc);
706 561
        }
707 562
        finalize(arc);
708 563
        level_stack.clear();
709 564
      }
710 565
      return node;
711 566
    }
712 567

	
713 568
    /// \brief Returns the number of the nodes to be processed.
714 569
    ///
715
    /// Returns the number of the nodes to be processed.
570
    /// Returns the number of the nodes to be processed in the priority
571
    /// queue.
716 572
    int queueSize() const {
717 573
      return queue.size();
718 574
    }
719 575

	
720 576
    /// \brief Returns \c false if there are nodes to be processed.
721 577
    ///
722 578
    /// Returns \c false if there are nodes to be processed.
723 579
    bool emptyQueue() const {
724 580
      return queue.empty();
725 581
    }
726 582

	
727 583
    /// \brief Executes the algorithm.
... ...
@@ -745,50 +601,207 @@
745 601

	
746 602
    /// \brief Runs %MinCostArborescence algorithm from node \c s.
747 603
    ///
748 604
    /// This method runs the %MinCostArborescence algorithm from
749 605
    /// a root node \c s.
750 606
    ///
751 607
    /// \note mca.run(s) is just a shortcut of the following code.
752 608
    /// \code
753 609
    /// mca.init();
754 610
    /// mca.addSource(s);
755 611
    /// mca.start();
756 612
    /// \endcode
757
    void run(Node node) {
613
    void run(Node s) {
758 614
      init();
759
      addSource(node);
615
      addSource(s);
760 616
      start();
761 617
    }
762 618

	
763 619
    ///@}
764 620

	
621
    /// \name Query Functions
622
    /// The result of the %MinCostArborescence algorithm can be obtained
623
    /// using these functions.\n
624
    /// Either run() or start() must be called before using them.
625

	
626
    /// @{
627

	
628
    /// \brief Returns the cost of the arborescence.
629
    ///
630
    /// Returns the cost of the arborescence.
631
    Value arborescenceCost() const {
632
      Value sum = 0;
633
      for (ArcIt it(*_digraph); it != INVALID; ++it) {
634
        if (arborescence(it)) {
635
          sum += (*_cost)[it];
636
        }
637
      }
638
      return sum;
639
    }
640

	
641
    /// \brief Returns \c true if the arc is in the arborescence.
642
    ///
643
    /// Returns \c true if the given arc is in the arborescence.
644
    /// \param arc An arc of the digraph.
645
    /// \pre \ref run() must be called before using this function.
646
    bool arborescence(Arc arc) const {
647
      return (*_pred)[_digraph->target(arc)] == arc;
648
    }
649

	
650
    /// \brief Returns a const reference to the arborescence map.
651
    ///
652
    /// Returns a const reference to the arborescence map.
653
    /// \pre \ref run() must be called before using this function.
654
    const ArborescenceMap& arborescenceMap() const {
655
      return *_arborescence;
656
    }
657

	
658
    /// \brief Returns the predecessor arc of the given node.
659
    ///
660
    /// Returns the predecessor arc of the given node.
661
    /// \pre \ref run() must be called before using this function.
662
    Arc pred(Node node) const {
663
      return (*_pred)[node];
664
    }
665

	
666
    /// \brief Returns a const reference to the pred map.
667
    ///
668
    /// Returns a const reference to the pred map.
669
    /// \pre \ref run() must be called before using this function.
670
    const PredMap& predMap() const {
671
      return *_pred;
672
    }
673

	
674
    /// \brief Indicates that a node is reachable from the sources.
675
    ///
676
    /// Indicates that a node is reachable from the sources.
677
    bool reached(Node node) const {
678
      return (*_node_order)[node] != -3;
679
    }
680

	
681
    /// \brief Indicates that a node is processed.
682
    ///
683
    /// Indicates that a node is processed. The arborescence path exists
684
    /// from the source to the given node.
685
    bool processed(Node node) const {
686
      return (*_node_order)[node] == -1;
687
    }
688

	
689
    /// \brief Returns the number of the dual variables in basis.
690
    ///
691
    /// Returns the number of the dual variables in basis.
692
    int dualNum() const {
693
      return _dual_variables.size();
694
    }
695

	
696
    /// \brief Returns the value of the dual solution.
697
    ///
698
    /// Returns the value of the dual solution. It should be
699
    /// equal to the arborescence value.
700
    Value dualValue() const {
701
      Value sum = 0;
702
      for (int i = 0; i < int(_dual_variables.size()); ++i) {
703
        sum += _dual_variables[i].value;
704
      }
705
      return sum;
706
    }
707

	
708
    /// \brief Returns the number of the nodes in the dual variable.
709
    ///
710
    /// Returns the number of the nodes in the dual variable.
711
    int dualSize(int k) const {
712
      return _dual_variables[k].end - _dual_variables[k].begin;
713
    }
714

	
715
    /// \brief Returns the value of the dual variable.
716
    ///
717
    /// Returns the the value of the dual variable.
718
    Value dualValue(int k) const {
719
      return _dual_variables[k].value;
720
    }
721

	
722
    /// \brief LEMON iterator for getting a dual variable.
723
    ///
724
    /// This class provides a common style LEMON iterator for getting a
725
    /// dual variable of \ref MinCostArborescence algorithm.
726
    /// It iterates over a subset of the nodes.
727
    class DualIt {
728
    public:
729

	
730
      /// \brief Constructor.
731
      ///
732
      /// Constructor for getting the nodeset of the dual variable
733
      /// of \ref MinCostArborescence algorithm.
734
      DualIt(const MinCostArborescence& algorithm, int variable)
735
        : _algorithm(&algorithm)
736
      {
737
        _index = _algorithm->_dual_variables[variable].begin;
738
        _last = _algorithm->_dual_variables[variable].end;
739
      }
740

	
741
      /// \brief Conversion to \c Node.
742
      ///
743
      /// Conversion to \c Node.
744
      operator Node() const {
745
        return _algorithm->_dual_node_list[_index];
746
      }
747

	
748
      /// \brief Increment operator.
749
      ///
750
      /// Increment operator.
751
      DualIt& operator++() {
752
        ++_index;
753
        return *this;
754
      }
755

	
756
      /// \brief Validity checking
757
      ///
758
      /// Checks whether the iterator is invalid.
759
      bool operator==(Invalid) const {
760
        return _index == _last;
761
      }
762

	
763
      /// \brief Validity checking
764
      ///
765
      /// Checks whether the iterator is valid.
766
      bool operator!=(Invalid) const {
767
        return _index != _last;
768
      }
769

	
770
    private:
771
      const MinCostArborescence* _algorithm;
772
      int _index, _last;
773
    };
774

	
775
    /// @}
776

	
765 777
  };
766 778

	
767 779
  /// \ingroup spantree
768 780
  ///
769 781
  /// \brief Function type interface for MinCostArborescence algorithm.
770 782
  ///
771 783
  /// Function type interface for MinCostArborescence algorithm.
772
  /// \param digraph The Digraph that the algorithm runs on.
773
  /// \param cost The CostMap of the arcs.
774
  /// \param source The source of the arborescence.
775
  /// \retval arborescence The bool ArcMap which stores the arborescence.
776
  /// \return The cost of the arborescence.
784
  /// \param digraph The digraph the algorithm runs on.
785
  /// \param cost An arc map storing the costs.
786
  /// \param source The source node of the arborescence.
787
  /// \retval arborescence An arc map with \c bool (or convertible) value
788
  /// type that stores the arborescence.
789
  /// \return The total cost of the arborescence.
777 790
  ///
778 791
  /// \sa MinCostArborescence
779 792
  template <typename Digraph, typename CostMap, typename ArborescenceMap>
780 793
  typename CostMap::Value minCostArborescence(const Digraph& digraph,
781 794
                                              const CostMap& cost,
782 795
                                              typename Digraph::Node source,
783 796
                                              ArborescenceMap& arborescence) {
784 797
    typename MinCostArborescence<Digraph, CostMap>
785
      ::template DefArborescenceMap<ArborescenceMap>
798
      ::template SetArborescenceMap<ArborescenceMap>
786 799
      ::Create mca(digraph, cost);
787 800
    mca.arborescenceMap(arborescence);
788 801
    mca.run(source);
789
    return mca.arborescenceValue();
802
    return mca.arborescenceCost();
790 803
  }
791 804

	
792 805
}
793 806

	
794 807
#endif
Ignore white space 24 line context
... ...
@@ -15,24 +15,25 @@
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20
#include <set>
21 21
#include <vector>
22 22
#include <iterator>
23 23

	
24 24
#include <lemon/smart_graph.h>
25 25
#include <lemon/min_cost_arborescence.h>
26 26
#include <lemon/lgf_reader.h>
27
#include <lemon/concepts/digraph.h>
27 28

	
28 29
#include "test_tools.h"
29 30

	
30 31
using namespace lemon;
31 32
using namespace std;
32 33

	
33 34
const char test_lgf[] =
34 35
  "@nodes\n"
35 36
  "label\n"
36 37
  "0\n"
37 38
  "1\n"
38 39
  "2\n"
... ...
@@ -61,24 +62,83 @@
61 62
  "6 3  13     95\n"
62 63
  "4 1  14     22\n"
63 64
  "1 1  15     31\n"
64 65
  "7 2  16     51\n"
65 66
  "2 6  17     29\n"
66 67
  "8 3  18     115\n"
67 68
  "6 9  19     32\n"
68 69
  "1 1  20     60\n"
69 70
  "0 3  21     40\n"
70 71
  "@attributes\n"
71 72
  "source 0\n";
72 73

	
74

	
75
void checkMinCostArborescenceCompile()
76
{
77
  typedef double VType;
78
  typedef concepts::Digraph Digraph;
79
  typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
80
  typedef Digraph::Node Node;
81
  typedef Digraph::Arc Arc;
82
  typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
83
  typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
84

	
85
  typedef MinCostArborescence<Digraph, CostMap>::
86
            SetArborescenceMap<ArbMap>::
87
            SetPredMap<PredMap>::Create MinCostArbType;
88

	
89
  Digraph g;
90
  Node s, n;
91
  Arc e;
92
  VType c;
93
  bool b;
94
  int i;
95
  CostMap cost;
96
  ArbMap arb;
97
  PredMap pred;
98

	
99
  MinCostArbType mcarb_test(g, cost);
100
  const MinCostArbType& const_mcarb_test = mcarb_test;
101

	
102
  mcarb_test
103
    .arborescenceMap(arb)
104
    .predMap(pred)
105
    .run(s);
106

	
107
  mcarb_test.init();
108
  mcarb_test.addSource(s);
109
  mcarb_test.start();
110
  n = mcarb_test.processNextNode();
111
  b = const_mcarb_test.emptyQueue();
112
  i = const_mcarb_test.queueSize();
113
  
114
  c = const_mcarb_test.arborescenceCost();
115
  b = const_mcarb_test.arborescence(e);
116
  e = const_mcarb_test.pred(n);
117
  const MinCostArbType::ArborescenceMap &am =
118
    const_mcarb_test.arborescenceMap();
119
  const MinCostArbType::PredMap &pm =
120
    const_mcarb_test.predMap();
121
  b = const_mcarb_test.reached(n);
122
  b = const_mcarb_test.processed(n);
123
  
124
  i = const_mcarb_test.dualNum();
125
  c = const_mcarb_test.dualValue();
126
  i = const_mcarb_test.dualSize(i);
127
  c = const_mcarb_test.dualValue(i);
128
  
129
  ignore_unused_variable_warning(am);
130
  ignore_unused_variable_warning(pm);
131
}
132

	
73 133
int main() {
74 134
  typedef SmartDigraph Digraph;
75 135
  DIGRAPH_TYPEDEFS(Digraph);
76 136

	
77 137
  typedef Digraph::ArcMap<double> CostMap;
78 138

	
79 139
  Digraph digraph;
80 140
  CostMap cost(digraph);
81 141
  Node source;
82 142

	
83 143
  std::istringstream is(test_lgf);
84 144
  digraphReader(digraph, is).
... ...
@@ -101,46 +161,46 @@
101 161
  for (ArcIt it(digraph); it != INVALID; ++it) {
102 162
    if (mca.reached(digraph.source(it))) {
103 163
      double sum = 0.0;
104 164
      for (int i = 0; i < int(dualSolution.size()); ++i) {
105 165
        if (dualSolution[i].second.find(digraph.target(it))
106 166
            != dualSolution[i].second.end() &&
107 167
            dualSolution[i].second.find(digraph.source(it))
108 168
            == dualSolution[i].second.end()) {
109 169
          sum += dualSolution[i].first;
110 170
        }
111 171
      }
112 172
      if (mca.arborescence(it)) {
113
        check(sum == cost[it], "INVALID DUAL");
173
        check(sum == cost[it], "Invalid dual solution");
114 174
      }
115
      check(sum <= cost[it], "INVALID DUAL");
175
      check(sum <= cost[it], "Invalid dual solution");
116 176
    }
117 177
  }
118 178

	
119 179

	
120
  check(mca.dualValue() == mca.arborescenceValue(), "INVALID DUAL");
180
  check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
121 181

	
122
  check(mca.reached(source), "INVALID ARBORESCENCE");
182
  check(mca.reached(source), "Invalid arborescence");
123 183
  for (ArcIt a(digraph); a != INVALID; ++a) {
124 184
    check(!mca.reached(digraph.source(a)) ||
125
          mca.reached(digraph.target(a)), "INVALID ARBORESCENCE");
185
          mca.reached(digraph.target(a)), "Invalid arborescence");
126 186
  }
127 187

	
128 188
  for (NodeIt n(digraph); n != INVALID; ++n) {
129 189
    if (!mca.reached(n)) continue;
130 190
    int cnt = 0;
131 191
    for (InArcIt a(digraph, n); a != INVALID; ++a) {
132 192
      if (mca.arborescence(a)) {
133
        check(mca.pred(n) == a, "INVALID ARBORESCENCE");
193
        check(mca.pred(n) == a, "Invalid arborescence");
134 194
        ++cnt;
135 195
      }
136 196
    }
137
    check((n == source ? cnt == 0 : cnt == 1), "INVALID ARBORESCENCE");
197
    check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
138 198
  }
139 199

	
140 200
  Digraph::ArcMap<bool> arborescence(digraph);
141
  check(mca.arborescenceValue() ==
201
  check(mca.arborescenceCost() ==
142 202
        minCostArborescence(digraph, cost, source, arborescence),
143
        "WRONG FUNCTION");
203
        "Wrong result of the function interface");
144 204

	
145 205
  return 0;
146 206
}
0 comments (0 inline)