gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add traits class + named parameters to Suurballe (#323) The following types can be modified using named parameters: - FlowMap - PotentialMap - Path - Heap + HeapCrossRef
0 2 0
default
2 files changed with 146 insertions and 21 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -5,131 +5,172 @@
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_SUURBALLE_H
20 20
#define LEMON_SUURBALLE_H
21 21

	
22 22
///\ingroup shortest_path
23 23
///\file
24 24
///\brief An algorithm for finding arc-disjoint paths between two
25 25
/// nodes having minimum total length.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <lemon/bin_heap.h>
30 30
#include <lemon/path.h>
31 31
#include <lemon/list_graph.h>
32 32
#include <lemon/dijkstra.h>
33 33
#include <lemon/maps.h>
34 34

	
35 35
namespace lemon {
36 36

	
37
  /// \brief Default traits class of Suurballe algorithm.
38
  ///
39
  /// Default traits class of Suurballe algorithm.
40
  /// \tparam GR The digraph type the algorithm runs on.
41
  /// \tparam LEN The type of the length map.
42
  /// The default value is <tt>GR::ArcMap<int></tt>.
43
#ifdef DOXYGEN
44
  template <typename GR, typename LEN>
45
#else
46
  template < typename GR,
47
             typename LEN = typename GR::template ArcMap<int> >
48
#endif
49
  struct SuurballeDefaultTraits
50
  {
51
    /// The type of the digraph.
52
    typedef GR Digraph;
53
    /// The type of the length map.
54
    typedef LEN LengthMap;
55
    /// The type of the lengths.
56
    typedef typename LEN::Value Length;
57
    /// The type of the flow map.
58
    typedef typename GR::template ArcMap<int> FlowMap;
59
    /// The type of the potential map.
60
    typedef typename GR::template NodeMap<Length> PotentialMap;
61

	
62
    /// \brief The path type
63
    ///
64
    /// The type used for storing the found arc-disjoint paths.
65
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
66
    /// and it must have an \c addBack() function.
67
    typedef lemon::Path<Digraph> Path;
68
    
69
    /// The cross reference type used for the heap.
70
    typedef typename GR::template NodeMap<int> HeapCrossRef;
71

	
72
    /// \brief The heap type used for internal Dijkstra computations.
73
    ///
74
    /// The type of the heap used for internal Dijkstra computations.
75
    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept
76
    /// and its priority type must be \c Length.
77
    typedef BinHeap<Length, HeapCrossRef> Heap;
78
  };
79

	
37 80
  /// \addtogroup shortest_path
38 81
  /// @{
39 82

	
40 83
  /// \brief Algorithm for finding arc-disjoint paths between two nodes
41 84
  /// having minimum total length.
42 85
  ///
43 86
  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
44 87
  /// finding arc-disjoint paths having minimum total length (cost)
45 88
  /// from a given source node to a given target node in a digraph.
46 89
  ///
47 90
  /// Note that this problem is a special case of the \ref min_cost_flow
48 91
  /// "minimum cost flow problem". This implementation is actually an
49 92
  /// efficient specialized version of the \ref CapacityScaling
50 93
  /// "successive shortest path" algorithm directly for this problem.
51 94
  /// Therefore this class provides query functions for flow values and
52 95
  /// node potentials (the dual solution) just like the minimum cost flow
53 96
  /// algorithms.
54 97
  ///
55 98
  /// \tparam GR The digraph type the algorithm runs on.
56 99
  /// \tparam LEN The type of the length map.
57 100
  /// The default value is <tt>GR::ArcMap<int></tt>.
58 101
  ///
59 102
  /// \warning Length values should be \e non-negative.
60 103
  ///
61 104
  /// \note For finding \e node-disjoint paths, this algorithm can be used
62 105
  /// along with the \ref SplitNodes adaptor.
63 106
#ifdef DOXYGEN
64
  template <typename GR, typename LEN>
107
  template <typename GR, typename LEN, typename TR>
65 108
#else
66 109
  template < typename GR,
67
             typename LEN = typename GR::template ArcMap<int> >
110
             typename LEN = typename GR::template ArcMap<int>,
111
             typename TR = SuurballeDefaultTraits<GR, LEN> >
68 112
#endif
69 113
  class Suurballe
70 114
  {
71 115
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
72 116

	
73 117
    typedef ConstMap<Arc, int> ConstArcMap;
74 118
    typedef typename GR::template NodeMap<Arc> PredMap;
75 119

	
76 120
  public:
77 121

	
78
    /// The type of the digraph the algorithm runs on.
79
    typedef GR Digraph;
122
    /// The type of the digraph.
123
    typedef typename TR::Digraph Digraph;
80 124
    /// The type of the length map.
81
    typedef LEN LengthMap;
125
    typedef typename TR::LengthMap LengthMap;
82 126
    /// The type of the lengths.
83
    typedef typename LengthMap::Value Length;
84
#ifdef DOXYGEN
127
    typedef typename TR::Length Length;
128

	
85 129
    /// The type of the flow map.
86
    typedef GR::ArcMap<int> FlowMap;
130
    typedef typename TR::FlowMap FlowMap;
87 131
    /// The type of the potential map.
88
    typedef GR::NodeMap<Length> PotentialMap;
89
#else
90
    /// The type of the flow map.
91
    typedef typename Digraph::template ArcMap<int> FlowMap;
92
    /// The type of the potential map.
93
    typedef typename Digraph::template NodeMap<Length> PotentialMap;
94
#endif
132
    typedef typename TR::PotentialMap PotentialMap;
133
    /// The type of the path structures.
134
    typedef typename TR::Path Path;
135
    /// The cross reference type used for the heap.
136
    typedef typename TR::HeapCrossRef HeapCrossRef;
137
    /// The heap type used for internal Dijkstra computations.
138
    typedef typename TR::Heap Heap;
95 139

	
96
    /// The type of the path structures.
97
    typedef SimplePath<GR> Path;
140
    /// The \ref SuurballeDefaultTraits "traits class" of the algorithm.
141
    typedef TR Traits;
98 142

	
99 143
  private:
100 144

	
101
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
102
    typedef BinHeap<Length, HeapCrossRef> Heap;
103

	
104 145
    // ResidualDijkstra is a special implementation of the
105 146
    // Dijkstra algorithm for finding shortest paths in the
106 147
    // residual network with respect to the reduced arc lengths
107 148
    // and modifying the node potentials according to the
108 149
    // distance of the nodes.
109 150
    class ResidualDijkstra
110 151
    {
111 152
    private:
112 153

	
113 154
      const Digraph &_graph;
114 155
      const LengthMap &_length;
115 156
      const FlowMap &_flow;
116 157
      PotentialMap &_pi;
117 158
      PredMap &_pred;
118 159
      Node _s;
119 160
      Node _t;
120 161
      
121 162
      PotentialMap _dist;
122 163
      std::vector<Node> _proc_nodes;
123 164

	
124 165
    public:
125 166

	
126 167
      // Constructor
127 168
      ResidualDijkstra(Suurballe &srb) :
128 169
        _graph(srb._graph), _length(srb._length),
129 170
        _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred), 
130 171
        _s(srb._s), _t(srb._t), _dist(_graph) {}
131 172
        
132 173
      // Run the algorithm and return true if a path is found
133 174
      // from the source node to the target node.
134 175
      bool run(int cnt) {
135 176
        return cnt == 0 ? startFirst() : start();
... ...
@@ -225,64 +266,141 @@
225 266
          for (InArcIt e(_graph, u); e != INVALID; ++e) {
226 267
            if (_flow[e] == 1) {
227 268
              v = _graph.source(e);
228 269
              switch(heap.state(v)) {
229 270
                case Heap::PRE_HEAP:
230 271
                  heap.push(v, d - _length[e] - _pi[v]);
231 272
                  _pred[v] = e;
232 273
                  break;
233 274
                case Heap::IN_HEAP:
234 275
                  dn = d - _length[e] - _pi[v];
235 276
                  if (dn < heap[v]) {
236 277
                    heap.decrease(v, dn);
237 278
                    _pred[v] = e;
238 279
                  }
239 280
                  break;
240 281
                case Heap::POST_HEAP:
241 282
                  break;
242 283
              }
243 284
            }
244 285
          }
245 286
        }
246 287
        if (heap.empty()) return false;
247 288

	
248 289
        // Update potentials of processed nodes
249 290
        Length t_dist = heap.prio();
250 291
        for (int i = 0; i < int(_proc_nodes.size()); ++i)
251 292
          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
252 293
        return true;
253 294
      }
254 295

	
255 296
    }; //class ResidualDijkstra
256 297

	
298
  public:
299

	
300
    /// \name Named Template Parameters
301
    /// @{
302

	
303
    template <typename T>
304
    struct SetFlowMapTraits : public Traits {
305
      typedef T FlowMap;
306
    };
307

	
308
    /// \brief \ref named-templ-param "Named parameter" for setting
309
    /// \c FlowMap type.
310
    ///
311
    /// \ref named-templ-param "Named parameter" for setting
312
    /// \c FlowMap type.
313
    template <typename T>
314
    struct SetFlowMap
315
      : public Suurballe<GR, LEN, SetFlowMapTraits<T> > {
316
      typedef Suurballe<GR, LEN, SetFlowMapTraits<T> > Create;
317
    };
318

	
319
    template <typename T>
320
    struct SetPotentialMapTraits : public Traits {
321
      typedef T PotentialMap;
322
    };
323

	
324
    /// \brief \ref named-templ-param "Named parameter" for setting
325
    /// \c PotentialMap type.
326
    ///
327
    /// \ref named-templ-param "Named parameter" for setting
328
    /// \c PotentialMap type.
329
    template <typename T>
330
    struct SetPotentialMap
331
      : public Suurballe<GR, LEN, SetPotentialMapTraits<T> > {
332
      typedef Suurballe<GR, LEN, SetPotentialMapTraits<T> > Create;
333
    };
334

	
335
    template <typename T>
336
    struct SetPathTraits : public Traits {
337
      typedef T Path;
338
    };
339

	
340
    /// \brief \ref named-templ-param "Named parameter" for setting
341
    /// \c %Path type.
342
    ///
343
    /// \ref named-templ-param "Named parameter" for setting \c %Path type.
344
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
345
    /// and it must have an \c addBack() function.
346
    template <typename T>
347
    struct SetPath
348
      : public Suurballe<GR, LEN, SetPathTraits<T> > {
349
      typedef Suurballe<GR, LEN, SetPathTraits<T> > Create;
350
    };
351
    
352
    template <typename H, typename CR>
353
    struct SetHeapTraits : public Traits {
354
      typedef H Heap;
355
      typedef CR HeapCrossRef;
356
    };
357

	
358
    /// \brief \ref named-templ-param "Named parameter" for setting
359
    /// \c Heap and \c HeapCrossRef types.
360
    ///
361
    /// \ref named-templ-param "Named parameter" for setting \c Heap
362
    /// and \c HeapCrossRef types with automatic allocation. 
363
    /// They will be used for internal Dijkstra computations.
364
    /// The heap type must conform to the \ref lemon::concepts::Heap "Heap"
365
    /// concept and its priority type must be \c Length.
366
    template <typename H,
367
              typename CR = typename Digraph::template NodeMap<int> >
368
    struct SetHeap
369
      : public Suurballe<GR, LEN, SetHeapTraits<H, CR> > {
370
      typedef Suurballe<GR, LEN, SetHeapTraits<H, CR> > Create;
371
    };
372

	
373
    /// @}
374

	
257 375
  private:
258 376

	
259 377
    // The digraph the algorithm runs on
260 378
    const Digraph &_graph;
261 379
    // The length map
262 380
    const LengthMap &_length;
263 381

	
264 382
    // Arc map of the current flow
265 383
    FlowMap *_flow;
266 384
    bool _local_flow;
267 385
    // Node map of the current potentials
268 386
    PotentialMap *_potential;
269 387
    bool _local_potential;
270 388

	
271 389
    // The source node
272 390
    Node _s;
273 391
    // The target node
274 392
    Node _t;
275 393

	
276 394
    // Container to store the found paths
277 395
    std::vector<Path> _paths;
278 396
    int _path_num;
279 397

	
280 398
    // The pred arc map
281 399
    PredMap _pred;
282 400
    
283 401
    // Data for full init
284 402
    PotentialMap *_init_dist;
285 403
    PredMap *_init_pred;
286 404
    bool _full_init;
287 405

	
288 406
  public:
Ignore white space 64 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20

	
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/path.h>
24 24
#include <lemon/suurballe.h>
25 25
#include <lemon/concepts/digraph.h>
26
#include <lemon/concepts/heap.h>
26 27

	
27 28
#include "test_tools.h"
28 29

	
29 30
using namespace lemon;
30 31

	
31 32
char test_lgf[] =
32 33
  "@nodes\n"
33 34
  "label\n"
34 35
  "1\n"
35 36
  "2\n"
36 37
  "3\n"
37 38
  "4\n"
38 39
  "5\n"
39 40
  "6\n"
40 41
  "7\n"
41 42
  "8\n"
42 43
  "9\n"
43 44
  "10\n"
44 45
  "11\n"
45 46
  "12\n"
46 47
  "@arcs\n"
47 48
  "      length\n"
48 49
  " 1  2  70\n"
49 50
  " 1  3 150\n"
50 51
  " 1  4  80\n"
51 52
  " 2  8  80\n"
52 53
  " 3  5 140\n"
53 54
  " 4  6  60\n"
54 55
  " 4  7  80\n"
55 56
  " 4  8 110\n"
56 57
  " 5  7  60\n"
57 58
  " 5 11 120\n"
58 59
  " 6  3   0\n"
59 60
  " 6  9 140\n"
60 61
  " 6 10  90\n"
61 62
  " 7  1  30\n"
62 63
  " 8 12  60\n"
63 64
  " 9 12  50\n"
64 65
  "10 12  70\n"
65 66
  "10  2 100\n"
66 67
  "10  7  60\n"
67 68
  "11 10  20\n"
68 69
  "12 11  30\n"
69 70
  "@attributes\n"
70 71
  "source  1\n"
71 72
  "target 12\n"
72 73
  "@end\n";
73 74

	
74 75
// Check the interface of Suurballe
75 76
void checkSuurballeCompile()
76 77
{
77 78
  typedef int VType;
78 79
  typedef concepts::Digraph Digraph;
79 80

	
80 81
  typedef Digraph::Node Node;
81 82
  typedef Digraph::Arc Arc;
82 83
  typedef concepts::ReadMap<Arc, VType> LengthMap;
83 84
  
84
  typedef Suurballe<Digraph, LengthMap> SuurballeType;
85
  typedef Suurballe<Digraph, LengthMap> ST;
86
  typedef Suurballe<Digraph, LengthMap>
87
    ::SetFlowMap<ST::FlowMap>
88
    ::SetPotentialMap<ST::PotentialMap>
89
    ::SetPath<SimplePath<Digraph> >
90
    ::SetHeap<concepts::Heap<VType, Digraph::NodeMap<int> > >
91
    ::Create SuurballeType;
85 92

	
86 93
  Digraph g;
87 94
  Node n;
88 95
  Arc e;
89 96
  LengthMap len;
90 97
  SuurballeType::FlowMap flow(g);
91 98
  SuurballeType::PotentialMap pi(g);
92 99

	
93 100
  SuurballeType suurb_test(g, len);
94 101
  const SuurballeType& const_suurb_test = suurb_test;
95 102

	
96 103
  suurb_test
97 104
    .flowMap(flow)
98 105
    .potentialMap(pi);
99 106

	
100 107
  int k;
101 108
  k = suurb_test.run(n, n);
102 109
  k = suurb_test.run(n, n, k);
103 110
  suurb_test.init(n);
104 111
  suurb_test.fullInit(n);
105 112
  suurb_test.start(n);
106 113
  suurb_test.start(n, k);
107 114
  k = suurb_test.findFlow(n);
108 115
  k = suurb_test.findFlow(n, k);
109 116
  suurb_test.findPaths();
110 117
  
111 118
  int f;
112 119
  VType c;
113 120
  c = const_suurb_test.totalLength();
114 121
  f = const_suurb_test.flow(e);
115 122
  const SuurballeType::FlowMap& fm =
116 123
    const_suurb_test.flowMap();
0 comments (0 inline)