gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add a detailed test file for MinMeanCycle and fix test_tools.h (#179)
0 4 1
default
5 files changed with 197 insertions and 5 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#include <iostream>
20
#include <sstream>
21

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

	
29
#include "test_tools.h"
30

	
31
using namespace lemon;
32

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

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

	
71
      typedef typename MMC
72
        ::template SetPath<ListPath<GR> >
73
        ::template SetLargeValue<Value>
74
        ::Create MmcAlg;
75
      MmcAlg mmc(me.g, me.length);
76
      const MmcAlg& const_mmc = mmc;
77
      
78
      b = mmc.cycle(p).run();
79
      b = mmc.findMinMean();
80
      b = mmc.findCycle();
81

	
82
      v = const_mmc.cycleLength();
83
      i = const_mmc.cycleArcNum();
84
      d = const_mmc.cycleMean();
85
      p = const_mmc.cycle();
86
    }
87

	
88
    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
89
  
90
    GR g;
91
    LM length;
92
    ListPath<GR> p;
93
    Value v;
94
    int i;
95
    double d;
96
    bool b;
97
  };
98
};
99

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

	
122
// Class for comparing types
123
template <typename T1, typename T2>
124
struct IsSameType {
125
  static const int result = 0;
126
};
127

	
128
template <typename T>
129
struct IsSameType<T,T> {
130
  static const int result = 1;
131
};
132

	
133

	
134
int main() {
135
  #ifdef LEMON_HAVE_LONG_LONG
136
    typedef long long long_int;
137
  #else
138
    typedef long long_int;
139
  #endif
140

	
141
  // Check the interface
142
  {
143
    typedef concepts::Digraph GR;
144
    typedef MinMeanCycle<GR, concepts::ReadMap<GR::Arc, int> > IntMmcAlg;
145
    typedef MinMeanCycle<GR, concepts::ReadMap<GR::Arc, float> > FloatMmcAlg;
146
    
147
    checkConcept<MmcClassConcept<GR, int>, IntMmcAlg>();
148
    checkConcept<MmcClassConcept<GR, float>, FloatMmcAlg>();
149
  
150
    if (IsSameType<IntMmcAlg::LargeValue, long_int>::result == 0)
151
      check(false, "Wrong LargeValue type");
152
    if (IsSameType<FloatMmcAlg::LargeValue, double>::result == 0)
153
      check(false, "Wrong LargeValue type");
154
  }
155

	
156
  // Run various tests
157
  {
158
    typedef SmartDigraph GR;
159
    DIGRAPH_TYPEDEFS(GR);
160
    
161
    GR gr;
162
    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
163
    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
164
    
165
    std::istringstream input(test_lgf);
166
    digraphReader(gr, input).
167
      arcMap("len1", l1).
168
      arcMap("len2", l2).
169
      arcMap("len3", l3).
170
      arcMap("len4", l4).
171
      arcMap("c1", c1).
172
      arcMap("c2", c2).
173
      arcMap("c3", c3).
174
      arcMap("c4", c4).
175
      run();
176

	
177
    checkMmcAlg<MinMeanCycle<GR, IntArcMap> >(gr, l1, c1,  6, 3);
178
    checkMmcAlg<MinMeanCycle<GR, IntArcMap> >(gr, l2, c2,  5, 2);
179
    checkMmcAlg<MinMeanCycle<GR, IntArcMap> >(gr, l3, c3,  0, 1);
180
    checkMmcAlg<MinMeanCycle<GR, IntArcMap> >(gr, l4, c4, -1, 1);
181
  }
182

	
183
  return 0;
184
}
Ignore white space 12 line context
... ...
@@ -22,12 +22,13 @@
22 22
/// \ingroup shortest_path
23 23
///
24 24
/// \file
25 25
/// \brief Howard's algorithm for finding a minimum mean cycle.
26 26

	
27 27
#include <vector>
28
#include <limits>
28 29
#include <lemon/core.h>
29 30
#include <lemon/path.h>
30 31
#include <lemon/tolerance.h>
31 32
#include <lemon/connectivity.h>
32 33

	
33 34
namespace lemon {
Ignore white space 6 line context
... ...
@@ -28,12 +28,13 @@
28 28
  heap_test
29 29
  kruskal_test
30 30
  maps_test
31 31
  matching_test
32 32
  min_cost_arborescence_test
33 33
  min_cost_flow_test
34
  min_mean_cycle_test
34 35
  path_test
35 36
  preflow_test
36 37
  radix_sort_test
37 38
  random_test
38 39
  suurballe_test
39 40
  time_measure_test
Ignore white space 6 line context
... ...
@@ -26,12 +26,13 @@
26 26
	test/heap_test \
27 27
	test/kruskal_test \
28 28
	test/maps_test \
29 29
	test/matching_test \
30 30
	test/min_cost_arborescence_test \
31 31
	test/min_cost_flow_test \
32
	test/min_mean_cycle_test \
32 33
	test/path_test \
33 34
	test/preflow_test \
34 35
	test/radix_sort_test \
35 36
	test/random_test \
36 37
	test/suurballe_test \
37 38
	test/test_tools_fail \
... ...
@@ -73,12 +74,13 @@
73 74
test_lp_test_SOURCES = test/lp_test.cc
74 75
test_maps_test_SOURCES = test/maps_test.cc
75 76
test_mip_test_SOURCES = test/mip_test.cc
76 77
test_matching_test_SOURCES = test/matching_test.cc
77 78
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
78 79
test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
80
test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
79 81
test_path_test_SOURCES = test/path_test.cc
80 82
test_preflow_test_SOURCES = test/preflow_test.cc
81 83
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
82 84
test_suurballe_test_SOURCES = test/suurballe_test.cc
83 85
test_random_test_SOURCES = test/random_test.cc
84 86
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
Ignore white space 6 line context
... ...
@@ -34,13 +34,17 @@
34 34
///using good source browsers like e.g. \c emacs.
35 35
///
36 36
///For example
37 37
///\code check(0==1,"This is obviously false.");\endcode will
38 38
///print something like this (and then exits).
39 39
///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
40
#define check(rc, msg) \
41
  if(!(rc)) { \
42
    std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
43
    abort(); \
44
  } else { } \
40
#define check(rc, msg)                                                  \
41
  {                                                                     \
42
    if(!(rc)) {                                                         \
43
      std::cerr << __FILE__ ":" << __LINE__ << ": error: "              \
44
                << msg << std::endl;                                    \
45
      abort();                                                          \
46
    } else { }                                                          \
47
  }                                                                     \
48
    
45 49

	
46 50
#endif
0 comments (0 inline)