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 96 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
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
#ifndef LEMON_MIN_MEAN_CYCLE_H
20 20
#define LEMON_MIN_MEAN_CYCLE_H
21 21

	
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 {
34 35

	
35 36
  /// \brief Default traits class of MinMeanCycle class.
36 37
  ///
37 38
  /// Default traits class of MinMeanCycle class.
38 39
  /// \tparam GR The type of the digraph.
39 40
  /// \tparam LEN The type of the length map.
40 41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
41 42
#ifdef DOXYGEN
42 43
  template <typename GR, typename LEN>
43 44
#else
44 45
  template <typename GR, typename LEN,
45 46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
46 47
#endif
47 48
  struct MinMeanCycleDefaultTraits
48 49
  {
49 50
    /// The type of the digraph
50 51
    typedef GR Digraph;
51 52
    /// The type of the length map
52 53
    typedef LEN LengthMap;
53 54
    /// The type of the arc lengths
54 55
    typedef typename LengthMap::Value Value;
55 56

	
56 57
    /// \brief The large value type used for internal computations
57 58
    ///
58 59
    /// The large value type used for internal computations.
59 60
    /// It is \c long \c long if the \c Value type is integer,
60 61
    /// otherwise it is \c double.
61 62
    /// \c Value must be convertible to \c LargeValue.
62 63
    typedef double LargeValue;
63 64

	
64 65
    /// The tolerance type used for internal computations
65 66
    typedef lemon::Tolerance<LargeValue> Tolerance;
66 67

	
67 68
    /// \brief The path type of the found cycles
68 69
    ///
69 70
    /// The path type of the found cycles.
70 71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
71 72
    /// and it must have an \c addBack() function.
72 73
    typedef lemon::Path<Digraph> Path;
73 74
  };
74 75

	
75 76
  // Default traits class for integer value types
Ignore white space 6 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6 6
LINK_DIRECTORIES(
7 7
  ${PROJECT_BINARY_DIR}/lemon
8 8
)
9 9

	
10 10
SET(TESTS
11 11
  adaptors_test
12 12
  bfs_test
13 13
  circulation_test
14 14
  connectivity_test
15 15
  counter_test
16 16
  dfs_test
17 17
  digraph_test
18 18
  dijkstra_test
19 19
  dim_test
20 20
  edge_set_test
21 21
  error_test
22 22
  euler_test
23 23
  gomory_hu_test
24 24
  graph_copy_test
25 25
  graph_test
26 26
  graph_utils_test
27 27
  hao_orlin_test
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
40 41
  unionfind_test
41 42
)
42 43

	
43 44
IF(LEMON_HAVE_LP)
44 45
  ADD_EXECUTABLE(lp_test lp_test.cc)
45 46
  SET(LP_TEST_LIBS lemon)
46 47

	
47 48
  IF(LEMON_HAVE_GLPK)
48 49
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
49 50
  ENDIF()
50 51
  IF(LEMON_HAVE_CPLEX)
51 52
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
52 53
  ENDIF()
53 54
  IF(LEMON_HAVE_CLP)
54 55
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
55 56
  ENDIF()
56 57

	
57 58
  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
58 59
  ADD_TEST(lp_test lp_test)
59 60

	
60 61
  IF(WIN32 AND LEMON_HAVE_GLPK)
61 62
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
62 63
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
63 64
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
64 65
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
65 66
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
66 67
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
67 68
    )
68 69
  ENDIF()
69 70

	
70 71
  IF(WIN32 AND LEMON_HAVE_CPLEX)
71 72
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
72 73
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
73 74
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
74 75
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
75 76
    )
76 77
  ENDIF()
77 78
ENDIF()
78 79

	
79 80
IF(LEMON_HAVE_MIP)
80 81
  ADD_EXECUTABLE(mip_test mip_test.cc)
81 82
  SET(MIP_TEST_LIBS lemon)
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	test/CMakeLists.txt
3 3

	
4 4
noinst_HEADERS += \
5 5
	test/graph_test.h \
6 6
	test/test_tools.h
7 7

	
8 8
check_PROGRAMS += \
9 9
	test/adaptors_test \
10 10
	test/bfs_test \
11 11
	test/circulation_test \
12 12
	test/connectivity_test \
13 13
	test/counter_test \
14 14
	test/dfs_test \
15 15
	test/digraph_test \
16 16
	test/dijkstra_test \
17 17
	test/dim_test \
18 18
	test/edge_set_test \
19 19
	test/error_test \
20 20
	test/euler_test \
21 21
	test/gomory_hu_test \
22 22
	test/graph_copy_test \
23 23
	test/graph_test \
24 24
	test/graph_utils_test \
25 25
	test/hao_orlin_test \
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 \
38 39
	test/test_tools_pass \
39 40
	test/time_measure_test \
40 41
	test/unionfind_test
41 42

	
42 43
test_test_tools_pass_DEPENDENCIES = demo
43 44

	
44 45
if HAVE_LP
45 46
check_PROGRAMS += test/lp_test
46 47
endif HAVE_LP
47 48
if HAVE_MIP
48 49
check_PROGRAMS += test/mip_test
49 50
endif HAVE_MIP
50 51

	
51 52
TESTS += $(check_PROGRAMS)
52 53
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
53 54

	
54 55
test_adaptors_test_SOURCES = test/adaptors_test.cc
55 56
test_bfs_test_SOURCES = test/bfs_test.cc
56 57
test_circulation_test_SOURCES = test/circulation_test.cc
57 58
test_counter_test_SOURCES = test/counter_test.cc
58 59
test_connectivity_test_SOURCES = test/connectivity_test.cc
59 60
test_dfs_test_SOURCES = test/dfs_test.cc
60 61
test_digraph_test_SOURCES = test/digraph_test.cc
61 62
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
62 63
test_dim_test_SOURCES = test/dim_test.cc
63 64
test_edge_set_test_SOURCES = test/edge_set_test.cc
64 65
test_error_test_SOURCES = test/error_test.cc
65 66
test_euler_test_SOURCES = test/euler_test.cc
66 67
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
67 68
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
68 69
test_graph_test_SOURCES = test/graph_test.cc
69 70
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
70 71
test_heap_test_SOURCES = test/heap_test.cc
71 72
test_kruskal_test_SOURCES = test/kruskal_test.cc
72 73
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
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
85 87
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
86 88
test_time_measure_test_SOURCES = test/time_measure_test.cc
87 89
test_unionfind_test_SOURCES = test/unionfind_test.cc
Ignore white space 6 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
#ifndef LEMON_TEST_TEST_TOOLS_H
20 20
#define LEMON_TEST_TEST_TOOLS_H
21 21

	
22 22
///\ingroup misc
23 23
///\file
24 24
///\brief Some utilities to write test programs.
25 25

	
26 26
#include <iostream>
27 27
#include <stdlib.h>
28 28

	
29 29
///If \c rc is fail, writes an error message and exits.
30 30

	
31 31
///If \c rc is fail, writes an error message and exits.
32 32
///The error message contains the file name and the line number of the
33 33
///source code in a standard from, which makes it possible to go there
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)