Add a detailed test file for MinMeanCycle and fix test_tools.h (#179)
authorPeter Kovacs <kpeter@inf.elte.hu>
Fri, 07 Aug 2009 14:52:40 +0200
changeset 81093cd93e82f9b
parent 809 03887b5e0f6f
child 811 1fac515a59c1
Add a detailed test file for MinMeanCycle and fix test_tools.h (#179)
lemon/min_mean_cycle.h
test/CMakeLists.txt
test/Makefile.am
test/min_mean_cycle_test.cc
test/test_tools.h
     1.1 --- a/lemon/min_mean_cycle.h	Thu Aug 06 20:31:04 2009 +0200
     1.2 +++ b/lemon/min_mean_cycle.h	Fri Aug 07 14:52:40 2009 +0200
     1.3 @@ -25,6 +25,7 @@
     1.4  /// \brief Howard's algorithm for finding a minimum mean cycle.
     1.5  
     1.6  #include <vector>
     1.7 +#include <limits>
     1.8  #include <lemon/core.h>
     1.9  #include <lemon/path.h>
    1.10  #include <lemon/tolerance.h>
     2.1 --- a/test/CMakeLists.txt	Thu Aug 06 20:31:04 2009 +0200
     2.2 +++ b/test/CMakeLists.txt	Fri Aug 07 14:52:40 2009 +0200
     2.3 @@ -31,6 +31,7 @@
     2.4    matching_test
     2.5    min_cost_arborescence_test
     2.6    min_cost_flow_test
     2.7 +  min_mean_cycle_test
     2.8    path_test
     2.9    preflow_test
    2.10    radix_sort_test
     3.1 --- a/test/Makefile.am	Thu Aug 06 20:31:04 2009 +0200
     3.2 +++ b/test/Makefile.am	Fri Aug 07 14:52:40 2009 +0200
     3.3 @@ -29,6 +29,7 @@
     3.4  	test/matching_test \
     3.5  	test/min_cost_arborescence_test \
     3.6  	test/min_cost_flow_test \
     3.7 +	test/min_mean_cycle_test \
     3.8  	test/path_test \
     3.9  	test/preflow_test \
    3.10  	test/radix_sort_test \
    3.11 @@ -76,6 +77,7 @@
    3.12  test_matching_test_SOURCES = test/matching_test.cc
    3.13  test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
    3.14  test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
    3.15 +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
    3.16  test_path_test_SOURCES = test/path_test.cc
    3.17  test_preflow_test_SOURCES = test/preflow_test.cc
    3.18  test_radix_sort_test_SOURCES = test/radix_sort_test.cc
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/min_mean_cycle_test.cc	Fri Aug 07 14:52:40 2009 +0200
     4.3 @@ -0,0 +1,184 @@
     4.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
     4.5 + *
     4.6 + * This file is a part of LEMON, a generic C++ optimization library.
     4.7 + *
     4.8 + * Copyright (C) 2003-2009
     4.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    4.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    4.11 + *
    4.12 + * Permission to use, modify and distribute this software is granted
    4.13 + * provided that this copyright notice appears in all copies. For
    4.14 + * precise terms see the accompanying LICENSE file.
    4.15 + *
    4.16 + * This software is provided "AS IS" with no warranty of any kind,
    4.17 + * express or implied, and with no claim as to its suitability for any
    4.18 + * purpose.
    4.19 + *
    4.20 + */
    4.21 +
    4.22 +#include <iostream>
    4.23 +#include <sstream>
    4.24 +
    4.25 +#include <lemon/smart_graph.h>
    4.26 +#include <lemon/lgf_reader.h>
    4.27 +#include <lemon/min_mean_cycle.h>
    4.28 +#include <lemon/path.h>
    4.29 +#include <lemon/concepts/digraph.h>
    4.30 +#include <lemon/concept_check.h>
    4.31 +
    4.32 +#include "test_tools.h"
    4.33 +
    4.34 +using namespace lemon;
    4.35 +
    4.36 +char test_lgf[] =
    4.37 +  "@nodes\n"
    4.38 +  "label\n"
    4.39 +  "1\n"
    4.40 +  "2\n"
    4.41 +  "3\n"
    4.42 +  "4\n"
    4.43 +  "5\n"
    4.44 +  "6\n"
    4.45 +  "7\n"
    4.46 +  "@arcs\n"
    4.47 +  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
    4.48 +  "1 2    1    1    1    1   0  0  0  0\n"
    4.49 +  "2 4    5    5    5    5   1  0  0  0\n"
    4.50 +  "2 3    8    8    8    8   0  0  0  0\n"
    4.51 +  "3 2   -2    0    0    0   1  0  0  0\n"
    4.52 +  "3 4    4    4    4    4   0  0  0  0\n"
    4.53 +  "3 7   -4   -4   -4   -4   0  0  0  0\n"
    4.54 +  "4 1    2    2    2    2   0  0  0  0\n"
    4.55 +  "4 3    3    3    3    3   1  0  0  0\n"
    4.56 +  "4 4    3    3    0    0   0  0  1  0\n"
    4.57 +  "5 2    4    4    4    4   0  0  0  0\n"
    4.58 +  "5 6    3    3    3    3   0  1  0  0\n"
    4.59 +  "6 5    2    2    2    2   0  1  0  0\n"
    4.60 +  "6 4   -1   -1   -1   -1   0  0  0  0\n"
    4.61 +  "6 7    1    1    1    1   0  0  0  0\n"
    4.62 +  "7 7    4    4    4   -1   0  0  0  1\n";
    4.63 +
    4.64 +                        
    4.65 +// Check the interface of an MMC algorithm
    4.66 +template <typename GR, typename Value>
    4.67 +struct MmcClassConcept
    4.68 +{
    4.69 +  template <typename MMC>
    4.70 +  struct Constraints {
    4.71 +    void constraints() {
    4.72 +      const Constraints& me = *this;
    4.73 +
    4.74 +      typedef typename MMC
    4.75 +        ::template SetPath<ListPath<GR> >
    4.76 +        ::template SetLargeValue<Value>
    4.77 +        ::Create MmcAlg;
    4.78 +      MmcAlg mmc(me.g, me.length);
    4.79 +      const MmcAlg& const_mmc = mmc;
    4.80 +      
    4.81 +      b = mmc.cycle(p).run();
    4.82 +      b = mmc.findMinMean();
    4.83 +      b = mmc.findCycle();
    4.84 +
    4.85 +      v = const_mmc.cycleLength();
    4.86 +      i = const_mmc.cycleArcNum();
    4.87 +      d = const_mmc.cycleMean();
    4.88 +      p = const_mmc.cycle();
    4.89 +    }
    4.90 +
    4.91 +    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
    4.92 +  
    4.93 +    GR g;
    4.94 +    LM length;
    4.95 +    ListPath<GR> p;
    4.96 +    Value v;
    4.97 +    int i;
    4.98 +    double d;
    4.99 +    bool b;
   4.100 +  };
   4.101 +};
   4.102 +
   4.103 +// Perform a test with the given parameters
   4.104 +template <typename MMC>
   4.105 +void checkMmcAlg(const SmartDigraph& gr,
   4.106 +                 const SmartDigraph::ArcMap<int>& lm,
   4.107 +                 const SmartDigraph::ArcMap<int>& cm,
   4.108 +                 int length, int size) {
   4.109 +  MMC alg(gr, lm);
   4.110 +  alg.findMinMean();
   4.111 +  check(alg.cycleMean() == static_cast<double>(length) / size,
   4.112 +        "Wrong cycle mean");
   4.113 +  alg.findCycle();
   4.114 +  check(alg.cycleLength() == length && alg.cycleArcNum() == size,
   4.115 +        "Wrong path");
   4.116 +  SmartDigraph::ArcMap<int> cycle(gr, 0);
   4.117 +  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
   4.118 +    ++cycle[a];
   4.119 +  }
   4.120 +  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
   4.121 +    check(cm[a] == cycle[a], "Wrong path");
   4.122 +  }
   4.123 +}
   4.124 +
   4.125 +// Class for comparing types
   4.126 +template <typename T1, typename T2>
   4.127 +struct IsSameType {
   4.128 +  static const int result = 0;
   4.129 +};
   4.130 +
   4.131 +template <typename T>
   4.132 +struct IsSameType<T,T> {
   4.133 +  static const int result = 1;
   4.134 +};
   4.135 +
   4.136 +
   4.137 +int main() {
   4.138 +  #ifdef LEMON_HAVE_LONG_LONG
   4.139 +    typedef long long long_int;
   4.140 +  #else
   4.141 +    typedef long long_int;
   4.142 +  #endif
   4.143 +
   4.144 +  // Check the interface
   4.145 +  {
   4.146 +    typedef concepts::Digraph GR;
   4.147 +    typedef MinMeanCycle<GR, concepts::ReadMap<GR::Arc, int> > IntMmcAlg;
   4.148 +    typedef MinMeanCycle<GR, concepts::ReadMap<GR::Arc, float> > FloatMmcAlg;
   4.149 +    
   4.150 +    checkConcept<MmcClassConcept<GR, int>, IntMmcAlg>();
   4.151 +    checkConcept<MmcClassConcept<GR, float>, FloatMmcAlg>();
   4.152 +  
   4.153 +    if (IsSameType<IntMmcAlg::LargeValue, long_int>::result == 0)
   4.154 +      check(false, "Wrong LargeValue type");
   4.155 +    if (IsSameType<FloatMmcAlg::LargeValue, double>::result == 0)
   4.156 +      check(false, "Wrong LargeValue type");
   4.157 +  }
   4.158 +
   4.159 +  // Run various tests
   4.160 +  {
   4.161 +    typedef SmartDigraph GR;
   4.162 +    DIGRAPH_TYPEDEFS(GR);
   4.163 +    
   4.164 +    GR gr;
   4.165 +    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
   4.166 +    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
   4.167 +    
   4.168 +    std::istringstream input(test_lgf);
   4.169 +    digraphReader(gr, input).
   4.170 +      arcMap("len1", l1).
   4.171 +      arcMap("len2", l2).
   4.172 +      arcMap("len3", l3).
   4.173 +      arcMap("len4", l4).
   4.174 +      arcMap("c1", c1).
   4.175 +      arcMap("c2", c2).
   4.176 +      arcMap("c3", c3).
   4.177 +      arcMap("c4", c4).
   4.178 +      run();
   4.179 +
   4.180 +    checkMmcAlg<MinMeanCycle<GR, IntArcMap> >(gr, l1, c1,  6, 3);
   4.181 +    checkMmcAlg<MinMeanCycle<GR, IntArcMap> >(gr, l2, c2,  5, 2);
   4.182 +    checkMmcAlg<MinMeanCycle<GR, IntArcMap> >(gr, l3, c3,  0, 1);
   4.183 +    checkMmcAlg<MinMeanCycle<GR, IntArcMap> >(gr, l4, c4, -1, 1);
   4.184 +  }
   4.185 +
   4.186 +  return 0;
   4.187 +}
     5.1 --- a/test/test_tools.h	Thu Aug 06 20:31:04 2009 +0200
     5.2 +++ b/test/test_tools.h	Fri Aug 07 14:52:40 2009 +0200
     5.3 @@ -37,10 +37,14 @@
     5.4  ///\code check(0==1,"This is obviously false.");\endcode will
     5.5  ///print something like this (and then exits).
     5.6  ///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
     5.7 -#define check(rc, msg) \
     5.8 -  if(!(rc)) { \
     5.9 -    std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
    5.10 -    abort(); \
    5.11 -  } else { } \
    5.12 +#define check(rc, msg)                                                  \
    5.13 +  {                                                                     \
    5.14 +    if(!(rc)) {                                                         \
    5.15 +      std::cerr << __FILE__ ":" << __LINE__ << ": error: "              \
    5.16 +                << msg << std::endl;                                    \
    5.17 +      abort();                                                          \
    5.18 +    } else { }                                                          \
    5.19 +  }                                                                     \
    5.20 +    
    5.21  
    5.22  #endif