test/min_mean_cycle_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 872 fa6f37d7a25b
parent 813 97744b6dabf8
child 942 d3ea191c3412
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
kpeter@810
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
kpeter@810
     2
 *
kpeter@810
     3
 * This file is a part of LEMON, a generic C++ optimization library.
kpeter@810
     4
 *
kpeter@810
     5
 * Copyright (C) 2003-2009
kpeter@810
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@810
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@810
     8
 *
kpeter@810
     9
 * Permission to use, modify and distribute this software is granted
kpeter@810
    10
 * provided that this copyright notice appears in all copies. For
kpeter@810
    11
 * precise terms see the accompanying LICENSE file.
kpeter@810
    12
 *
kpeter@810
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@810
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@810
    15
 * purpose.
kpeter@810
    16
 *
kpeter@810
    17
 */
kpeter@810
    18
kpeter@810
    19
#include <iostream>
kpeter@810
    20
#include <sstream>
kpeter@810
    21
kpeter@810
    22
#include <lemon/smart_graph.h>
kpeter@810
    23
#include <lemon/lgf_reader.h>
kpeter@810
    24
#include <lemon/path.h>
kpeter@810
    25
#include <lemon/concepts/digraph.h>
kpeter@810
    26
#include <lemon/concept_check.h>
kpeter@810
    27
kpeter@812
    28
#include <lemon/karp.h>
kpeter@813
    29
#include <lemon/hartmann_orlin.h>
kpeter@812
    30
#include <lemon/howard.h>
kpeter@812
    31
kpeter@810
    32
#include "test_tools.h"
kpeter@810
    33
kpeter@810
    34
using namespace lemon;
kpeter@810
    35
kpeter@810
    36
char test_lgf[] =
kpeter@810
    37
  "@nodes\n"
kpeter@810
    38
  "label\n"
kpeter@810
    39
  "1\n"
kpeter@810
    40
  "2\n"
kpeter@810
    41
  "3\n"
kpeter@810
    42
  "4\n"
kpeter@810
    43
  "5\n"
kpeter@810
    44
  "6\n"
kpeter@810
    45
  "7\n"
kpeter@810
    46
  "@arcs\n"
kpeter@810
    47
  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
kpeter@810
    48
  "1 2    1    1    1    1   0  0  0  0\n"
kpeter@810
    49
  "2 4    5    5    5    5   1  0  0  0\n"
kpeter@810
    50
  "2 3    8    8    8    8   0  0  0  0\n"
kpeter@810
    51
  "3 2   -2    0    0    0   1  0  0  0\n"
kpeter@810
    52
  "3 4    4    4    4    4   0  0  0  0\n"
kpeter@810
    53
  "3 7   -4   -4   -4   -4   0  0  0  0\n"
kpeter@810
    54
  "4 1    2    2    2    2   0  0  0  0\n"
kpeter@810
    55
  "4 3    3    3    3    3   1  0  0  0\n"
kpeter@810
    56
  "4 4    3    3    0    0   0  0  1  0\n"
kpeter@810
    57
  "5 2    4    4    4    4   0  0  0  0\n"
kpeter@810
    58
  "5 6    3    3    3    3   0  1  0  0\n"
kpeter@810
    59
  "6 5    2    2    2    2   0  1  0  0\n"
kpeter@810
    60
  "6 4   -1   -1   -1   -1   0  0  0  0\n"
kpeter@810
    61
  "6 7    1    1    1    1   0  0  0  0\n"
kpeter@810
    62
  "7 7    4    4    4   -1   0  0  0  1\n";
kpeter@810
    63
kpeter@810
    64
                        
kpeter@810
    65
// Check the interface of an MMC algorithm
kpeter@810
    66
template <typename GR, typename Value>
kpeter@810
    67
struct MmcClassConcept
kpeter@810
    68
{
kpeter@810
    69
  template <typename MMC>
kpeter@810
    70
  struct Constraints {
kpeter@810
    71
    void constraints() {
kpeter@810
    72
      const Constraints& me = *this;
kpeter@810
    73
kpeter@810
    74
      typedef typename MMC
kpeter@810
    75
        ::template SetPath<ListPath<GR> >
kpeter@810
    76
        ::template SetLargeValue<Value>
kpeter@810
    77
        ::Create MmcAlg;
kpeter@810
    78
      MmcAlg mmc(me.g, me.length);
kpeter@810
    79
      const MmcAlg& const_mmc = mmc;
kpeter@810
    80
      
kpeter@816
    81
      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
kpeter@816
    82
      mmc.tolerance(tol);
kpeter@816
    83
      
kpeter@810
    84
      b = mmc.cycle(p).run();
kpeter@810
    85
      b = mmc.findMinMean();
kpeter@810
    86
      b = mmc.findCycle();
kpeter@810
    87
kpeter@810
    88
      v = const_mmc.cycleLength();
kpeter@810
    89
      i = const_mmc.cycleArcNum();
kpeter@810
    90
      d = const_mmc.cycleMean();
kpeter@810
    91
      p = const_mmc.cycle();
kpeter@810
    92
    }
kpeter@810
    93
kpeter@810
    94
    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
kpeter@810
    95
  
kpeter@810
    96
    GR g;
kpeter@810
    97
    LM length;
kpeter@810
    98
    ListPath<GR> p;
kpeter@810
    99
    Value v;
kpeter@810
   100
    int i;
kpeter@810
   101
    double d;
kpeter@810
   102
    bool b;
kpeter@810
   103
  };
kpeter@810
   104
};
kpeter@810
   105
kpeter@810
   106
// Perform a test with the given parameters
kpeter@810
   107
template <typename MMC>
kpeter@810
   108
void checkMmcAlg(const SmartDigraph& gr,
kpeter@810
   109
                 const SmartDigraph::ArcMap<int>& lm,
kpeter@810
   110
                 const SmartDigraph::ArcMap<int>& cm,
kpeter@810
   111
                 int length, int size) {
kpeter@810
   112
  MMC alg(gr, lm);
kpeter@810
   113
  alg.findMinMean();
kpeter@810
   114
  check(alg.cycleMean() == static_cast<double>(length) / size,
kpeter@810
   115
        "Wrong cycle mean");
kpeter@810
   116
  alg.findCycle();
kpeter@810
   117
  check(alg.cycleLength() == length && alg.cycleArcNum() == size,
kpeter@810
   118
        "Wrong path");
kpeter@810
   119
  SmartDigraph::ArcMap<int> cycle(gr, 0);
kpeter@810
   120
  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
kpeter@810
   121
    ++cycle[a];
kpeter@810
   122
  }
kpeter@810
   123
  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
kpeter@810
   124
    check(cm[a] == cycle[a], "Wrong path");
kpeter@810
   125
  }
kpeter@810
   126
}
kpeter@810
   127
kpeter@810
   128
// Class for comparing types
kpeter@810
   129
template <typename T1, typename T2>
kpeter@810
   130
struct IsSameType {
kpeter@810
   131
  static const int result = 0;
kpeter@810
   132
};
kpeter@810
   133
kpeter@810
   134
template <typename T>
kpeter@810
   135
struct IsSameType<T,T> {
kpeter@810
   136
  static const int result = 1;
kpeter@810
   137
};
kpeter@810
   138
kpeter@810
   139
kpeter@810
   140
int main() {
kpeter@810
   141
  #ifdef LEMON_HAVE_LONG_LONG
kpeter@810
   142
    typedef long long long_int;
kpeter@810
   143
  #else
kpeter@810
   144
    typedef long long_int;
kpeter@810
   145
  #endif
kpeter@810
   146
kpeter@810
   147
  // Check the interface
kpeter@810
   148
  {
kpeter@810
   149
    typedef concepts::Digraph GR;
kpeter@812
   150
kpeter@812
   151
    // Karp
kpeter@812
   152
    checkConcept< MmcClassConcept<GR, int>,
kpeter@812
   153
                  Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
kpeter@812
   154
    checkConcept< MmcClassConcept<GR, float>,
kpeter@812
   155
                  Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
kpeter@810
   156
    
kpeter@813
   157
    // HartmannOrlin
kpeter@813
   158
    checkConcept< MmcClassConcept<GR, int>,
kpeter@813
   159
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
kpeter@813
   160
    checkConcept< MmcClassConcept<GR, float>,
kpeter@813
   161
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
kpeter@813
   162
    
kpeter@812
   163
    // Howard
kpeter@812
   164
    checkConcept< MmcClassConcept<GR, int>,
kpeter@812
   165
                  Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
kpeter@812
   166
    checkConcept< MmcClassConcept<GR, float>,
kpeter@812
   167
                  Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
kpeter@812
   168
kpeter@812
   169
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
kpeter@812
   170
          long_int>::result == 0) check(false, "Wrong LargeValue type");
kpeter@812
   171
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
kpeter@812
   172
          double>::result == 0) check(false, "Wrong LargeValue type");
kpeter@810
   173
  }
kpeter@810
   174
kpeter@810
   175
  // Run various tests
kpeter@810
   176
  {
kpeter@810
   177
    typedef SmartDigraph GR;
kpeter@810
   178
    DIGRAPH_TYPEDEFS(GR);
kpeter@810
   179
    
kpeter@810
   180
    GR gr;
kpeter@810
   181
    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
kpeter@810
   182
    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
kpeter@810
   183
    
kpeter@810
   184
    std::istringstream input(test_lgf);
kpeter@810
   185
    digraphReader(gr, input).
kpeter@810
   186
      arcMap("len1", l1).
kpeter@810
   187
      arcMap("len2", l2).
kpeter@810
   188
      arcMap("len3", l3).
kpeter@810
   189
      arcMap("len4", l4).
kpeter@810
   190
      arcMap("c1", c1).
kpeter@810
   191
      arcMap("c2", c2).
kpeter@810
   192
      arcMap("c3", c3).
kpeter@810
   193
      arcMap("c4", c4).
kpeter@810
   194
      run();
kpeter@810
   195
kpeter@812
   196
    // Karp
kpeter@812
   197
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
kpeter@812
   198
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
kpeter@812
   199
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
kpeter@812
   200
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
kpeter@812
   201
kpeter@813
   202
    // HartmannOrlin
kpeter@813
   203
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
kpeter@813
   204
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
kpeter@813
   205
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
kpeter@813
   206
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
kpeter@813
   207
kpeter@812
   208
    // Howard
kpeter@811
   209
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
kpeter@811
   210
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
kpeter@811
   211
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
kpeter@811
   212
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
kpeter@810
   213
  }
kpeter@810
   214
kpeter@810
   215
  return 0;
kpeter@810
   216
}