lemon/concepts/digraph.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 786 e20173729589
child 1049 7bf489cf624e
child 1084 8b2d4e5d96e4
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@57
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@57
     4
 *
alpar@877
     5
 * Copyright (C) 2003-2010
deba@57
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@57
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@57
     8
 *
deba@57
     9
 * Permission to use, modify and distribute this software is granted
deba@57
    10
 * provided that this copyright notice appears in all copies. For
deba@57
    11
 * precise terms see the accompanying LICENSE file.
deba@57
    12
 *
deba@57
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@57
    14
 * express or implied, and with no claim as to its suitability for any
deba@57
    15
 * purpose.
deba@57
    16
 *
deba@57
    17
 */
deba@57
    18
deba@529
    19
#ifndef LEMON_CONCEPTS_DIGRAPH_H
deba@529
    20
#define LEMON_CONCEPTS_DIGRAPH_H
deba@57
    21
deba@57
    22
///\ingroup graph_concepts
deba@57
    23
///\file
deba@57
    24
///\brief The concept of directed graphs.
deba@57
    25
deba@220
    26
#include <lemon/core.h>
deba@57
    27
#include <lemon/concepts/maps.h>
deba@57
    28
#include <lemon/concept_check.h>
deba@57
    29
#include <lemon/concepts/graph_components.h>
deba@57
    30
deba@57
    31
namespace lemon {
deba@57
    32
  namespace concepts {
deba@57
    33
deba@57
    34
    /// \ingroup graph_concepts
deba@57
    35
    ///
deba@57
    36
    /// \brief Class describing the concept of directed graphs.
deba@57
    37
    ///
kpeter@734
    38
    /// This class describes the common interface of all directed
kpeter@734
    39
    /// graphs (digraphs).
deba@57
    40
    ///
kpeter@734
    41
    /// Like all concept classes, it only provides an interface
kpeter@734
    42
    /// without any sensible implementation. So any general algorithm for
kpeter@734
    43
    /// directed graphs should compile with this class, but it will not
kpeter@734
    44
    /// run properly, of course.
kpeter@734
    45
    /// An actual digraph implementation like \ref ListDigraph or
kpeter@734
    46
    /// \ref SmartDigraph may have additional functionality.
deba@57
    47
    ///
kpeter@734
    48
    /// \sa Graph
deba@57
    49
    class Digraph {
deba@57
    50
    private:
kpeter@734
    51
      /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
kpeter@734
    52
      Digraph(const Digraph &) {}
kpeter@734
    53
      /// \brief Assignment of a digraph to another one is \e not allowed.
kpeter@734
    54
      /// Use DigraphCopy instead.
kpeter@734
    55
      void operator=(const Digraph &) {}
alpar@209
    56
kpeter@734
    57
    public:
kpeter@734
    58
      /// Default constructor.
kpeter@734
    59
      Digraph() { }
alpar@209
    60
kpeter@734
    61
      /// The node type of the digraph
deba@57
    62
deba@57
    63
      /// This class identifies a node of the digraph. It also serves
deba@57
    64
      /// as a base class of the node iterators,
kpeter@734
    65
      /// thus they convert to this type.
deba@57
    66
      class Node {
deba@57
    67
      public:
deba@57
    68
        /// Default constructor
deba@57
    69
kpeter@734
    70
        /// Default constructor.
kpeter@734
    71
        /// \warning It sets the object to an undefined value.
deba@57
    72
        Node() { }
deba@57
    73
        /// Copy constructor.
deba@57
    74
deba@57
    75
        /// Copy constructor.
deba@57
    76
        ///
deba@57
    77
        Node(const Node&) { }
deba@57
    78
kpeter@734
    79
        /// %Invalid constructor \& conversion.
deba@57
    80
kpeter@734
    81
        /// Initializes the object to be invalid.
deba@57
    82
        /// \sa Invalid for more details.
deba@57
    83
        Node(Invalid) { }
deba@57
    84
        /// Equality operator
deba@57
    85
kpeter@734
    86
        /// Equality operator.
kpeter@734
    87
        ///
deba@57
    88
        /// Two iterators are equal if and only if they point to the
kpeter@734
    89
        /// same object or both are \c INVALID.
deba@57
    90
        bool operator==(Node) const { return true; }
deba@57
    91
deba@57
    92
        /// Inequality operator
alpar@209
    93
kpeter@734
    94
        /// Inequality operator.
deba@57
    95
        bool operator!=(Node) const { return true; }
deba@57
    96
alpar@209
    97
        /// Artificial ordering operator.
alpar@209
    98
kpeter@734
    99
        /// Artificial ordering operator.
alpar@209
   100
        ///
kpeter@734
   101
        /// \note This operator only has to define some strict ordering of
kpeter@734
   102
        /// the nodes; this order has nothing to do with the iteration
kpeter@734
   103
        /// ordering of the nodes.
alpar@209
   104
        bool operator<(Node) const { return false; }
deba@57
   105
      };
alpar@209
   106
kpeter@734
   107
      /// Iterator class for the nodes.
deba@57
   108
kpeter@734
   109
      /// This iterator goes through each node of the digraph.
kpeter@786
   110
      /// Its usage is quite simple, for example, you can count the number
kpeter@734
   111
      /// of nodes in a digraph \c g of type \c %Digraph like this:
deba@57
   112
      ///\code
deba@57
   113
      /// int count=0;
deba@57
   114
      /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
deba@57
   115
      ///\endcode
deba@57
   116
      class NodeIt : public Node {
deba@57
   117
      public:
deba@57
   118
        /// Default constructor
deba@57
   119
kpeter@734
   120
        /// Default constructor.
kpeter@734
   121
        /// \warning It sets the iterator to an undefined value.
deba@57
   122
        NodeIt() { }
deba@57
   123
        /// Copy constructor.
alpar@209
   124
deba@57
   125
        /// Copy constructor.
deba@57
   126
        ///
deba@57
   127
        NodeIt(const NodeIt& n) : Node(n) { }
kpeter@734
   128
        /// %Invalid constructor \& conversion.
deba@57
   129
kpeter@734
   130
        /// Initializes the iterator to be invalid.
deba@57
   131
        /// \sa Invalid for more details.
deba@57
   132
        NodeIt(Invalid) { }
deba@57
   133
        /// Sets the iterator to the first node.
deba@57
   134
kpeter@734
   135
        /// Sets the iterator to the first node of the given digraph.
deba@57
   136
        ///
kpeter@734
   137
        explicit NodeIt(const Digraph&) { }
kpeter@734
   138
        /// Sets the iterator to the given node.
deba@57
   139
kpeter@734
   140
        /// Sets the iterator to the given node of the given digraph.
kpeter@734
   141
        ///
deba@57
   142
        NodeIt(const Digraph&, const Node&) { }
deba@57
   143
        /// Next node.
deba@57
   144
deba@57
   145
        /// Assign the iterator to the next node.
deba@57
   146
        ///
deba@57
   147
        NodeIt& operator++() { return *this; }
deba@57
   148
      };
alpar@209
   149
alpar@209
   150
kpeter@734
   151
      /// The arc type of the digraph
deba@57
   152
deba@57
   153
      /// This class identifies an arc of the digraph. It also serves
deba@57
   154
      /// as a base class of the arc iterators,
deba@57
   155
      /// thus they will convert to this type.
deba@57
   156
      class Arc {
deba@57
   157
      public:
deba@57
   158
        /// Default constructor
deba@57
   159
kpeter@734
   160
        /// Default constructor.
kpeter@734
   161
        /// \warning It sets the object to an undefined value.
deba@57
   162
        Arc() { }
deba@57
   163
        /// Copy constructor.
deba@57
   164
deba@57
   165
        /// Copy constructor.
deba@57
   166
        ///
deba@57
   167
        Arc(const Arc&) { }
kpeter@734
   168
        /// %Invalid constructor \& conversion.
deba@57
   169
kpeter@734
   170
        /// Initializes the object to be invalid.
kpeter@734
   171
        /// \sa Invalid for more details.
deba@57
   172
        Arc(Invalid) { }
deba@57
   173
        /// Equality operator
deba@57
   174
kpeter@734
   175
        /// Equality operator.
kpeter@734
   176
        ///
deba@57
   177
        /// Two iterators are equal if and only if they point to the
kpeter@734
   178
        /// same object or both are \c INVALID.
deba@57
   179
        bool operator==(Arc) const { return true; }
deba@57
   180
        /// Inequality operator
deba@57
   181
kpeter@734
   182
        /// Inequality operator.
deba@57
   183
        bool operator!=(Arc) const { return true; }
deba@57
   184
alpar@209
   185
        /// Artificial ordering operator.
alpar@209
   186
kpeter@734
   187
        /// Artificial ordering operator.
alpar@209
   188
        ///
kpeter@734
   189
        /// \note This operator only has to define some strict ordering of
kpeter@734
   190
        /// the arcs; this order has nothing to do with the iteration
kpeter@734
   191
        /// ordering of the arcs.
alpar@209
   192
        bool operator<(Arc) const { return false; }
deba@57
   193
      };
alpar@209
   194
kpeter@734
   195
      /// Iterator class for the outgoing arcs of a node.
deba@57
   196
deba@57
   197
      /// This iterator goes trough the \e outgoing arcs of a certain node
deba@57
   198
      /// of a digraph.
kpeter@786
   199
      /// Its usage is quite simple, for example, you can count the number
deba@57
   200
      /// of outgoing arcs of a node \c n
kpeter@734
   201
      /// in a digraph \c g of type \c %Digraph as follows.
deba@57
   202
      ///\code
deba@57
   203
      /// int count=0;
kpeter@734
   204
      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
deba@57
   205
      ///\endcode
deba@57
   206
      class OutArcIt : public Arc {
deba@57
   207
      public:
deba@57
   208
        /// Default constructor
deba@57
   209
kpeter@734
   210
        /// Default constructor.
kpeter@734
   211
        /// \warning It sets the iterator to an undefined value.
deba@57
   212
        OutArcIt() { }
deba@57
   213
        /// Copy constructor.
deba@57
   214
deba@57
   215
        /// Copy constructor.
deba@57
   216
        ///
deba@57
   217
        OutArcIt(const OutArcIt& e) : Arc(e) { }
kpeter@734
   218
        /// %Invalid constructor \& conversion.
deba@57
   219
kpeter@734
   220
        /// Initializes the iterator to be invalid.
kpeter@734
   221
        /// \sa Invalid for more details.
kpeter@734
   222
        OutArcIt(Invalid) { }
kpeter@734
   223
        /// Sets the iterator to the first outgoing arc.
kpeter@734
   224
kpeter@734
   225
        /// Sets the iterator to the first outgoing arc of the given node.
deba@57
   226
        ///
kpeter@734
   227
        OutArcIt(const Digraph&, const Node&) { }
kpeter@734
   228
        /// Sets the iterator to the given arc.
alpar@209
   229
kpeter@734
   230
        /// Sets the iterator to the given arc of the given digraph.
kpeter@734
   231
        ///
deba@57
   232
        OutArcIt(const Digraph&, const Arc&) { }
kpeter@734
   233
        /// Next outgoing arc
alpar@209
   234
alpar@209
   235
        /// Assign the iterator to the next
deba@57
   236
        /// outgoing arc of the corresponding node.
deba@57
   237
        OutArcIt& operator++() { return *this; }
deba@57
   238
      };
deba@57
   239
kpeter@734
   240
      /// Iterator class for the incoming arcs of a node.
deba@57
   241
deba@57
   242
      /// This iterator goes trough the \e incoming arcs of a certain node
deba@57
   243
      /// of a digraph.
kpeter@786
   244
      /// Its usage is quite simple, for example, you can count the number
kpeter@734
   245
      /// of incoming arcs of a node \c n
kpeter@734
   246
      /// in a digraph \c g of type \c %Digraph as follows.
deba@57
   247
      ///\code
deba@57
   248
      /// int count=0;
kpeter@734
   249
      /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
deba@57
   250
      ///\endcode
deba@57
   251
      class InArcIt : public Arc {
deba@57
   252
      public:
deba@57
   253
        /// Default constructor
deba@57
   254
kpeter@734
   255
        /// Default constructor.
kpeter@734
   256
        /// \warning It sets the iterator to an undefined value.
deba@57
   257
        InArcIt() { }
deba@57
   258
        /// Copy constructor.
deba@57
   259
deba@57
   260
        /// Copy constructor.
deba@57
   261
        ///
deba@57
   262
        InArcIt(const InArcIt& e) : Arc(e) { }
kpeter@734
   263
        /// %Invalid constructor \& conversion.
deba@57
   264
kpeter@734
   265
        /// Initializes the iterator to be invalid.
kpeter@734
   266
        /// \sa Invalid for more details.
kpeter@734
   267
        InArcIt(Invalid) { }
kpeter@734
   268
        /// Sets the iterator to the first incoming arc.
kpeter@734
   269
kpeter@734
   270
        /// Sets the iterator to the first incoming arc of the given node.
deba@57
   271
        ///
kpeter@734
   272
        InArcIt(const Digraph&, const Node&) { }
kpeter@734
   273
        /// Sets the iterator to the given arc.
alpar@209
   274
kpeter@734
   275
        /// Sets the iterator to the given arc of the given digraph.
kpeter@734
   276
        ///
deba@57
   277
        InArcIt(const Digraph&, const Arc&) { }
deba@57
   278
        /// Next incoming arc
deba@57
   279
kpeter@734
   280
        /// Assign the iterator to the next
kpeter@734
   281
        /// incoming arc of the corresponding node.
deba@57
   282
        InArcIt& operator++() { return *this; }
deba@57
   283
      };
deba@57
   284
kpeter@734
   285
      /// Iterator class for the arcs.
kpeter@734
   286
kpeter@734
   287
      /// This iterator goes through each arc of the digraph.
kpeter@786
   288
      /// Its usage is quite simple, for example, you can count the number
kpeter@734
   289
      /// of arcs in a digraph \c g of type \c %Digraph as follows:
deba@57
   290
      ///\code
deba@57
   291
      /// int count=0;
kpeter@734
   292
      /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
deba@57
   293
      ///\endcode
deba@57
   294
      class ArcIt : public Arc {
deba@57
   295
      public:
deba@57
   296
        /// Default constructor
deba@57
   297
kpeter@734
   298
        /// Default constructor.
kpeter@734
   299
        /// \warning It sets the iterator to an undefined value.
deba@57
   300
        ArcIt() { }
deba@57
   301
        /// Copy constructor.
deba@57
   302
deba@57
   303
        /// Copy constructor.
deba@57
   304
        ///
deba@57
   305
        ArcIt(const ArcIt& e) : Arc(e) { }
kpeter@734
   306
        /// %Invalid constructor \& conversion.
deba@57
   307
kpeter@734
   308
        /// Initializes the iterator to be invalid.
kpeter@734
   309
        /// \sa Invalid for more details.
kpeter@734
   310
        ArcIt(Invalid) { }
kpeter@734
   311
        /// Sets the iterator to the first arc.
kpeter@734
   312
kpeter@734
   313
        /// Sets the iterator to the first arc of the given digraph.
deba@57
   314
        ///
kpeter@734
   315
        explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
kpeter@734
   316
        /// Sets the iterator to the given arc.
alpar@209
   317
kpeter@734
   318
        /// Sets the iterator to the given arc of the given digraph.
kpeter@734
   319
        ///
alpar@209
   320
        ArcIt(const Digraph&, const Arc&) { }
kpeter@734
   321
        /// Next arc
alpar@209
   322
deba@57
   323
        /// Assign the iterator to the next arc.
kpeter@734
   324
        ///
deba@57
   325
        ArcIt& operator++() { return *this; }
deba@57
   326
      };
deba@57
   327
kpeter@734
   328
      /// \brief The source node of the arc.
deba@57
   329
      ///
kpeter@734
   330
      /// Returns the source node of the given arc.
deba@57
   331
      Node source(Arc) const { return INVALID; }
deba@57
   332
kpeter@734
   333
      /// \brief The target node of the arc.
kpeter@734
   334
      ///
kpeter@734
   335
      /// Returns the target node of the given arc.
kpeter@734
   336
      Node target(Arc) const { return INVALID; }
kpeter@734
   337
kpeter@734
   338
      /// \brief The ID of the node.
kpeter@734
   339
      ///
kpeter@734
   340
      /// Returns the ID of the given node.
alpar@209
   341
      int id(Node) const { return -1; }
deba@61
   342
kpeter@734
   343
      /// \brief The ID of the arc.
kpeter@734
   344
      ///
kpeter@734
   345
      /// Returns the ID of the given arc.
alpar@209
   346
      int id(Arc) const { return -1; }
deba@61
   347
kpeter@734
   348
      /// \brief The node with the given ID.
deba@61
   349
      ///
kpeter@734
   350
      /// Returns the node with the given ID.
kpeter@734
   351
      /// \pre The argument should be a valid node ID in the digraph.
alpar@209
   352
      Node nodeFromId(int) const { return INVALID; }
deba@61
   353
kpeter@734
   354
      /// \brief The arc with the given ID.
deba@61
   355
      ///
kpeter@734
   356
      /// Returns the arc with the given ID.
kpeter@734
   357
      /// \pre The argument should be a valid arc ID in the digraph.
alpar@209
   358
      Arc arcFromId(int) const { return INVALID; }
deba@61
   359
kpeter@734
   360
      /// \brief An upper bound on the node IDs.
kpeter@734
   361
      ///
kpeter@734
   362
      /// Returns an upper bound on the node IDs.
alpar@209
   363
      int maxNodeId() const { return -1; }
deba@61
   364
kpeter@734
   365
      /// \brief An upper bound on the arc IDs.
kpeter@734
   366
      ///
kpeter@734
   367
      /// Returns an upper bound on the arc IDs.
alpar@209
   368
      int maxArcId() const { return -1; }
deba@61
   369
deba@57
   370
      void first(Node&) const {}
deba@57
   371
      void next(Node&) const {}
deba@57
   372
deba@57
   373
      void first(Arc&) const {}
deba@57
   374
      void next(Arc&) const {}
deba@57
   375
deba@57
   376
deba@57
   377
      void firstIn(Arc&, const Node&) const {}
deba@57
   378
      void nextIn(Arc&) const {}
deba@57
   379
deba@57
   380
      void firstOut(Arc&, const Node&) const {}
deba@57
   381
      void nextOut(Arc&) const {}
deba@57
   382
deba@61
   383
      // The second parameter is dummy.
deba@61
   384
      Node fromId(int, Node) const { return INVALID; }
deba@61
   385
      // The second parameter is dummy.
deba@61
   386
      Arc fromId(int, Arc) const { return INVALID; }
deba@61
   387
deba@61
   388
      // Dummy parameter.
alpar@209
   389
      int maxId(Node) const { return -1; }
deba@61
   390
      // Dummy parameter.
alpar@209
   391
      int maxId(Arc) const { return -1; }
deba@61
   392
kpeter@734
   393
      /// \brief The opposite node on the arc.
kpeter@734
   394
      ///
kpeter@734
   395
      /// Returns the opposite node on the given arc.
kpeter@734
   396
      Node oppositeNode(Node, Arc) const { return INVALID; }
kpeter@734
   397
deba@57
   398
      /// \brief The base node of the iterator.
deba@57
   399
      ///
kpeter@734
   400
      /// Returns the base node of the given outgoing arc iterator
kpeter@734
   401
      /// (i.e. the source node of the corresponding arc).
kpeter@734
   402
      Node baseNode(OutArcIt) const { return INVALID; }
deba@57
   403
deba@57
   404
      /// \brief The running node of the iterator.
deba@57
   405
      ///
kpeter@734
   406
      /// Returns the running node of the given outgoing arc iterator
kpeter@734
   407
      /// (i.e. the target node of the corresponding arc).
kpeter@734
   408
      Node runningNode(OutArcIt) const { return INVALID; }
deba@57
   409
deba@57
   410
      /// \brief The base node of the iterator.
deba@57
   411
      ///
kpeter@734
   412
      /// Returns the base node of the given incomming arc iterator
kpeter@734
   413
      /// (i.e. the target node of the corresponding arc).
kpeter@734
   414
      Node baseNode(InArcIt) const { return INVALID; }
deba@57
   415
deba@57
   416
      /// \brief The running node of the iterator.
deba@57
   417
      ///
kpeter@734
   418
      /// Returns the running node of the given incomming arc iterator
kpeter@734
   419
      /// (i.e. the source node of the corresponding arc).
kpeter@734
   420
      Node runningNode(InArcIt) const { return INVALID; }
deba@57
   421
kpeter@734
   422
      /// \brief Standard graph map type for the nodes.
deba@57
   423
      ///
kpeter@734
   424
      /// Standard graph map type for the nodes.
kpeter@734
   425
      /// It conforms to the ReferenceMap concept.
alpar@209
   426
      template<class T>
kpeter@580
   427
      class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
deba@57
   428
      public:
deba@57
   429
kpeter@734
   430
        /// Constructor
kpeter@734
   431
        explicit NodeMap(const Digraph&) { }
kpeter@734
   432
        /// Constructor with given initial value
deba@57
   433
        NodeMap(const Digraph&, T) { }
deba@57
   434
kpeter@263
   435
      private:
deba@57
   436
        ///Copy constructor
alpar@877
   437
        NodeMap(const NodeMap& nm) :
kpeter@580
   438
          ReferenceMap<Node, T, T&, const T&>(nm) { }
deba@57
   439
        ///Assignment operator
deba@57
   440
        template <typename CMap>
alpar@209
   441
        NodeMap& operator=(const CMap&) {
deba@57
   442
          checkConcept<ReadMap<Node, T>, CMap>();
alpar@209
   443
          return *this;
deba@57
   444
        }
deba@57
   445
      };
deba@57
   446
kpeter@734
   447
      /// \brief Standard graph map type for the arcs.
deba@57
   448
      ///
kpeter@734
   449
      /// Standard graph map type for the arcs.
kpeter@734
   450
      /// It conforms to the ReferenceMap concept.
alpar@209
   451
      template<class T>
kpeter@580
   452
      class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
deba@57
   453
      public:
deba@57
   454
kpeter@734
   455
        /// Constructor
kpeter@734
   456
        explicit ArcMap(const Digraph&) { }
kpeter@734
   457
        /// Constructor with given initial value
deba@57
   458
        ArcMap(const Digraph&, T) { }
kpeter@734
   459
kpeter@263
   460
      private:
deba@57
   461
        ///Copy constructor
kpeter@580
   462
        ArcMap(const ArcMap& em) :
kpeter@580
   463
          ReferenceMap<Arc, T, T&, const T&>(em) { }
deba@57
   464
        ///Assignment operator
deba@57
   465
        template <typename CMap>
alpar@209
   466
        ArcMap& operator=(const CMap&) {
deba@57
   467
          checkConcept<ReadMap<Arc, T>, CMap>();
alpar@209
   468
          return *this;
deba@57
   469
        }
deba@57
   470
      };
deba@57
   471
deba@125
   472
      template <typename _Digraph>
deba@57
   473
      struct Constraints {
deba@57
   474
        void constraints() {
kpeter@580
   475
          checkConcept<BaseDigraphComponent, _Digraph>();
deba@125
   476
          checkConcept<IterableDigraphComponent<>, _Digraph>();
alpar@209
   477
          checkConcept<IDableDigraphComponent<>, _Digraph>();
deba@125
   478
          checkConcept<MappableDigraphComponent<>, _Digraph>();
deba@57
   479
        }
deba@57
   480
      };
deba@57
   481
deba@57
   482
    };
alpar@209
   483
alpar@209
   484
  } //namespace concepts
deba@57
   485
} //namespace lemon
deba@57
   486
deba@57
   487
deba@57
   488
deba@529
   489
#endif