test/min_mean_cycle_test.cc
author Alpar Juttner <alpar@cs.elte.hu>
Fri, 23 Mar 2018 16:09:27 +0100
branch1.3
changeset 1391 411819b8702c
parent 1178 21a9f829ab68
permissions -rw-r--r--
Merge bugfix #608 to branch 1.3
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
 *
alpar@1270
     5
 * Copyright (C) 2003-2013
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@942
    28
#include <lemon/karp_mmc.h>
kpeter@942
    29
#include <lemon/hartmann_orlin_mmc.h>
kpeter@942
    30
#include <lemon/howard_mmc.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
alpar@956
    64
kpeter@810
    65
// Check the interface of an MMC algorithm
kpeter@942
    66
template <typename GR, typename Cost>
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@942
    76
        ::template SetLargeCost<Cost>
kpeter@810
    77
        ::Create MmcAlg;
kpeter@942
    78
      MmcAlg mmc(me.g, me.cost);
kpeter@810
    79
      const MmcAlg& const_mmc = mmc;
alpar@956
    80
kpeter@816
    81
      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
kpeter@816
    82
      mmc.tolerance(tol);
alpar@956
    83
kpeter@810
    84
      b = mmc.cycle(p).run();
kpeter@942
    85
      b = mmc.findCycleMean();
kpeter@810
    86
      b = mmc.findCycle();
kpeter@810
    87
kpeter@942
    88
      v = const_mmc.cycleCost();
kpeter@942
    89
      i = const_mmc.cycleSize();
kpeter@810
    90
      d = const_mmc.cycleMean();
kpeter@810
    91
      p = const_mmc.cycle();
kpeter@810
    92
    }
kpeter@810
    93
kpeter@942
    94
    typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
alpar@956
    95
kpeter@810
    96
    GR g;
kpeter@942
    97
    CM cost;
kpeter@810
    98
    ListPath<GR> p;
kpeter@942
    99
    Cost 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@942
   111
                 int cost, int size) {
kpeter@810
   112
  MMC alg(gr, lm);
kpeter@1178
   113
  check(alg.findCycleMean(), "Wrong result");
kpeter@942
   114
  check(alg.cycleMean() == static_cast<double>(cost) / size,
kpeter@810
   115
        "Wrong cycle mean");
kpeter@810
   116
  alg.findCycle();
kpeter@942
   117
  check(alg.cycleCost() == cost && alg.cycleSize() == 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@942
   151
    // KarpMmc
kpeter@812
   152
    checkConcept< MmcClassConcept<GR, int>,
kpeter@942
   153
                  KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
kpeter@812
   154
    checkConcept< MmcClassConcept<GR, float>,
kpeter@942
   155
                  KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
alpar@956
   156
kpeter@942
   157
    // HartmannOrlinMmc
kpeter@813
   158
    checkConcept< MmcClassConcept<GR, int>,
kpeter@942
   159
                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
kpeter@813
   160
    checkConcept< MmcClassConcept<GR, float>,
kpeter@942
   161
                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
alpar@956
   162
kpeter@942
   163
    // HowardMmc
kpeter@812
   164
    checkConcept< MmcClassConcept<GR, int>,
kpeter@942
   165
                  HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
kpeter@812
   166
    checkConcept< MmcClassConcept<GR, float>,
kpeter@942
   167
                  HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
kpeter@812
   168
kpeter@942
   169
    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
kpeter@942
   170
           ::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
kpeter@942
   171
    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
kpeter@942
   172
           ::LargeCost, double>::result == 1), "Wrong LargeCost 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);
alpar@956
   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);
alpar@956
   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@942
   197
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
kpeter@942
   198
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
kpeter@942
   199
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
kpeter@942
   200
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
kpeter@812
   201
kpeter@813
   202
    // HartmannOrlin
kpeter@942
   203
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
kpeter@942
   204
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
kpeter@942
   205
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
kpeter@942
   206
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
kpeter@813
   207
kpeter@812
   208
    // Howard
kpeter@942
   209
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
kpeter@942
   210
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
kpeter@942
   211
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
kpeter@942
   212
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
alpar@1270
   213
kpeter@1178
   214
    // Howard with iteration limit
kpeter@1178
   215
    HowardMmc<GR, IntArcMap> mmc(gr, l1);
kpeter@1178
   216
    check((mmc.findCycleMean(2) == HowardMmc<GR, IntArcMap>::ITERATION_LIMIT),
kpeter@1178
   217
      "Wrong termination cause");
kpeter@1178
   218
    check((mmc.findCycleMean(4) == HowardMmc<GR, IntArcMap>::OPTIMAL),
kpeter@1178
   219
      "Wrong termination cause");
kpeter@810
   220
  }
kpeter@810
   221
kpeter@810
   222
  return 0;
kpeter@810
   223
}