lemon/path_utils.h
author deba
Mon, 08 Jan 2007 10:39:59 +0000
changeset 2335 27aa03cd3121
child 2350 eb371753e814
permissions -rw-r--r--
New path concept and path structures

TODO: BellmanFord::negativeCycle()
deba@2335
     1
/* -*- C++ -*-
deba@2335
     2
 *
deba@2335
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2335
     4
 *
deba@2335
     5
 * Copyright (C) 2003-2006
deba@2335
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2335
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2335
     8
 *
deba@2335
     9
 * Permission to use, modify and distribute this software is granted
deba@2335
    10
 * provided that this copyright notice appears in all copies. For
deba@2335
    11
 * precise terms see the accompanying LICENSE file.
deba@2335
    12
 *
deba@2335
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2335
    14
 * express or implied, and with no claim as to its suitability for any
deba@2335
    15
 * purpose.
deba@2335
    16
 *
deba@2335
    17
 */
deba@2335
    18
deba@2335
    19
deba@2335
    20
///\ingroup paths
deba@2335
    21
///\file
deba@2335
    22
///\brief Classes for representing paths in graphs.
deba@2335
    23
///
deba@2335
    24
deba@2335
    25
#ifndef LEMON_PATH_UTILS_H
deba@2335
    26
#define LEMON_PATH_UTILS_H
deba@2335
    27
deba@2335
    28
#include <lemon/concepts/path.h>
deba@2335
    29
deba@2335
    30
namespace lemon {
deba@2335
    31
deba@2335
    32
  namespace _path_bits {
deba@2335
    33
deba@2335
    34
    template <typename Path, typename Enable = void>
deba@2335
    35
    struct RevTagIndicator {
deba@2335
    36
      static const bool value = false;
deba@2335
    37
    };
deba@2335
    38
deba@2335
    39
    template <typename Graph>
deba@2335
    40
    struct RevTagIndicator<
deba@2335
    41
      Graph, 
deba@2335
    42
      typename enable_if<typename Graph::RevTag, void>::type
deba@2335
    43
    > {
deba@2335
    44
      static const bool value = true;
deba@2335
    45
    };
deba@2335
    46
deba@2335
    47
    template <typename Target, typename Source,
deba@2335
    48
              typename BuildEnable = void, typename RevEnable = void>
deba@2335
    49
    struct PathCopySelector {
deba@2335
    50
      static void copy(Target& target, const Source& source) {
deba@2335
    51
        source.clear();
deba@2335
    52
        for (typename Source::EdgeIt it(source); it != INVALID; ++it) {
deba@2335
    53
          target.addBack(it);
deba@2335
    54
        }
deba@2335
    55
      }
deba@2335
    56
    };
deba@2335
    57
deba@2335
    58
    template <typename Target, typename Source, typename BuildEnable>
deba@2335
    59
    struct PathCopySelector<
deba@2335
    60
      Target, Source, BuildEnable, 
deba@2335
    61
      typename enable_if<typename Source::RevPathTag, void>::type> {
deba@2335
    62
      static void copy(Target& target, const Source& source) {
deba@2335
    63
        source.clear();
deba@2335
    64
        for (typename Source::RevIt it(source); it != INVALID; ++it) {
deba@2335
    65
          target.addFront(it);
deba@2335
    66
        }
deba@2335
    67
      }
deba@2335
    68
    };
deba@2335
    69
deba@2335
    70
    template <typename Target, typename Source, typename RevEnable>
deba@2335
    71
    struct PathCopySelector<
deba@2335
    72
      Target, Source, 
deba@2335
    73
      typename enable_if<typename Target::BuildTag, void>::type, RevEnable> {
deba@2335
    74
      static void copy(Target& target, const Source& source) {
deba@2335
    75
        target.clear();
deba@2335
    76
        target.build(source);
deba@2335
    77
      }
deba@2335
    78
    };
deba@2335
    79
deba@2335
    80
    template <typename Target, typename Source>
deba@2335
    81
    struct PathCopySelector<
deba@2335
    82
      Target, Source, 
deba@2335
    83
      typename enable_if<typename Target::BuildTag, void>::type,
deba@2335
    84
      typename enable_if<typename Source::RevPathTag, void>::type> {
deba@2335
    85
      static void copy(Target& target, const Source& source) {
deba@2335
    86
        target.clear();
deba@2335
    87
        target.buildRev(source);
deba@2335
    88
      }
deba@2335
    89
    };
deba@2335
    90
deba@2335
    91
  }
deba@2335
    92
deba@2335
    93
deba@2335
    94
  /// \brief Make of copy of a path.
deba@2335
    95
  ///
deba@2335
    96
  ///  Make of copy of a path.
deba@2335
    97
  template <typename Target, typename Source>
deba@2335
    98
  void copyPath(Target& target, const Source& source) {
deba@2335
    99
    checkConcept<concepts::PathDumper<typename Source::Graph>, Source>();
deba@2335
   100
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
deba@2335
   101
  }
deba@2335
   102
deba@2335
   103
  /// \brief Checks the path's consistency.
deba@2335
   104
  ///
deba@2335
   105
  /// Checks that each edge's target is the next's source. 
deba@2335
   106
  /// \Checks the path's consistency.
deba@2335
   107
  ///
deba@2335
   108
  /// Checks that each edge's target is the next's source. 
deba@2335
   109
  template <typename Graph, typename Path>
deba@2335
   110
  bool checkPath(const Graph& graph, const Path& path) {
deba@2335
   111
    typename Path::EdgeIt it(path);
deba@2335
   112
    if (it == INVALID) return true;
deba@2335
   113
    typename Graph::Node node = graph.target(it);
deba@2335
   114
    ++it;
deba@2335
   115
    while (it != INVALID) {
deba@2335
   116
      if (graph.source(it) != node) return false;
deba@2335
   117
      node = graph.target(it);
deba@2335
   118
      ++it;
deba@2335
   119
    }
deba@2335
   120
    return true;
deba@2335
   121
  }
deba@2335
   122
deba@2335
   123
  /// \brief Gives back the source of the path
deba@2335
   124
  ///
deba@2335
   125
  /// Gives back the source of the path.
deba@2335
   126
  template <typename Graph, typename Path>
deba@2335
   127
  typename Graph::Node pathSource(const Graph& graph, const Path& path) {
deba@2335
   128
    return graph.source(path.front());
deba@2335
   129
  }
deba@2335
   130
deba@2335
   131
  /// \brief Gives back the target of the path
deba@2335
   132
  ///
deba@2335
   133
  /// Gives back the target of the path.
deba@2335
   134
  template <typename Graph, typename Path>
deba@2335
   135
  typename Graph::Node pathTarget(const Graph& graph, const Path& path) {
deba@2335
   136
    return graph.target(path.back());
deba@2335
   137
  }
deba@2335
   138
}
deba@2335
   139
deba@2335
   140
#endif