gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add tolerance() functions for MMC classes (#179)
0 4 0
default
4 files changed with 57 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -93,384 +93,402 @@
93 93
  /// \addtogroup min_mean_cycle
94 94
  /// @{
95 95

	
96 96
  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
97 97
  /// a minimum mean cycle.
98 98
  ///
99 99
  /// This class implements the Hartmann-Orlin algorithm for finding
100 100
  /// a directed cycle of minimum mean length (cost) in a digraph.
101 101
  /// It is an improved version of \ref Karp "Karp"'s original algorithm,
102 102
  /// it applies an efficient early termination scheme.
103 103
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
104 104
  ///
105 105
  /// \tparam GR The type of the digraph the algorithm runs on.
106 106
  /// \tparam LEN The type of the length map. The default
107 107
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
108 108
#ifdef DOXYGEN
109 109
  template <typename GR, typename LEN, typename TR>
110 110
#else
111 111
  template < typename GR,
112 112
             typename LEN = typename GR::template ArcMap<int>,
113 113
             typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
114 114
#endif
115 115
  class HartmannOrlin
116 116
  {
117 117
  public:
118 118

	
119 119
    /// The type of the digraph
120 120
    typedef typename TR::Digraph Digraph;
121 121
    /// The type of the length map
122 122
    typedef typename TR::LengthMap LengthMap;
123 123
    /// The type of the arc lengths
124 124
    typedef typename TR::Value Value;
125 125

	
126 126
    /// \brief The large value type
127 127
    ///
128 128
    /// The large value type used for internal computations.
129 129
    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
130 130
    /// it is \c long \c long if the \c Value type is integer,
131 131
    /// otherwise it is \c double.
132 132
    typedef typename TR::LargeValue LargeValue;
133 133

	
134 134
    /// The tolerance type
135 135
    typedef typename TR::Tolerance Tolerance;
136 136

	
137 137
    /// \brief The path type of the found cycles
138 138
    ///
139 139
    /// The path type of the found cycles.
140 140
    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
141 141
    /// it is \ref lemon::Path "Path<Digraph>".
142 142
    typedef typename TR::Path Path;
143 143

	
144 144
    /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
145 145
    typedef TR Traits;
146 146

	
147 147
  private:
148 148

	
149 149
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
150 150

	
151 151
    // Data sturcture for path data
152 152
    struct PathData
153 153
    {
154 154
      LargeValue dist;
155 155
      Arc pred;
156 156
      PathData(LargeValue d, Arc p = INVALID) :
157 157
        dist(d), pred(p) {}
158 158
    };
159 159

	
160 160
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
161 161
      PathDataNodeMap;
162 162

	
163 163
  private:
164 164

	
165 165
    // The digraph the algorithm runs on
166 166
    const Digraph &_gr;
167 167
    // The length of the arcs
168 168
    const LengthMap &_length;
169 169

	
170 170
    // Data for storing the strongly connected components
171 171
    int _comp_num;
172 172
    typename Digraph::template NodeMap<int> _comp;
173 173
    std::vector<std::vector<Node> > _comp_nodes;
174 174
    std::vector<Node>* _nodes;
175 175
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
176 176

	
177 177
    // Data for the found cycles
178 178
    bool _curr_found, _best_found;
179 179
    LargeValue _curr_length, _best_length;
180 180
    int _curr_size, _best_size;
181 181
    Node _curr_node, _best_node;
182 182
    int _curr_level, _best_level;
183 183

	
184 184
    Path *_cycle_path;
185 185
    bool _local_path;
186 186

	
187 187
    // Node map for storing path data
188 188
    PathDataNodeMap _data;
189 189
    // The processed nodes in the last round
190 190
    std::vector<Node> _process;
191 191

	
192 192
    Tolerance _tolerance;
193 193

	
194 194
    // Infinite constant
195 195
    const LargeValue INF;
196 196

	
197 197
  public:
198 198

	
199 199
    /// \name Named Template Parameters
200 200
    /// @{
201 201

	
202 202
    template <typename T>
203 203
    struct SetLargeValueTraits : public Traits {
204 204
      typedef T LargeValue;
205 205
      typedef lemon::Tolerance<T> Tolerance;
206 206
    };
207 207

	
208 208
    /// \brief \ref named-templ-param "Named parameter" for setting
209 209
    /// \c LargeValue type.
210 210
    ///
211 211
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
212 212
    /// type. It is used for internal computations in the algorithm.
213 213
    template <typename T>
214 214
    struct SetLargeValue
215 215
      : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
216 216
      typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
217 217
    };
218 218

	
219 219
    template <typename T>
220 220
    struct SetPathTraits : public Traits {
221 221
      typedef T Path;
222 222
    };
223 223

	
224 224
    /// \brief \ref named-templ-param "Named parameter" for setting
225 225
    /// \c %Path type.
226 226
    ///
227 227
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
228 228
    /// type of the found cycles.
229 229
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
230 230
    /// and it must have an \c addFront() function.
231 231
    template <typename T>
232 232
    struct SetPath
233 233
      : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
234 234
      typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
235 235
    };
236 236

	
237 237
    /// @}
238 238

	
239 239
  public:
240 240

	
241 241
    /// \brief Constructor.
242 242
    ///
243 243
    /// The constructor of the class.
244 244
    ///
245 245
    /// \param digraph The digraph the algorithm runs on.
246 246
    /// \param length The lengths (costs) of the arcs.
247 247
    HartmannOrlin( const Digraph &digraph,
248 248
                   const LengthMap &length ) :
249 249
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
250 250
      _best_found(false), _best_length(0), _best_size(1),
251 251
      _cycle_path(NULL), _local_path(false), _data(digraph),
252 252
      INF(std::numeric_limits<LargeValue>::has_infinity ?
253 253
          std::numeric_limits<LargeValue>::infinity() :
254 254
          std::numeric_limits<LargeValue>::max())
255 255
    {}
256 256

	
257 257
    /// Destructor.
258 258
    ~HartmannOrlin() {
259 259
      if (_local_path) delete _cycle_path;
260 260
    }
261 261

	
262 262
    /// \brief Set the path structure for storing the found cycle.
263 263
    ///
264 264
    /// This function sets an external path structure for storing the
265 265
    /// found cycle.
266 266
    ///
267 267
    /// If you don't call this function before calling \ref run() or
268 268
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
269 269
    /// structure. The destuctor deallocates this automatically
270 270
    /// allocated object, of course.
271 271
    ///
272 272
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
273 273
    /// "addFront()" function of the given path structure.
274 274
    ///
275 275
    /// \return <tt>(*this)</tt>
276 276
    HartmannOrlin& cycle(Path &path) {
277 277
      if (_local_path) {
278 278
        delete _cycle_path;
279 279
        _local_path = false;
280 280
      }
281 281
      _cycle_path = &path;
282 282
      return *this;
283 283
    }
284 284

	
285
    /// \brief Set the tolerance used by the algorithm.
286
    ///
287
    /// This function sets the tolerance object used by the algorithm.
288
    ///
289
    /// \return <tt>(*this)</tt>
290
    HartmannOrlin& tolerance(const Tolerance& tolerance) {
291
      _tolerance = tolerance;
292
      return *this;
293
    }
294

	
295
    /// \brief Return a const reference to the tolerance.
296
    ///
297
    /// This function returns a const reference to the tolerance object
298
    /// used by the algorithm.
299
    const Tolerance& tolerance() const {
300
      return _tolerance;
301
    }
302

	
285 303
    /// \name Execution control
286 304
    /// The simplest way to execute the algorithm is to call the \ref run()
287 305
    /// function.\n
288 306
    /// If you only need the minimum mean length, you may call
289 307
    /// \ref findMinMean().
290 308

	
291 309
    /// @{
292 310

	
293 311
    /// \brief Run the algorithm.
294 312
    ///
295 313
    /// This function runs the algorithm.
296 314
    /// It can be called more than once (e.g. if the underlying digraph
297 315
    /// and/or the arc lengths have been modified).
298 316
    ///
299 317
    /// \return \c true if a directed cycle exists in the digraph.
300 318
    ///
301 319
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
302 320
    /// \code
303 321
    ///   return mmc.findMinMean() && mmc.findCycle();
304 322
    /// \endcode
305 323
    bool run() {
306 324
      return findMinMean() && findCycle();
307 325
    }
308 326

	
309 327
    /// \brief Find the minimum cycle mean.
310 328
    ///
311 329
    /// This function finds the minimum mean length of the directed
312 330
    /// cycles in the digraph.
313 331
    ///
314 332
    /// \return \c true if a directed cycle exists in the digraph.
315 333
    bool findMinMean() {
316 334
      // Initialization and find strongly connected components
317 335
      init();
318 336
      findComponents();
319 337
      
320 338
      // Find the minimum cycle mean in the components
321 339
      for (int comp = 0; comp < _comp_num; ++comp) {
322 340
        if (!initComponent(comp)) continue;
323 341
        processRounds();
324 342
        
325 343
        // Update the best cycle (global minimum mean cycle)
326 344
        if ( _curr_found && (!_best_found || 
327 345
             _curr_length * _best_size < _best_length * _curr_size) ) {
328 346
          _best_found = true;
329 347
          _best_length = _curr_length;
330 348
          _best_size = _curr_size;
331 349
          _best_node = _curr_node;
332 350
          _best_level = _curr_level;
333 351
        }
334 352
      }
335 353
      return _best_found;
336 354
    }
337 355

	
338 356
    /// \brief Find a minimum mean directed cycle.
339 357
    ///
340 358
    /// This function finds a directed cycle of minimum mean length
341 359
    /// in the digraph using the data computed by findMinMean().
342 360
    ///
343 361
    /// \return \c true if a directed cycle exists in the digraph.
344 362
    ///
345 363
    /// \pre \ref findMinMean() must be called before using this function.
346 364
    bool findCycle() {
347 365
      if (!_best_found) return false;
348 366
      IntNodeMap reached(_gr, -1);
349 367
      int r = _best_level + 1;
350 368
      Node u = _best_node;
351 369
      while (reached[u] < 0) {
352 370
        reached[u] = --r;
353 371
        u = _gr.source(_data[u][r].pred);
354 372
      }
355 373
      r = reached[u];
356 374
      Arc e = _data[u][r].pred;
357 375
      _cycle_path->addFront(e);
358 376
      _best_length = _length[e];
359 377
      _best_size = 1;
360 378
      Node v;
361 379
      while ((v = _gr.source(e)) != u) {
362 380
        e = _data[v][--r].pred;
363 381
        _cycle_path->addFront(e);
364 382
        _best_length += _length[e];
365 383
        ++_best_size;
366 384
      }
367 385
      return true;
368 386
    }
369 387

	
370 388
    /// @}
371 389

	
372 390
    /// \name Query Functions
373 391
    /// The results of the algorithm can be obtained using these
374 392
    /// functions.\n
375 393
    /// The algorithm should be executed before using them.
376 394

	
377 395
    /// @{
378 396

	
379 397
    /// \brief Return the total length of the found cycle.
380 398
    ///
381 399
    /// This function returns the total length of the found cycle.
382 400
    ///
383 401
    /// \pre \ref run() or \ref findMinMean() must be called before
384 402
    /// using this function.
385 403
    LargeValue cycleLength() const {
386 404
      return _best_length;
387 405
    }
388 406

	
389 407
    /// \brief Return the number of arcs on the found cycle.
390 408
    ///
391 409
    /// This function returns the number of arcs on the found cycle.
392 410
    ///
393 411
    /// \pre \ref run() or \ref findMinMean() must be called before
394 412
    /// using this function.
395 413
    int cycleArcNum() const {
396 414
      return _best_size;
397 415
    }
398 416

	
399 417
    /// \brief Return the mean length of the found cycle.
400 418
    ///
401 419
    /// This function returns the mean length of the found cycle.
402 420
    ///
403 421
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
404 422
    /// following code.
405 423
    /// \code
406 424
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
407 425
    /// \endcode
408 426
    ///
409 427
    /// \pre \ref run() or \ref findMinMean() must be called before
410 428
    /// using this function.
411 429
    double cycleMean() const {
412 430
      return static_cast<double>(_best_length) / _best_size;
413 431
    }
414 432

	
415 433
    /// \brief Return the found cycle.
416 434
    ///
417 435
    /// This function returns a const reference to the path structure
418 436
    /// storing the found cycle.
419 437
    ///
420 438
    /// \pre \ref run() or \ref findCycle() must be called before using
421 439
    /// this function.
422 440
    const Path& cycle() const {
423 441
      return *_cycle_path;
424 442
    }
425 443

	
426 444
    ///@}
427 445

	
428 446
  private:
429 447

	
430 448
    // Initialization
431 449
    void init() {
432 450
      if (!_cycle_path) {
433 451
        _local_path = true;
434 452
        _cycle_path = new Path;
435 453
      }
436 454
      _cycle_path->clear();
437 455
      _best_found = false;
438 456
      _best_length = 0;
439 457
      _best_size = 1;
440 458
      _cycle_path->clear();
441 459
      for (NodeIt u(_gr); u != INVALID; ++u)
442 460
        _data[u].clear();
443 461
    }
444 462

	
445 463
    // Find strongly connected components and initialize _comp_nodes
446 464
    // and _out_arcs
447 465
    void findComponents() {
448 466
      _comp_num = stronglyConnectedComponents(_gr, _comp);
449 467
      _comp_nodes.resize(_comp_num);
450 468
      if (_comp_num == 1) {
451 469
        _comp_nodes[0].clear();
452 470
        for (NodeIt n(_gr); n != INVALID; ++n) {
453 471
          _comp_nodes[0].push_back(n);
454 472
          _out_arcs[n].clear();
455 473
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
456 474
            _out_arcs[n].push_back(a);
457 475
          }
458 476
        }
459 477
      } else {
460 478
        for (int i = 0; i < _comp_num; ++i)
461 479
          _comp_nodes[i].clear();
462 480
        for (NodeIt n(_gr); n != INVALID; ++n) {
463 481
          int k = _comp[n];
464 482
          _comp_nodes[k].push_back(n);
465 483
          _out_arcs[n].clear();
466 484
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
467 485
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
468 486
          }
469 487
        }
470 488
      }
471 489
    }
472 490

	
473 491
    // Initialize path data for the current component
474 492
    bool initComponent(int comp) {
475 493
      _nodes = &(_comp_nodes[comp]);
476 494
      int n = _nodes->size();
Ignore white space 6 line context
... ...
@@ -84,384 +84,402 @@
84 84
    typedef long long LargeValue;
85 85
#else
86 86
    typedef long LargeValue;
87 87
#endif
88 88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89 89
    typedef lemon::Path<Digraph> Path;
90 90
  };
91 91

	
92 92

	
93 93
  /// \addtogroup min_mean_cycle
94 94
  /// @{
95 95

	
96 96
  /// \brief Implementation of Howard's algorithm for finding a minimum
97 97
  /// mean cycle.
98 98
  ///
99 99
  /// This class implements Howard's policy iteration algorithm for finding
100 100
  /// a directed cycle of minimum mean length (cost) in a digraph.
101 101
  /// This class provides the most efficient algorithm for the
102 102
  /// minimum mean cycle problem, though the best known theoretical
103 103
  /// bound on its running time is exponential.
104 104
  ///
105 105
  /// \tparam GR The type of the digraph the algorithm runs on.
106 106
  /// \tparam LEN The type of the length map. The default
107 107
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
108 108
#ifdef DOXYGEN
109 109
  template <typename GR, typename LEN, typename TR>
110 110
#else
111 111
  template < typename GR,
112 112
             typename LEN = typename GR::template ArcMap<int>,
113 113
             typename TR = HowardDefaultTraits<GR, LEN> >
114 114
#endif
115 115
  class Howard
116 116
  {
117 117
  public:
118 118
  
119 119
    /// The type of the digraph
120 120
    typedef typename TR::Digraph Digraph;
121 121
    /// The type of the length map
122 122
    typedef typename TR::LengthMap LengthMap;
123 123
    /// The type of the arc lengths
124 124
    typedef typename TR::Value Value;
125 125

	
126 126
    /// \brief The large value type
127 127
    ///
128 128
    /// The large value type used for internal computations.
129 129
    /// Using the \ref HowardDefaultTraits "default traits class",
130 130
    /// it is \c long \c long if the \c Value type is integer,
131 131
    /// otherwise it is \c double.
132 132
    typedef typename TR::LargeValue LargeValue;
133 133

	
134 134
    /// The tolerance type
135 135
    typedef typename TR::Tolerance Tolerance;
136 136

	
137 137
    /// \brief The path type of the found cycles
138 138
    ///
139 139
    /// The path type of the found cycles.
140 140
    /// Using the \ref HowardDefaultTraits "default traits class",
141 141
    /// it is \ref lemon::Path "Path<Digraph>".
142 142
    typedef typename TR::Path Path;
143 143

	
144 144
    /// The \ref HowardDefaultTraits "traits class" of the algorithm
145 145
    typedef TR Traits;
146 146

	
147 147
  private:
148 148

	
149 149
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
150 150
  
151 151
    // The digraph the algorithm runs on
152 152
    const Digraph &_gr;
153 153
    // The length of the arcs
154 154
    const LengthMap &_length;
155 155

	
156 156
    // Data for the found cycles
157 157
    bool _curr_found, _best_found;
158 158
    LargeValue _curr_length, _best_length;
159 159
    int _curr_size, _best_size;
160 160
    Node _curr_node, _best_node;
161 161

	
162 162
    Path *_cycle_path;
163 163
    bool _local_path;
164 164

	
165 165
    // Internal data used by the algorithm
166 166
    typename Digraph::template NodeMap<Arc> _policy;
167 167
    typename Digraph::template NodeMap<bool> _reached;
168 168
    typename Digraph::template NodeMap<int> _level;
169 169
    typename Digraph::template NodeMap<LargeValue> _dist;
170 170

	
171 171
    // Data for storing the strongly connected components
172 172
    int _comp_num;
173 173
    typename Digraph::template NodeMap<int> _comp;
174 174
    std::vector<std::vector<Node> > _comp_nodes;
175 175
    std::vector<Node>* _nodes;
176 176
    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
177 177
    
178 178
    // Queue used for BFS search
179 179
    std::vector<Node> _queue;
180 180
    int _qfront, _qback;
181 181

	
182 182
    Tolerance _tolerance;
183 183
  
184 184
    // Infinite constant
185 185
    const LargeValue INF;
186 186

	
187 187
  public:
188 188
  
189 189
    /// \name Named Template Parameters
190 190
    /// @{
191 191

	
192 192
    template <typename T>
193 193
    struct SetLargeValueTraits : public Traits {
194 194
      typedef T LargeValue;
195 195
      typedef lemon::Tolerance<T> Tolerance;
196 196
    };
197 197

	
198 198
    /// \brief \ref named-templ-param "Named parameter" for setting
199 199
    /// \c LargeValue type.
200 200
    ///
201 201
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
202 202
    /// type. It is used for internal computations in the algorithm.
203 203
    template <typename T>
204 204
    struct SetLargeValue
205 205
      : public Howard<GR, LEN, SetLargeValueTraits<T> > {
206 206
      typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
207 207
    };
208 208

	
209 209
    template <typename T>
210 210
    struct SetPathTraits : public Traits {
211 211
      typedef T Path;
212 212
    };
213 213

	
214 214
    /// \brief \ref named-templ-param "Named parameter" for setting
215 215
    /// \c %Path type.
216 216
    ///
217 217
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
218 218
    /// type of the found cycles.
219 219
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
220 220
    /// and it must have an \c addBack() function.
221 221
    template <typename T>
222 222
    struct SetPath
223 223
      : public Howard<GR, LEN, SetPathTraits<T> > {
224 224
      typedef Howard<GR, LEN, SetPathTraits<T> > Create;
225 225
    };
226 226
    
227 227
    /// @}
228 228

	
229 229
  public:
230 230

	
231 231
    /// \brief Constructor.
232 232
    ///
233 233
    /// The constructor of the class.
234 234
    ///
235 235
    /// \param digraph The digraph the algorithm runs on.
236 236
    /// \param length The lengths (costs) of the arcs.
237 237
    Howard( const Digraph &digraph,
238 238
            const LengthMap &length ) :
239 239
      _gr(digraph), _length(length), _best_found(false),
240 240
      _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
241 241
      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
242 242
      _comp(digraph), _in_arcs(digraph),
243 243
      INF(std::numeric_limits<LargeValue>::has_infinity ?
244 244
          std::numeric_limits<LargeValue>::infinity() :
245 245
          std::numeric_limits<LargeValue>::max())
246 246
    {}
247 247

	
248 248
    /// Destructor.
249 249
    ~Howard() {
250 250
      if (_local_path) delete _cycle_path;
251 251
    }
252 252

	
253 253
    /// \brief Set the path structure for storing the found cycle.
254 254
    ///
255 255
    /// This function sets an external path structure for storing the
256 256
    /// found cycle.
257 257
    ///
258 258
    /// If you don't call this function before calling \ref run() or
259 259
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
260 260
    /// structure. The destuctor deallocates this automatically
261 261
    /// allocated object, of course.
262 262
    ///
263 263
    /// \note The algorithm calls only the \ref lemon::Path::addBack()
264 264
    /// "addBack()" function of the given path structure.
265 265
    ///
266 266
    /// \return <tt>(*this)</tt>
267 267
    Howard& cycle(Path &path) {
268 268
      if (_local_path) {
269 269
        delete _cycle_path;
270 270
        _local_path = false;
271 271
      }
272 272
      _cycle_path = &path;
273 273
      return *this;
274 274
    }
275 275

	
276
    /// \brief Set the tolerance used by the algorithm.
277
    ///
278
    /// This function sets the tolerance object used by the algorithm.
279
    ///
280
    /// \return <tt>(*this)</tt>
281
    Howard& tolerance(const Tolerance& tolerance) {
282
      _tolerance = tolerance;
283
      return *this;
284
    }
285

	
286
    /// \brief Return a const reference to the tolerance.
287
    ///
288
    /// This function returns a const reference to the tolerance object
289
    /// used by the algorithm.
290
    const Tolerance& tolerance() const {
291
      return _tolerance;
292
    }
293

	
276 294
    /// \name Execution control
277 295
    /// The simplest way to execute the algorithm is to call the \ref run()
278 296
    /// function.\n
279 297
    /// If you only need the minimum mean length, you may call
280 298
    /// \ref findMinMean().
281 299

	
282 300
    /// @{
283 301

	
284 302
    /// \brief Run the algorithm.
285 303
    ///
286 304
    /// This function runs the algorithm.
287 305
    /// It can be called more than once (e.g. if the underlying digraph
288 306
    /// and/or the arc lengths have been modified).
289 307
    ///
290 308
    /// \return \c true if a directed cycle exists in the digraph.
291 309
    ///
292 310
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
293 311
    /// \code
294 312
    ///   return mmc.findMinMean() && mmc.findCycle();
295 313
    /// \endcode
296 314
    bool run() {
297 315
      return findMinMean() && findCycle();
298 316
    }
299 317

	
300 318
    /// \brief Find the minimum cycle mean.
301 319
    ///
302 320
    /// This function finds the minimum mean length of the directed
303 321
    /// cycles in the digraph.
304 322
    ///
305 323
    /// \return \c true if a directed cycle exists in the digraph.
306 324
    bool findMinMean() {
307 325
      // Initialize and find strongly connected components
308 326
      init();
309 327
      findComponents();
310 328
      
311 329
      // Find the minimum cycle mean in the components
312 330
      for (int comp = 0; comp < _comp_num; ++comp) {
313 331
        // Find the minimum mean cycle in the current component
314 332
        if (!buildPolicyGraph(comp)) continue;
315 333
        while (true) {
316 334
          findPolicyCycle();
317 335
          if (!computeNodeDistances()) break;
318 336
        }
319 337
        // Update the best cycle (global minimum mean cycle)
320 338
        if ( _curr_found && (!_best_found ||
321 339
             _curr_length * _best_size < _best_length * _curr_size) ) {
322 340
          _best_found = true;
323 341
          _best_length = _curr_length;
324 342
          _best_size = _curr_size;
325 343
          _best_node = _curr_node;
326 344
        }
327 345
      }
328 346
      return _best_found;
329 347
    }
330 348

	
331 349
    /// \brief Find a minimum mean directed cycle.
332 350
    ///
333 351
    /// This function finds a directed cycle of minimum mean length
334 352
    /// in the digraph using the data computed by findMinMean().
335 353
    ///
336 354
    /// \return \c true if a directed cycle exists in the digraph.
337 355
    ///
338 356
    /// \pre \ref findMinMean() must be called before using this function.
339 357
    bool findCycle() {
340 358
      if (!_best_found) return false;
341 359
      _cycle_path->addBack(_policy[_best_node]);
342 360
      for ( Node v = _best_node;
343 361
            (v = _gr.target(_policy[v])) != _best_node; ) {
344 362
        _cycle_path->addBack(_policy[v]);
345 363
      }
346 364
      return true;
347 365
    }
348 366

	
349 367
    /// @}
350 368

	
351 369
    /// \name Query Functions
352 370
    /// The results of the algorithm can be obtained using these
353 371
    /// functions.\n
354 372
    /// The algorithm should be executed before using them.
355 373

	
356 374
    /// @{
357 375

	
358 376
    /// \brief Return the total length of the found cycle.
359 377
    ///
360 378
    /// This function returns the total length of the found cycle.
361 379
    ///
362 380
    /// \pre \ref run() or \ref findMinMean() must be called before
363 381
    /// using this function.
364 382
    LargeValue cycleLength() const {
365 383
      return _best_length;
366 384
    }
367 385

	
368 386
    /// \brief Return the number of arcs on the found cycle.
369 387
    ///
370 388
    /// This function returns the number of arcs on the found cycle.
371 389
    ///
372 390
    /// \pre \ref run() or \ref findMinMean() must be called before
373 391
    /// using this function.
374 392
    int cycleArcNum() const {
375 393
      return _best_size;
376 394
    }
377 395

	
378 396
    /// \brief Return the mean length of the found cycle.
379 397
    ///
380 398
    /// This function returns the mean length of the found cycle.
381 399
    ///
382 400
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
383 401
    /// following code.
384 402
    /// \code
385 403
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
386 404
    /// \endcode
387 405
    ///
388 406
    /// \pre \ref run() or \ref findMinMean() must be called before
389 407
    /// using this function.
390 408
    double cycleMean() const {
391 409
      return static_cast<double>(_best_length) / _best_size;
392 410
    }
393 411

	
394 412
    /// \brief Return the found cycle.
395 413
    ///
396 414
    /// This function returns a const reference to the path structure
397 415
    /// storing the found cycle.
398 416
    ///
399 417
    /// \pre \ref run() or \ref findCycle() must be called before using
400 418
    /// this function.
401 419
    const Path& cycle() const {
402 420
      return *_cycle_path;
403 421
    }
404 422

	
405 423
    ///@}
406 424

	
407 425
  private:
408 426

	
409 427
    // Initialize
410 428
    void init() {
411 429
      if (!_cycle_path) {
412 430
        _local_path = true;
413 431
        _cycle_path = new Path;
414 432
      }
415 433
      _queue.resize(countNodes(_gr));
416 434
      _best_found = false;
417 435
      _best_length = 0;
418 436
      _best_size = 1;
419 437
      _cycle_path->clear();
420 438
    }
421 439
    
422 440
    // Find strongly connected components and initialize _comp_nodes
423 441
    // and _in_arcs
424 442
    void findComponents() {
425 443
      _comp_num = stronglyConnectedComponents(_gr, _comp);
426 444
      _comp_nodes.resize(_comp_num);
427 445
      if (_comp_num == 1) {
428 446
        _comp_nodes[0].clear();
429 447
        for (NodeIt n(_gr); n != INVALID; ++n) {
430 448
          _comp_nodes[0].push_back(n);
431 449
          _in_arcs[n].clear();
432 450
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
433 451
            _in_arcs[n].push_back(a);
434 452
          }
435 453
        }
436 454
      } else {
437 455
        for (int i = 0; i < _comp_num; ++i)
438 456
          _comp_nodes[i].clear();
439 457
        for (NodeIt n(_gr); n != INVALID; ++n) {
440 458
          int k = _comp[n];
441 459
          _comp_nodes[k].push_back(n);
442 460
          _in_arcs[n].clear();
443 461
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
444 462
            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
445 463
          }
446 464
        }
447 465
      }
448 466
    }
449 467

	
450 468
    // Build the policy graph in the given strongly connected component
451 469
    // (the out-degree of every node is 1)
452 470
    bool buildPolicyGraph(int comp) {
453 471
      _nodes = &(_comp_nodes[comp]);
454 472
      if (_nodes->size() < 1 ||
455 473
          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
456 474
        return false;
457 475
      }
458 476
      for (int i = 0; i < int(_nodes->size()); ++i) {
459 477
        _dist[(*_nodes)[i]] = INF;
460 478
      }
461 479
      Node u, v;
462 480
      Arc e;
463 481
      for (int i = 0; i < int(_nodes->size()); ++i) {
464 482
        v = (*_nodes)[i];
465 483
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
466 484
          e = _in_arcs[v][j];
467 485
          u = _gr.source(e);
Ignore white space 6 line context
... ...
@@ -89,384 +89,402 @@
89 89
    typedef lemon::Path<Digraph> Path;
90 90
  };
91 91

	
92 92

	
93 93
  /// \addtogroup min_mean_cycle
94 94
  /// @{
95 95

	
96 96
  /// \brief Implementation of Karp's algorithm for finding a minimum
97 97
  /// mean cycle.
98 98
  ///
99 99
  /// This class implements Karp's algorithm for finding a directed
100 100
  /// cycle of minimum mean length (cost) in a digraph.
101 101
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
102 102
  ///
103 103
  /// \tparam GR The type of the digraph the algorithm runs on.
104 104
  /// \tparam LEN The type of the length map. The default
105 105
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
106 106
#ifdef DOXYGEN
107 107
  template <typename GR, typename LEN, typename TR>
108 108
#else
109 109
  template < typename GR,
110 110
             typename LEN = typename GR::template ArcMap<int>,
111 111
             typename TR = KarpDefaultTraits<GR, LEN> >
112 112
#endif
113 113
  class Karp
114 114
  {
115 115
  public:
116 116

	
117 117
    /// The type of the digraph
118 118
    typedef typename TR::Digraph Digraph;
119 119
    /// The type of the length map
120 120
    typedef typename TR::LengthMap LengthMap;
121 121
    /// The type of the arc lengths
122 122
    typedef typename TR::Value Value;
123 123

	
124 124
    /// \brief The large value type
125 125
    ///
126 126
    /// The large value type used for internal computations.
127 127
    /// Using the \ref KarpDefaultTraits "default traits class",
128 128
    /// it is \c long \c long if the \c Value type is integer,
129 129
    /// otherwise it is \c double.
130 130
    typedef typename TR::LargeValue LargeValue;
131 131

	
132 132
    /// The tolerance type
133 133
    typedef typename TR::Tolerance Tolerance;
134 134

	
135 135
    /// \brief The path type of the found cycles
136 136
    ///
137 137
    /// The path type of the found cycles.
138 138
    /// Using the \ref KarpDefaultTraits "default traits class",
139 139
    /// it is \ref lemon::Path "Path<Digraph>".
140 140
    typedef typename TR::Path Path;
141 141

	
142 142
    /// The \ref KarpDefaultTraits "traits class" of the algorithm
143 143
    typedef TR Traits;
144 144

	
145 145
  private:
146 146

	
147 147
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
148 148

	
149 149
    // Data sturcture for path data
150 150
    struct PathData
151 151
    {
152 152
      LargeValue dist;
153 153
      Arc pred;
154 154
      PathData(LargeValue d, Arc p = INVALID) :
155 155
        dist(d), pred(p) {}
156 156
    };
157 157

	
158 158
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
159 159
      PathDataNodeMap;
160 160

	
161 161
  private:
162 162

	
163 163
    // The digraph the algorithm runs on
164 164
    const Digraph &_gr;
165 165
    // The length of the arcs
166 166
    const LengthMap &_length;
167 167

	
168 168
    // Data for storing the strongly connected components
169 169
    int _comp_num;
170 170
    typename Digraph::template NodeMap<int> _comp;
171 171
    std::vector<std::vector<Node> > _comp_nodes;
172 172
    std::vector<Node>* _nodes;
173 173
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
174 174

	
175 175
    // Data for the found cycle
176 176
    LargeValue _cycle_length;
177 177
    int _cycle_size;
178 178
    Node _cycle_node;
179 179

	
180 180
    Path *_cycle_path;
181 181
    bool _local_path;
182 182

	
183 183
    // Node map for storing path data
184 184
    PathDataNodeMap _data;
185 185
    // The processed nodes in the last round
186 186
    std::vector<Node> _process;
187 187

	
188 188
    Tolerance _tolerance;
189 189
    
190 190
    // Infinite constant
191 191
    const LargeValue INF;
192 192

	
193 193
  public:
194 194

	
195 195
    /// \name Named Template Parameters
196 196
    /// @{
197 197

	
198 198
    template <typename T>
199 199
    struct SetLargeValueTraits : public Traits {
200 200
      typedef T LargeValue;
201 201
      typedef lemon::Tolerance<T> Tolerance;
202 202
    };
203 203

	
204 204
    /// \brief \ref named-templ-param "Named parameter" for setting
205 205
    /// \c LargeValue type.
206 206
    ///
207 207
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
208 208
    /// type. It is used for internal computations in the algorithm.
209 209
    template <typename T>
210 210
    struct SetLargeValue
211 211
      : public Karp<GR, LEN, SetLargeValueTraits<T> > {
212 212
      typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
213 213
    };
214 214

	
215 215
    template <typename T>
216 216
    struct SetPathTraits : public Traits {
217 217
      typedef T Path;
218 218
    };
219 219

	
220 220
    /// \brief \ref named-templ-param "Named parameter" for setting
221 221
    /// \c %Path type.
222 222
    ///
223 223
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
224 224
    /// type of the found cycles.
225 225
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
226 226
    /// and it must have an \c addFront() function.
227 227
    template <typename T>
228 228
    struct SetPath
229 229
      : public Karp<GR, LEN, SetPathTraits<T> > {
230 230
      typedef Karp<GR, LEN, SetPathTraits<T> > Create;
231 231
    };
232 232

	
233 233
    /// @}
234 234

	
235 235
  public:
236 236

	
237 237
    /// \brief Constructor.
238 238
    ///
239 239
    /// The constructor of the class.
240 240
    ///
241 241
    /// \param digraph The digraph the algorithm runs on.
242 242
    /// \param length The lengths (costs) of the arcs.
243 243
    Karp( const Digraph &digraph,
244 244
          const LengthMap &length ) :
245 245
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
246 246
      _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
247 247
      _cycle_path(NULL), _local_path(false), _data(digraph),
248 248
      INF(std::numeric_limits<LargeValue>::has_infinity ?
249 249
          std::numeric_limits<LargeValue>::infinity() :
250 250
          std::numeric_limits<LargeValue>::max())
251 251
    {}
252 252

	
253 253
    /// Destructor.
254 254
    ~Karp() {
255 255
      if (_local_path) delete _cycle_path;
256 256
    }
257 257

	
258 258
    /// \brief Set the path structure for storing the found cycle.
259 259
    ///
260 260
    /// This function sets an external path structure for storing the
261 261
    /// found cycle.
262 262
    ///
263 263
    /// If you don't call this function before calling \ref run() or
264 264
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
265 265
    /// structure. The destuctor deallocates this automatically
266 266
    /// allocated object, of course.
267 267
    ///
268 268
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
269 269
    /// "addFront()" function of the given path structure.
270 270
    ///
271 271
    /// \return <tt>(*this)</tt>
272 272
    Karp& cycle(Path &path) {
273 273
      if (_local_path) {
274 274
        delete _cycle_path;
275 275
        _local_path = false;
276 276
      }
277 277
      _cycle_path = &path;
278 278
      return *this;
279 279
    }
280 280

	
281
    /// \brief Set the tolerance used by the algorithm.
282
    ///
283
    /// This function sets the tolerance object used by the algorithm.
284
    ///
285
    /// \return <tt>(*this)</tt>
286
    Karp& tolerance(const Tolerance& tolerance) {
287
      _tolerance = tolerance;
288
      return *this;
289
    }
290

	
291
    /// \brief Return a const reference to the tolerance.
292
    ///
293
    /// This function returns a const reference to the tolerance object
294
    /// used by the algorithm.
295
    const Tolerance& tolerance() const {
296
      return _tolerance;
297
    }
298

	
281 299
    /// \name Execution control
282 300
    /// The simplest way to execute the algorithm is to call the \ref run()
283 301
    /// function.\n
284 302
    /// If you only need the minimum mean length, you may call
285 303
    /// \ref findMinMean().
286 304

	
287 305
    /// @{
288 306

	
289 307
    /// \brief Run the algorithm.
290 308
    ///
291 309
    /// This function runs the algorithm.
292 310
    /// It can be called more than once (e.g. if the underlying digraph
293 311
    /// and/or the arc lengths have been modified).
294 312
    ///
295 313
    /// \return \c true if a directed cycle exists in the digraph.
296 314
    ///
297 315
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
298 316
    /// \code
299 317
    ///   return mmc.findMinMean() && mmc.findCycle();
300 318
    /// \endcode
301 319
    bool run() {
302 320
      return findMinMean() && findCycle();
303 321
    }
304 322

	
305 323
    /// \brief Find the minimum cycle mean.
306 324
    ///
307 325
    /// This function finds the minimum mean length of the directed
308 326
    /// cycles in the digraph.
309 327
    ///
310 328
    /// \return \c true if a directed cycle exists in the digraph.
311 329
    bool findMinMean() {
312 330
      // Initialization and find strongly connected components
313 331
      init();
314 332
      findComponents();
315 333
      
316 334
      // Find the minimum cycle mean in the components
317 335
      for (int comp = 0; comp < _comp_num; ++comp) {
318 336
        if (!initComponent(comp)) continue;
319 337
        processRounds();
320 338
        updateMinMean();
321 339
      }
322 340
      return (_cycle_node != INVALID);
323 341
    }
324 342

	
325 343
    /// \brief Find a minimum mean directed cycle.
326 344
    ///
327 345
    /// This function finds a directed cycle of minimum mean length
328 346
    /// in the digraph using the data computed by findMinMean().
329 347
    ///
330 348
    /// \return \c true if a directed cycle exists in the digraph.
331 349
    ///
332 350
    /// \pre \ref findMinMean() must be called before using this function.
333 351
    bool findCycle() {
334 352
      if (_cycle_node == INVALID) return false;
335 353
      IntNodeMap reached(_gr, -1);
336 354
      int r = _data[_cycle_node].size();
337 355
      Node u = _cycle_node;
338 356
      while (reached[u] < 0) {
339 357
        reached[u] = --r;
340 358
        u = _gr.source(_data[u][r].pred);
341 359
      }
342 360
      r = reached[u];
343 361
      Arc e = _data[u][r].pred;
344 362
      _cycle_path->addFront(e);
345 363
      _cycle_length = _length[e];
346 364
      _cycle_size = 1;
347 365
      Node v;
348 366
      while ((v = _gr.source(e)) != u) {
349 367
        e = _data[v][--r].pred;
350 368
        _cycle_path->addFront(e);
351 369
        _cycle_length += _length[e];
352 370
        ++_cycle_size;
353 371
      }
354 372
      return true;
355 373
    }
356 374

	
357 375
    /// @}
358 376

	
359 377
    /// \name Query Functions
360 378
    /// The results of the algorithm can be obtained using these
361 379
    /// functions.\n
362 380
    /// The algorithm should be executed before using them.
363 381

	
364 382
    /// @{
365 383

	
366 384
    /// \brief Return the total length of the found cycle.
367 385
    ///
368 386
    /// This function returns the total length of the found cycle.
369 387
    ///
370 388
    /// \pre \ref run() or \ref findMinMean() must be called before
371 389
    /// using this function.
372 390
    LargeValue cycleLength() const {
373 391
      return _cycle_length;
374 392
    }
375 393

	
376 394
    /// \brief Return the number of arcs on the found cycle.
377 395
    ///
378 396
    /// This function returns the number of arcs on the found cycle.
379 397
    ///
380 398
    /// \pre \ref run() or \ref findMinMean() must be called before
381 399
    /// using this function.
382 400
    int cycleArcNum() const {
383 401
      return _cycle_size;
384 402
    }
385 403

	
386 404
    /// \brief Return the mean length of the found cycle.
387 405
    ///
388 406
    /// This function returns the mean length of the found cycle.
389 407
    ///
390 408
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
391 409
    /// following code.
392 410
    /// \code
393 411
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
394 412
    /// \endcode
395 413
    ///
396 414
    /// \pre \ref run() or \ref findMinMean() must be called before
397 415
    /// using this function.
398 416
    double cycleMean() const {
399 417
      return static_cast<double>(_cycle_length) / _cycle_size;
400 418
    }
401 419

	
402 420
    /// \brief Return the found cycle.
403 421
    ///
404 422
    /// This function returns a const reference to the path structure
405 423
    /// storing the found cycle.
406 424
    ///
407 425
    /// \pre \ref run() or \ref findCycle() must be called before using
408 426
    /// this function.
409 427
    const Path& cycle() const {
410 428
      return *_cycle_path;
411 429
    }
412 430

	
413 431
    ///@}
414 432

	
415 433
  private:
416 434

	
417 435
    // Initialization
418 436
    void init() {
419 437
      if (!_cycle_path) {
420 438
        _local_path = true;
421 439
        _cycle_path = new Path;
422 440
      }
423 441
      _cycle_path->clear();
424 442
      _cycle_length = 0;
425 443
      _cycle_size = 1;
426 444
      _cycle_node = INVALID;
427 445
      for (NodeIt u(_gr); u != INVALID; ++u)
428 446
        _data[u].clear();
429 447
    }
430 448

	
431 449
    // Find strongly connected components and initialize _comp_nodes
432 450
    // and _out_arcs
433 451
    void findComponents() {
434 452
      _comp_num = stronglyConnectedComponents(_gr, _comp);
435 453
      _comp_nodes.resize(_comp_num);
436 454
      if (_comp_num == 1) {
437 455
        _comp_nodes[0].clear();
438 456
        for (NodeIt n(_gr); n != INVALID; ++n) {
439 457
          _comp_nodes[0].push_back(n);
440 458
          _out_arcs[n].clear();
441 459
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
442 460
            _out_arcs[n].push_back(a);
443 461
          }
444 462
        }
445 463
      } else {
446 464
        for (int i = 0; i < _comp_num; ++i)
447 465
          _comp_nodes[i].clear();
448 466
        for (NodeIt n(_gr); n != INVALID; ++n) {
449 467
          int k = _comp[n];
450 468
          _comp_nodes[k].push_back(n);
451 469
          _out_arcs[n].clear();
452 470
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
453 471
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
454 472
          }
455 473
        }
456 474
      }
457 475
    }
458 476

	
459 477
    // Initialize path data for the current component
460 478
    bool initComponent(int comp) {
461 479
      _nodes = &(_comp_nodes[comp]);
462 480
      int n = _nodes->size();
463 481
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
464 482
        return false;
465 483
      }      
466 484
      for (int i = 0; i < n; ++i) {
467 485
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
468 486
      }
469 487
      return true;
470 488
    }
471 489

	
472 490
    // Process all rounds of computing path data for the current component.
Ignore white space 384 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
#include <sstream>
21 21

	
22 22
#include <lemon/smart_graph.h>
23 23
#include <lemon/lgf_reader.h>
24 24
#include <lemon/path.h>
25 25
#include <lemon/concepts/digraph.h>
26 26
#include <lemon/concept_check.h>
27 27

	
28 28
#include <lemon/karp.h>
29 29
#include <lemon/hartmann_orlin.h>
30 30
#include <lemon/howard.h>
31 31

	
32 32
#include "test_tools.h"
33 33

	
34 34
using namespace lemon;
35 35

	
36 36
char test_lgf[] =
37 37
  "@nodes\n"
38 38
  "label\n"
39 39
  "1\n"
40 40
  "2\n"
41 41
  "3\n"
42 42
  "4\n"
43 43
  "5\n"
44 44
  "6\n"
45 45
  "7\n"
46 46
  "@arcs\n"
47 47
  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
48 48
  "1 2    1    1    1    1   0  0  0  0\n"
49 49
  "2 4    5    5    5    5   1  0  0  0\n"
50 50
  "2 3    8    8    8    8   0  0  0  0\n"
51 51
  "3 2   -2    0    0    0   1  0  0  0\n"
52 52
  "3 4    4    4    4    4   0  0  0  0\n"
53 53
  "3 7   -4   -4   -4   -4   0  0  0  0\n"
54 54
  "4 1    2    2    2    2   0  0  0  0\n"
55 55
  "4 3    3    3    3    3   1  0  0  0\n"
56 56
  "4 4    3    3    0    0   0  0  1  0\n"
57 57
  "5 2    4    4    4    4   0  0  0  0\n"
58 58
  "5 6    3    3    3    3   0  1  0  0\n"
59 59
  "6 5    2    2    2    2   0  1  0  0\n"
60 60
  "6 4   -1   -1   -1   -1   0  0  0  0\n"
61 61
  "6 7    1    1    1    1   0  0  0  0\n"
62 62
  "7 7    4    4    4   -1   0  0  0  1\n";
63 63

	
64 64
                        
65 65
// Check the interface of an MMC algorithm
66 66
template <typename GR, typename Value>
67 67
struct MmcClassConcept
68 68
{
69 69
  template <typename MMC>
70 70
  struct Constraints {
71 71
    void constraints() {
72 72
      const Constraints& me = *this;
73 73

	
74 74
      typedef typename MMC
75 75
        ::template SetPath<ListPath<GR> >
76 76
        ::template SetLargeValue<Value>
77 77
        ::Create MmcAlg;
78 78
      MmcAlg mmc(me.g, me.length);
79 79
      const MmcAlg& const_mmc = mmc;
80 80
      
81
      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
82
      mmc.tolerance(tol);
83
      
81 84
      b = mmc.cycle(p).run();
82 85
      b = mmc.findMinMean();
83 86
      b = mmc.findCycle();
84 87

	
85 88
      v = const_mmc.cycleLength();
86 89
      i = const_mmc.cycleArcNum();
87 90
      d = const_mmc.cycleMean();
88 91
      p = const_mmc.cycle();
89 92
    }
90 93

	
91 94
    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
92 95
  
93 96
    GR g;
94 97
    LM length;
95 98
    ListPath<GR> p;
96 99
    Value v;
97 100
    int i;
98 101
    double d;
99 102
    bool b;
100 103
  };
101 104
};
102 105

	
103 106
// Perform a test with the given parameters
104 107
template <typename MMC>
105 108
void checkMmcAlg(const SmartDigraph& gr,
106 109
                 const SmartDigraph::ArcMap<int>& lm,
107 110
                 const SmartDigraph::ArcMap<int>& cm,
108 111
                 int length, int size) {
109 112
  MMC alg(gr, lm);
110 113
  alg.findMinMean();
111 114
  check(alg.cycleMean() == static_cast<double>(length) / size,
112 115
        "Wrong cycle mean");
113 116
  alg.findCycle();
114 117
  check(alg.cycleLength() == length && alg.cycleArcNum() == size,
115 118
        "Wrong path");
116 119
  SmartDigraph::ArcMap<int> cycle(gr, 0);
117 120
  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
118 121
    ++cycle[a];
119 122
  }
120 123
  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
121 124
    check(cm[a] == cycle[a], "Wrong path");
122 125
  }
123 126
}
124 127

	
125 128
// Class for comparing types
126 129
template <typename T1, typename T2>
127 130
struct IsSameType {
128 131
  static const int result = 0;
129 132
};
130 133

	
131 134
template <typename T>
132 135
struct IsSameType<T,T> {
133 136
  static const int result = 1;
134 137
};
135 138

	
136 139

	
137 140
int main() {
138 141
  #ifdef LEMON_HAVE_LONG_LONG
139 142
    typedef long long long_int;
140 143
  #else
141 144
    typedef long long_int;
142 145
  #endif
143 146

	
144 147
  // Check the interface
145 148
  {
146 149
    typedef concepts::Digraph GR;
147 150

	
148 151
    // Karp
149 152
    checkConcept< MmcClassConcept<GR, int>,
150 153
                  Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
151 154
    checkConcept< MmcClassConcept<GR, float>,
152 155
                  Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
153 156
    
154 157
    // HartmannOrlin
155 158
    checkConcept< MmcClassConcept<GR, int>,
156 159
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
157 160
    checkConcept< MmcClassConcept<GR, float>,
158 161
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
159 162
    
160 163
    // Howard
161 164
    checkConcept< MmcClassConcept<GR, int>,
162 165
                  Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
163 166
    checkConcept< MmcClassConcept<GR, float>,
164 167
                  Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
165 168

	
166 169
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
167 170
          long_int>::result == 0) check(false, "Wrong LargeValue type");
168 171
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
169 172
          double>::result == 0) check(false, "Wrong LargeValue type");
170 173
  }
171 174

	
172 175
  // Run various tests
173 176
  {
174 177
    typedef SmartDigraph GR;
175 178
    DIGRAPH_TYPEDEFS(GR);
176 179
    
177 180
    GR gr;
178 181
    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
179 182
    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
180 183
    
181 184
    std::istringstream input(test_lgf);
182 185
    digraphReader(gr, input).
183 186
      arcMap("len1", l1).
184 187
      arcMap("len2", l2).
185 188
      arcMap("len3", l3).
186 189
      arcMap("len4", l4).
187 190
      arcMap("c1", c1).
188 191
      arcMap("c2", c2).
189 192
      arcMap("c3", c3).
190 193
      arcMap("c4", c4).
191 194
      run();
192 195

	
193 196
    // Karp
194 197
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
195 198
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
196 199
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
197 200
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
198 201

	
199 202
    // HartmannOrlin
200 203
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
201 204
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
202 205
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
203 206
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
204 207

	
205 208
    // Howard
206 209
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
207 210
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
208 211
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
209 212
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
210 213
  }
211 214

	
212 215
  return 0;
213 216
}
0 comments (0 inline)