gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Rename max_matching.h to matching.h (#265)
2 4 2
default
8 files changed with 6 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	lemon/lemon.pc.in \
3 3
	lemon/CMakeLists.txt
4 4

	
5 5
pkgconfig_DATA += lemon/lemon.pc
6 6

	
7 7
lib_LTLIBRARIES += lemon/libemon.la
8 8

	
9 9
lemon_libemon_la_SOURCES = \
10 10
	lemon/arg_parser.cc \
11 11
	lemon/base.cc \
12 12
	lemon/color.cc \
13 13
	lemon/lp_base.cc \
14 14
	lemon/lp_skeleton.cc \
15 15
	lemon/random.cc \
16 16
	lemon/bits/windows.cc
17 17

	
18 18

	
19 19
lemon_libemon_la_CXXFLAGS = \
20 20
	$(AM_CXXFLAGS) \
21 21
	$(GLPK_CFLAGS) \
22 22
	$(CPLEX_CFLAGS) \
23 23
	$(SOPLEX_CXXFLAGS) \
24 24
	$(CLP_CXXFLAGS) \
25 25
	$(CBC_CXXFLAGS)
26 26

	
27 27
lemon_libemon_la_LDFLAGS = \
28 28
	$(GLPK_LIBS) \
29 29
	$(CPLEX_LIBS) \
30 30
	$(SOPLEX_LIBS) \
31 31
	$(CLP_LIBS) \
32 32
	$(CBC_LIBS)
33 33

	
34 34
if HAVE_GLPK
35 35
lemon_libemon_la_SOURCES += lemon/glpk.cc
36 36
endif
37 37

	
38 38
if HAVE_CPLEX
39 39
lemon_libemon_la_SOURCES += lemon/cplex.cc
40 40
endif
41 41

	
42 42
if HAVE_SOPLEX
43 43
lemon_libemon_la_SOURCES += lemon/soplex.cc
44 44
endif
45 45

	
46 46
if HAVE_CLP
47 47
lemon_libemon_la_SOURCES += lemon/clp.cc
48 48
endif
49 49

	
50 50
if HAVE_CBC
51 51
lemon_libemon_la_SOURCES += lemon/cbc.cc
52 52
endif
53 53

	
54 54
lemon_HEADERS += \
55 55
	lemon/adaptors.h \
56 56
	lemon/arg_parser.h \
57 57
	lemon/assert.h \
58 58
	lemon/bfs.h \
59 59
	lemon/bin_heap.h \
60 60
	lemon/circulation.h \
61 61
	lemon/clp.h \
62 62
	lemon/color.h \
63 63
	lemon/concept_check.h \
64 64
	lemon/connectivity.h \
65 65
	lemon/counter.h \
66 66
	lemon/core.h \
67 67
	lemon/cplex.h \
68 68
	lemon/dfs.h \
69 69
	lemon/dijkstra.h \
70 70
	lemon/dim2.h \
71 71
	lemon/dimacs.h \
72 72
	lemon/edge_set.h \
73 73
	lemon/elevator.h \
74 74
	lemon/error.h \
75 75
	lemon/euler.h \
76 76
	lemon/full_graph.h \
77 77
	lemon/glpk.h \
78 78
	lemon/gomory_hu.h \
79 79
	lemon/graph_to_eps.h \
80 80
	lemon/grid_graph.h \
81 81
	lemon/hypercube_graph.h \
82 82
	lemon/kruskal.h \
83 83
	lemon/hao_orlin.h \
84 84
	lemon/lgf_reader.h \
85 85
	lemon/lgf_writer.h \
86 86
	lemon/list_graph.h \
87 87
	lemon/lp.h \
88 88
	lemon/lp_base.h \
89 89
	lemon/lp_skeleton.h \
90 90
	lemon/list_graph.h \
91 91
	lemon/maps.h \
92
	lemon/matching.h \
92 93
	lemon/math.h \
93
	lemon/max_matching.h \
94 94
	lemon/min_cost_arborescence.h \
95 95
	lemon/nauty_reader.h \
96 96
	lemon/path.h \
97 97
	lemon/preflow.h \
98 98
	lemon/radix_sort.h \
99 99
	lemon/random.h \
100 100
	lemon/smart_graph.h \
101 101
	lemon/soplex.h \
102 102
	lemon/suurballe.h \
103 103
	lemon/time_measure.h \
104 104
	lemon/tolerance.h \
105 105
	lemon/unionfind.h \
106 106
	lemon/bits/windows.h
107 107

	
108 108
bits_HEADERS += \
109 109
	lemon/bits/alteration_notifier.h \
110 110
	lemon/bits/array_map.h \
111 111
	lemon/bits/base_extender.h \
112 112
	lemon/bits/bezier.h \
113 113
	lemon/bits/default_map.h \
114 114
	lemon/bits/edge_set_extender.h \
115 115
	lemon/bits/enable_if.h \
116 116
	lemon/bits/graph_adaptor_extender.h \
117 117
	lemon/bits/graph_extender.h \
118 118
	lemon/bits/map_extender.h \
119 119
	lemon/bits/path_dump.h \
120 120
	lemon/bits/solver_bits.h \
121 121
	lemon/bits/traits.h \
122 122
	lemon/bits/variant.h \
123 123
	lemon/bits/vector_map.h
124 124

	
125 125
concept_HEADERS += \
126 126
	lemon/concepts/digraph.h \
127 127
	lemon/concepts/graph.h \
128 128
	lemon/concepts/graph_components.h \
129 129
	lemon/concepts/heap.h \
130 130
	lemon/concepts/maps.h \
131 131
	lemon/concepts/path.h
Ignore white space 6 line context
file renamed from lemon/max_matching.h to lemon/matching.h
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
IF(HAVE_GLPK)
7 7
  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIR})
8 8
ENDIF(HAVE_GLPK)
9 9

	
10 10
LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lemon)
11 11

	
12 12
SET(TESTS
13 13
  adaptors_test
14 14
  bfs_test
15 15
  circulation_test
16 16
  counter_test
17 17
  dfs_test
18 18
  digraph_test
19 19
  dijkstra_test
20 20
  dim_test
21 21
  edge_set_test
22 22
  error_test
23 23
  euler_test
24 24
  gomory_hu_test
25 25
  graph_copy_test
26 26
  graph_test
27 27
  graph_utils_test
28 28
  hao_orlin_test
29 29
  heap_test
30 30
  kruskal_test
31 31
  maps_test
32
  max_matching_test
32
  matching_test
33 33
  min_cost_arborescence_test
34 34
  path_test
35 35
  preflow_test
36 36
  radix_sort_test
37 37
  random_test
38 38
  suurballe_test
39 39
  time_measure_test
40 40
  unionfind_test)
41 41

	
42 42
IF(HAVE_LP)
43 43
  ADD_EXECUTABLE(lp_test lp_test.cc)
44 44
  IF(HAVE_GLPK)
45 45
    TARGET_LINK_LIBRARIES(lp_test lemon ${GLPK_LIBRARIES})
46 46
  ENDIF(HAVE_GLPK)
47 47
  ADD_TEST(lp_test lp_test)
48 48

	
49 49
  IF(WIN32 AND HAVE_GLPK)
50 50
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
51 51
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
52 52
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
53 53
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
54 54
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
55 55
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
56 56
    )
57 57
  ENDIF(WIN32 AND HAVE_GLPK)
58 58
ENDIF(HAVE_LP)
59 59

	
60 60
IF(HAVE_MIP)
61 61
  ADD_EXECUTABLE(mip_test mip_test.cc)
62 62
  IF(HAVE_GLPK)
63 63
    TARGET_LINK_LIBRARIES(mip_test lemon ${GLPK_LIBRARIES})
64 64
  ENDIF(HAVE_GLPK)
65 65
  ADD_TEST(mip_test mip_test)
66 66

	
67 67
  IF(WIN32 AND HAVE_GLPK)
68 68
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
69 69
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
70 70
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
71 71
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
72 72
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
73 73
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
74 74
    )
75 75
  ENDIF(WIN32 AND HAVE_GLPK)
76 76
ENDIF(HAVE_MIP)
77 77

	
78 78
FOREACH(TEST_NAME ${TESTS})
79 79
  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
80 80
  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
81 81
  ADD_TEST(${TEST_NAME} ${TEST_NAME})
82 82
ENDFOREACH(TEST_NAME)
Ignore white space 768 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/counter_test \
13 13
	test/dfs_test \
14 14
	test/digraph_test \
15 15
	test/dijkstra_test \
16 16
	test/dim_test \
17 17
	test/edge_set_test \
18 18
	test/error_test \
19 19
	test/euler_test \
20 20
	test/gomory_hu_test \
21 21
	test/graph_copy_test \
22 22
	test/graph_test \
23 23
	test/graph_utils_test \
24 24
	test/hao_orlin_test \
25 25
	test/heap_test \
26 26
	test/kruskal_test \
27 27
	test/maps_test \
28
	test/max_matching_test \
28
	test/matching_test \
29 29
	test/min_cost_arborescence_test \
30 30
	test/path_test \
31 31
	test/preflow_test \
32 32
	test/radix_sort_test \
33 33
	test/random_test \
34 34
	test/suurballe_test \
35 35
	test/test_tools_fail \
36 36
	test/test_tools_pass \
37 37
	test/time_measure_test \
38 38
	test/unionfind_test
39 39

	
40 40
test_test_tools_pass_DEPENDENCIES = demo
41 41

	
42 42
if HAVE_LP
43 43
check_PROGRAMS += test/lp_test
44 44
endif HAVE_LP
45 45
if HAVE_MIP
46 46
check_PROGRAMS += test/mip_test
47 47
endif HAVE_MIP
48 48

	
49 49
TESTS += $(check_PROGRAMS)
50 50
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
51 51

	
52 52
test_adaptors_test_SOURCES = test/adaptors_test.cc
53 53
test_bfs_test_SOURCES = test/bfs_test.cc
54 54
test_circulation_test_SOURCES = test/circulation_test.cc
55 55
test_counter_test_SOURCES = test/counter_test.cc
56 56
test_dfs_test_SOURCES = test/dfs_test.cc
57 57
test_digraph_test_SOURCES = test/digraph_test.cc
58 58
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
59 59
test_dim_test_SOURCES = test/dim_test.cc
60 60
test_edge_set_test_SOURCES = test/edge_set_test.cc
61 61
test_error_test_SOURCES = test/error_test.cc
62 62
test_euler_test_SOURCES = test/euler_test.cc
63 63
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
64 64
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
65 65
test_graph_test_SOURCES = test/graph_test.cc
66 66
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
67 67
test_heap_test_SOURCES = test/heap_test.cc
68 68
test_kruskal_test_SOURCES = test/kruskal_test.cc
69 69
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
70 70
test_lp_test_SOURCES = test/lp_test.cc
71 71
test_maps_test_SOURCES = test/maps_test.cc
72 72
test_mip_test_SOURCES = test/mip_test.cc
73
test_max_matching_test_SOURCES = test/max_matching_test.cc
73
test_matching_test_SOURCES = test/matching_test.cc
74 74
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
75 75
test_path_test_SOURCES = test/path_test.cc
76 76
test_preflow_test_SOURCES = test/preflow_test.cc
77 77
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
78 78
test_suurballe_test_SOURCES = test/suurballe_test.cc
79 79
test_random_test_SOURCES = test/random_test.cc
80 80
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
81 81
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
82 82
test_time_measure_test_SOURCES = test/time_measure_test.cc
83 83
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
#include <iostream>
20 20
#include <sstream>
21 21
#include <vector>
22 22
#include <queue>
23 23
#include <cstdlib>
24 24

	
25
#include <lemon/max_matching.h>
25
#include <lemon/matching.h>
26 26
#include <lemon/smart_graph.h>
27 27
#include <lemon/concepts/graph.h>
28 28
#include <lemon/concepts/maps.h>
29 29
#include <lemon/lgf_reader.h>
30 30
#include <lemon/math.h>
31 31

	
32 32
#include "test_tools.h"
33 33

	
34 34
using namespace std;
35 35
using namespace lemon;
36 36

	
37 37
GRAPH_TYPEDEFS(SmartGraph);
38 38

	
39 39

	
40 40
const int lgfn = 3;
41 41
const std::string lgf[lgfn] = {
42 42
  "@nodes\n"
43 43
  "label\n"
44 44
  "0\n"
45 45
  "1\n"
46 46
  "2\n"
47 47
  "3\n"
48 48
  "4\n"
49 49
  "5\n"
50 50
  "6\n"
51 51
  "7\n"
52 52
  "@edges\n"
53 53
  "     label  weight\n"
54 54
  "7 4  0      984\n"
55 55
  "0 7  1      73\n"
56 56
  "7 1  2      204\n"
57 57
  "2 3  3      583\n"
58 58
  "2 7  4      565\n"
59 59
  "2 1  5      582\n"
60 60
  "0 4  6      551\n"
61 61
  "2 5  7      385\n"
62 62
  "1 5  8      561\n"
63 63
  "5 3  9      484\n"
64 64
  "7 5  10     904\n"
65 65
  "3 6  11     47\n"
66 66
  "7 6  12     888\n"
67 67
  "3 0  13     747\n"
68 68
  "6 1  14     310\n",
69 69

	
70 70
  "@nodes\n"
71 71
  "label\n"
72 72
  "0\n"
73 73
  "1\n"
74 74
  "2\n"
75 75
  "3\n"
76 76
  "4\n"
77 77
  "5\n"
78 78
  "6\n"
79 79
  "7\n"
80 80
  "@edges\n"
81 81
  "     label  weight\n"
82 82
  "2 5  0      710\n"
83 83
  "0 5  1      241\n"
84 84
  "2 4  2      856\n"
85 85
  "2 6  3      762\n"
86 86
  "4 1  4      747\n"
87 87
  "6 1  5      962\n"
88 88
  "4 7  6      723\n"
89 89
  "1 7  7      661\n"
90 90
  "2 3  8      376\n"
91 91
  "1 0  9      416\n"
92 92
  "6 7  10     391\n",
93 93

	
94 94
  "@nodes\n"
95 95
  "label\n"
96 96
  "0\n"
97 97
  "1\n"
98 98
  "2\n"
99 99
  "3\n"
100 100
  "4\n"
101 101
  "5\n"
102 102
  "6\n"
103 103
  "7\n"
104 104
  "@edges\n"
105 105
  "     label  weight\n"
106 106
  "6 2  0      553\n"
107 107
  "0 7  1      653\n"
108 108
  "6 3  2      22\n"
109 109
  "4 7  3      846\n"
110 110
  "7 2  4      981\n"
111 111
  "7 6  5      250\n"
112 112
  "5 2  6      539\n",
113 113
};
114 114

	
115 115
void checkMaxMatchingCompile()
116 116
{
117 117
  typedef concepts::Graph Graph;
118 118
  typedef Graph::Node Node;
119 119
  typedef Graph::Edge Edge;
120 120
  typedef Graph::EdgeMap<bool> MatMap;
121 121

	
122 122
  Graph g;
123 123
  Node n;
124 124
  Edge e;
125 125
  MatMap mat(g);
126 126

	
127 127
  MaxMatching<Graph> mat_test(g);
128 128
  const MaxMatching<Graph>&
129 129
    const_mat_test = mat_test;
130 130

	
131 131
  mat_test.init();
132 132
  mat_test.greedyInit();
133 133
  mat_test.matchingInit(mat);
134 134
  mat_test.startSparse();
135 135
  mat_test.startDense();
136 136
  mat_test.run();
137 137
  
138 138
  const_mat_test.matchingSize();
139 139
  const_mat_test.matching(e);
140 140
  const_mat_test.matching(n);
141 141
  const MaxMatching<Graph>::MatchingMap& mmap =
142 142
    const_mat_test.matchingMap();
143 143
  e = mmap[n];
144 144
  const_mat_test.mate(n);
145 145

	
146 146
  MaxMatching<Graph>::Status stat = 
147 147
    const_mat_test.status(n);
148 148
  const MaxMatching<Graph>::StatusMap& smap =
149 149
    const_mat_test.statusMap();
150 150
  stat = smap[n];
151 151
  const_mat_test.barrier(n);
152 152
}
153 153

	
154 154
void checkMaxWeightedMatchingCompile()
155 155
{
156 156
  typedef concepts::Graph Graph;
157 157
  typedef Graph::Node Node;
158 158
  typedef Graph::Edge Edge;
159 159
  typedef Graph::EdgeMap<int> WeightMap;
160 160

	
161 161
  Graph g;
162 162
  Node n;
163 163
  Edge e;
164 164
  WeightMap w(g);
165 165

	
166 166
  MaxWeightedMatching<Graph> mat_test(g, w);
167 167
  const MaxWeightedMatching<Graph>&
168 168
    const_mat_test = mat_test;
169 169

	
170 170
  mat_test.init();
171 171
  mat_test.start();
172 172
  mat_test.run();
173 173
  
174 174
  const_mat_test.matchingWeight();
175 175
  const_mat_test.matchingSize();
176 176
  const_mat_test.matching(e);
177 177
  const_mat_test.matching(n);
178 178
  const MaxWeightedMatching<Graph>::MatchingMap& mmap =
179 179
    const_mat_test.matchingMap();
180 180
  e = mmap[n];
181 181
  const_mat_test.mate(n);
182 182
  
183 183
  int k = 0;
184 184
  const_mat_test.dualValue();
185 185
  const_mat_test.nodeValue(n);
186 186
  const_mat_test.blossomNum();
187 187
  const_mat_test.blossomSize(k);
188 188
  const_mat_test.blossomValue(k);
189 189
}
190 190

	
191 191
void checkMaxWeightedPerfectMatchingCompile()
192 192
{
193 193
  typedef concepts::Graph Graph;
194 194
  typedef Graph::Node Node;
195 195
  typedef Graph::Edge Edge;
196 196
  typedef Graph::EdgeMap<int> WeightMap;
197 197

	
198 198
  Graph g;
199 199
  Node n;
200 200
  Edge e;
201 201
  WeightMap w(g);
202 202

	
203 203
  MaxWeightedPerfectMatching<Graph> mat_test(g, w);
204 204
  const MaxWeightedPerfectMatching<Graph>&
205 205
    const_mat_test = mat_test;
206 206

	
207 207
  mat_test.init();
208 208
  mat_test.start();
209 209
  mat_test.run();
210 210
  
211 211
  const_mat_test.matchingWeight();
212 212
  const_mat_test.matching(e);
213 213
  const_mat_test.matching(n);
214 214
  const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
215 215
    const_mat_test.matchingMap();
216 216
  e = mmap[n];
217 217
  const_mat_test.mate(n);
218 218
  
219 219
  int k = 0;
220 220
  const_mat_test.dualValue();
221 221
  const_mat_test.nodeValue(n);
222 222
  const_mat_test.blossomNum();
223 223
  const_mat_test.blossomSize(k);
224 224
  const_mat_test.blossomValue(k);
225 225
}
226 226

	
227 227
void checkMatching(const SmartGraph& graph,
228 228
                   const MaxMatching<SmartGraph>& mm) {
229 229
  int num = 0;
230 230

	
231 231
  IntNodeMap comp_index(graph);
232 232
  UnionFind<IntNodeMap> comp(comp_index);
233 233

	
234 234
  int barrier_num = 0;
235 235

	
236 236
  for (NodeIt n(graph); n != INVALID; ++n) {
237 237
    check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
238 238
          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
239 239
    if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
240 240
      ++barrier_num;
241 241
    } else {
242 242
      comp.insert(n);
243 243
    }
244 244
  }
245 245

	
246 246
  for (EdgeIt e(graph); e != INVALID; ++e) {
247 247
    if (mm.matching(e)) {
248 248
      check(e == mm.matching(graph.u(e)), "Wrong matching");
249 249
      check(e == mm.matching(graph.v(e)), "Wrong matching");
250 250
      ++num;
251 251
    }
252 252
    check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
253 253
          mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
254 254
          "Wrong Gallai-Edmonds decomposition");
255 255

	
256 256
    check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
257 257
          mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
258 258
          "Wrong Gallai-Edmonds decomposition");
259 259

	
260 260
    if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
261 261
        mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
262 262
      comp.join(graph.u(e), graph.v(e));
263 263
    }
264 264
  }
265 265

	
266 266
  std::set<int> comp_root;
267 267
  int odd_comp_num = 0;
268 268
  for (NodeIt n(graph); n != INVALID; ++n) {
269 269
    if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
270 270
      int root = comp.find(n);
271 271
      if (comp_root.find(root) == comp_root.end()) {
272 272
        comp_root.insert(root);
273 273
        if (comp.size(n) % 2 == 1) {
274 274
          ++odd_comp_num;
275 275
        }
276 276
      }
277 277
    }
278 278
  }
279 279

	
280 280
  check(mm.matchingSize() == num, "Wrong matching");
281 281
  check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
282 282
         "Wrong matching");
283 283
  return;
284 284
}
285 285

	
286 286
void checkWeightedMatching(const SmartGraph& graph,
287 287
                   const SmartGraph::EdgeMap<int>& weight,
288 288
                   const MaxWeightedMatching<SmartGraph>& mwm) {
289 289
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
290 290
    if (graph.u(e) == graph.v(e)) continue;
291 291
    int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
292 292

	
293 293
    for (int i = 0; i < mwm.blossomNum(); ++i) {
294 294
      bool s = false, t = false;
295 295
      for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
296 296
           n != INVALID; ++n) {
297 297
        if (graph.u(e) == n) s = true;
298 298
        if (graph.v(e) == n) t = true;
299 299
      }
300 300
      if (s == true && t == true) {
301 301
        rw += mwm.blossomValue(i);
302 302
      }
303 303
    }
304 304
    rw -= weight[e] * mwm.dualScale;
305 305

	
306 306
    check(rw >= 0, "Negative reduced weight");
307 307
    check(rw == 0 || !mwm.matching(e),
308 308
          "Non-zero reduced weight on matching edge");
309 309
  }
310 310

	
311 311
  int pv = 0;
312 312
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
313 313
    if (mwm.matching(n) != INVALID) {
314 314
      check(mwm.nodeValue(n) >= 0, "Invalid node value");
315 315
      pv += weight[mwm.matching(n)];
316 316
      SmartGraph::Node o = graph.target(mwm.matching(n));
317 317
      check(mwm.mate(n) == o, "Invalid matching");
318 318
      check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
319 319
            "Invalid matching");
320 320
    } else {
321 321
      check(mwm.mate(n) == INVALID, "Invalid matching");
322 322
      check(mwm.nodeValue(n) == 0, "Invalid matching");
323 323
    }
324 324
  }
325 325

	
326 326
  int dv = 0;
327 327
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
328 328
    dv += mwm.nodeValue(n);
329 329
  }
330 330

	
331 331
  for (int i = 0; i < mwm.blossomNum(); ++i) {
332 332
    check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
333 333
    check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
334 334
    dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
335 335
  }
336 336

	
337 337
  check(pv * mwm.dualScale == dv * 2, "Wrong duality");
338 338

	
339 339
  return;
340 340
}
341 341

	
342 342
void checkWeightedPerfectMatching(const SmartGraph& graph,
343 343
                          const SmartGraph::EdgeMap<int>& weight,
344 344
                          const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
345 345
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
346 346
    if (graph.u(e) == graph.v(e)) continue;
347 347
    int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
348 348

	
349 349
    for (int i = 0; i < mwpm.blossomNum(); ++i) {
350 350
      bool s = false, t = false;
351 351
      for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
352 352
           n != INVALID; ++n) {
353 353
        if (graph.u(e) == n) s = true;
354 354
        if (graph.v(e) == n) t = true;
355 355
      }
356 356
      if (s == true && t == true) {
357 357
        rw += mwpm.blossomValue(i);
358 358
      }
359 359
    }
360 360
    rw -= weight[e] * mwpm.dualScale;
361 361

	
362 362
    check(rw >= 0, "Negative reduced weight");
363 363
    check(rw == 0 || !mwpm.matching(e),
364 364
          "Non-zero reduced weight on matching edge");
365 365
  }
366 366

	
367 367
  int pv = 0;
368 368
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
369 369
    check(mwpm.matching(n) != INVALID, "Non perfect");
370 370
    pv += weight[mwpm.matching(n)];
371 371
    SmartGraph::Node o = graph.target(mwpm.matching(n));
372 372
    check(mwpm.mate(n) == o, "Invalid matching");
373 373
    check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
374 374
          "Invalid matching");
375 375
  }
376 376

	
377 377
  int dv = 0;
378 378
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
379 379
    dv += mwpm.nodeValue(n);
380 380
  }
381 381

	
382 382
  for (int i = 0; i < mwpm.blossomNum(); ++i) {
383 383
    check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
384 384
    check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
385 385
    dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
386 386
  }
387 387

	
388 388
  check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
389 389

	
390 390
  return;
391 391
}
392 392

	
393 393

	
394 394
int main() {
395 395

	
396 396
  for (int i = 0; i < lgfn; ++i) {
397 397
    SmartGraph graph;
398 398
    SmartGraph::EdgeMap<int> weight(graph);
399 399

	
400 400
    istringstream lgfs(lgf[i]);
401 401
    graphReader(graph, lgfs).
402 402
      edgeMap("weight", weight).run();
403 403

	
404 404
    MaxMatching<SmartGraph> mm(graph);
405 405
    mm.run();
406 406
    checkMatching(graph, mm);
407 407

	
408 408
    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
409 409
    mwm.run();
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
///\ingroup tools
20 20
///\file
21 21
///\brief DIMACS problem solver.
22 22
///
23 23
/// This program solves various problems given in DIMACS format.
24 24
///
25 25
/// See
26 26
/// \code
27 27
///   dimacs-solver --help
28 28
/// \endcode
29 29
/// for more info on usage.
30 30

	
31 31
#include <iostream>
32 32
#include <fstream>
33 33
#include <cstring>
34 34

	
35 35
#include <lemon/smart_graph.h>
36 36
#include <lemon/dimacs.h>
37 37
#include <lemon/lgf_writer.h>
38 38
#include <lemon/time_measure.h>
39 39

	
40 40
#include <lemon/arg_parser.h>
41 41
#include <lemon/error.h>
42 42

	
43 43
#include <lemon/dijkstra.h>
44 44
#include <lemon/preflow.h>
45
#include <lemon/max_matching.h>
45
#include <lemon/matching.h>
46 46

	
47 47
using namespace lemon;
48 48
typedef SmartDigraph Digraph;
49 49
DIGRAPH_TYPEDEFS(Digraph);
50 50
typedef SmartGraph Graph;
51 51

	
52 52
template<class Value>
53 53
void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
54 54
              DimacsDescriptor &desc)
55 55
{
56 56
  bool report = !ap.given("q");
57 57
  Digraph g;
58 58
  Node s;
59 59
  Digraph::ArcMap<Value> len(g);
60 60
  Timer t;
61 61
  t.restart();
62 62
  readDimacsSp(is, g, len, s, desc);
63 63
  if(report) std::cerr << "Read the file: " << t << '\n';
64 64
  t.restart();
65 65
  Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
66 66
  if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
67 67
  t.restart();
68 68
  dij.run(s);
69 69
  if(report) std::cerr << "Run Dijkstra: " << t << '\n';
70 70
}
71 71

	
72 72
template<class Value>
73 73
void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
74 74
               Value infty, DimacsDescriptor &desc)
75 75
{
76 76
  bool report = !ap.given("q");
77 77
  Digraph g;
78 78
  Node s,t;
79 79
  Digraph::ArcMap<Value> cap(g);
80 80
  Timer ti;
81 81
  ti.restart();
82 82
  readDimacsMax(is, g, cap, s, t, infty, desc);
83 83
  if(report) std::cerr << "Read the file: " << ti << '\n';
84 84
  ti.restart();
85 85
  Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
86 86
  if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
87 87
  ti.restart();
88 88
  pre.run();
89 89
  if(report) std::cerr << "Run Preflow: " << ti << '\n';
90 90
  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
91 91
}
92 92

	
93 93
void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
94 94
              DimacsDescriptor &desc)
95 95
{
96 96
  bool report = !ap.given("q");
97 97
  Graph g;
98 98
  Timer ti;
99 99
  ti.restart();
100 100
  readDimacsMat(is, g, desc);
101 101
  if(report) std::cerr << "Read the file: " << ti << '\n';
102 102
  ti.restart();
103 103
  MaxMatching<Graph> mat(g);
104 104
  if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
105 105
  ti.restart();
106 106
  mat.run();
107 107
  if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
108 108
  if(report) std::cerr << "\nCardinality of max matching: "
109 109
                       << mat.matchingSize() << '\n';  
110 110
}
111 111

	
112 112

	
113 113
template<class Value>
114 114
void solve(ArgParser &ap, std::istream &is, std::ostream &os,
115 115
           DimacsDescriptor &desc)
116 116
{
117 117
  std::stringstream iss(static_cast<std::string>(ap["infcap"]));
118 118
  Value infty;
119 119
  iss >> infty;
120 120
  if(iss.fail())
121 121
    {
122 122
      std::cerr << "Cannot interpret '"
123 123
                << static_cast<std::string>(ap["infcap"]) << "' as infinite"
124 124
                << std::endl;
125 125
      exit(1);
126 126
    }
127 127
  
128 128
  switch(desc.type)
129 129
    {
130 130
    case DimacsDescriptor::MIN:
131 131
      std::cerr <<
132 132
        "\n\n Sorry, the min. cost flow solver is not yet available.\n";
133 133
      break;
134 134
    case DimacsDescriptor::MAX:
135 135
      solve_max<Value>(ap,is,os,infty,desc);
136 136
      break;
137 137
    case DimacsDescriptor::SP:
138 138
      solve_sp<Value>(ap,is,os,desc);
139 139
      break;
140 140
    case DimacsDescriptor::MAT:
141 141
      solve_mat(ap,is,os,desc);
142 142
      break;
143 143
    default:
144 144
      break;
145 145
    }
146 146
}
147 147

	
148 148
int main(int argc, const char *argv[]) {
149 149
  typedef SmartDigraph Digraph;
150 150

	
151 151
  typedef Digraph::Arc Arc;
152 152

	
153 153
  std::string inputName;
154 154
  std::string outputName;
155 155

	
156 156
  ArgParser ap(argc, argv);
157 157
  ap.other("[INFILE [OUTFILE]]",
158 158
           "If either the INFILE or OUTFILE file is missing the standard\n"
159 159
           "     input/output will be used instead.")
160 160
    .boolOption("q", "Do not print any report")
161 161
    .boolOption("int","Use 'int' for capacities, costs etc. (default)")
162 162
    .optionGroup("datatype","int")
163 163
#ifdef HAVE_LONG_LONG
164 164
    .boolOption("long","Use 'long long' for capacities, costs etc.")
165 165
    .optionGroup("datatype","long")
166 166
#endif
167 167
    .boolOption("double","Use 'double' for capacities, costs etc.")
168 168
    .optionGroup("datatype","double")
169 169
    .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
170 170
    .optionGroup("datatype","ldouble")
171 171
    .onlyOneGroup("datatype")
172 172
    .stringOption("infcap","Value used for 'very high' capacities","0")
173 173
    .run();
174 174

	
175 175
  std::ifstream input;
176 176
  std::ofstream output;
177 177

	
178 178
  switch(ap.files().size())
179 179
    {
180 180
    case 2:
181 181
      output.open(ap.files()[1].c_str());
182 182
      if (!output) {
183 183
        throw IoError("Cannot open the file for writing", ap.files()[1]);
184 184
      }
185 185
    case 1:
186 186
      input.open(ap.files()[0].c_str());
187 187
      if (!input) {
188 188
        throw IoError("File cannot be found", ap.files()[0]);
189 189
      }
190 190
    case 0:
191 191
      break;
192 192
    default:
193 193
      std::cerr << ap.commandName() << ": too many arguments\n";
194 194
      return 1;
195 195
    }
196 196
  std::istream& is = (ap.files().size()<1 ? std::cin : input);
197 197
  std::ostream& os = (ap.files().size()<2 ? std::cout : output);
198 198

	
199 199
  DimacsDescriptor desc = dimacsType(is);
200 200
  
201 201
  if(!ap.given("q"))
202 202
    {
203 203
      std::cout << "Problem type: ";
204 204
      switch(desc.type)
205 205
        {
206 206
        case DimacsDescriptor::MIN:
207 207
          std::cout << "min";
208 208
          break;
209 209
        case DimacsDescriptor::MAX:
210 210
          std::cout << "max";
211 211
          break;
212 212
        case DimacsDescriptor::SP:
213 213
          std::cout << "sp";
214 214
        case DimacsDescriptor::MAT:
215 215
          std::cout << "mat";
216 216
          break;
217 217
        default:
218 218
          exit(1);
219 219
          break;
220 220
        }
221 221
      std::cout << "\nNum of nodes: " << desc.nodeNum;
222 222
      std::cout << "\nNum of arcs:  " << desc.edgeNum;
223 223
      std::cout << "\n\n";
224 224
    }
225 225
    
226 226
  if(ap.given("double"))
227 227
    solve<double>(ap,is,os,desc);
228 228
  else if(ap.given("ldouble"))
229 229
    solve<long double>(ap,is,os,desc);
230 230
#ifdef HAVE_LONG_LONG
231 231
  else if(ap.given("long"))
232 232
    solve<long long>(ap,is,os,desc);
233 233
#endif
234 234
  else solve<int>(ap,is,os,desc);
235 235

	
236 236
  return 0;
237 237
}
0 comments (0 inline)