gravatar
tapolcai@tmit.bme.hu
tapolcai@tmit.bme.hu
Porting Gomory-Hu algorithm (#66)
0 3 2
default
5 files changed with 387 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
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
#ifndef LEMON_GOMORY_HU_TREE_H
20
#define LEMON_GOMORY_HU_TREE_H
21

	
22
#include <limits>
23

	
24
#include <lemon/preflow.h>
25
#include <lemon/concept_check.h>
26
#include <lemon/concepts/maps.h>
27

	
28
/// \ingroup min_cut
29
/// \file 
30
/// \brief Gomory-Hu cut tree in graphs.
31

	
32
namespace lemon {
33

	
34
  /// \ingroup min_cut
35
  ///
36
  /// \brief Gomory-Hu cut tree algorithm
37
  ///
38
  /// The Gomory-Hu tree is a tree on the nodeset of the digraph, but it
39
  /// may contain arcs which are not in the original digraph. It helps
40
  /// to calculate the minimum cut between all pairs of nodes, because
41
  /// the minimum capacity arc on the tree path between two nodes has
42
  /// the same weight as the minimum cut in the digraph between these
43
  /// nodes. Moreover this arc separates the nodes to two parts which
44
  /// determine this minimum cut.
45
  /// 
46
  /// The algorithm calculates \e n-1 distinict minimum cuts with
47
  /// preflow algorithm, therefore the algorithm has
48
  /// \f$(O(n^3\sqrt{e})\f$ overall time complexity. It calculates a
49
  /// rooted Gomory-Hu tree, the structure of the tree and the weights
50
  /// can be obtained with \c predNode() and \c predValue()
51
  /// functions. The \c minCutValue() and \c minCutMap() calculates
52
  /// the minimum cut and the minimum cut value between any two node
53
  /// in the digraph.
54
  template <typename _Graph, 
55
	    typename _Capacity = typename _Graph::template EdgeMap<int> >
56
  class GomoryHuTree {
57
  public:
58

	
59
    /// The graph type
60
    typedef _Graph Graph;
61
    /// The capacity on edges
62
    typedef _Capacity Capacity;
63
    /// The value type of capacities
64
    typedef typename Capacity::Value Value;
65
    
66
  private:
67

	
68
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
69

	
70
    const Graph& _graph;
71
    const Capacity& _capacity;
72

	
73
    Node _root;
74
    typename Graph::template NodeMap<Node>* _pred;
75
    typename Graph::template NodeMap<Value>* _weight;
76
    typename Graph::template NodeMap<int>* _order;
77

	
78
    void createStructures() {
79
      if (!_pred) {
80
	_pred = new typename Graph::template NodeMap<Node>(_graph);
81
      }
82
      if (!_weight) {
83
	_weight = new typename Graph::template NodeMap<Value>(_graph);
84
      }
85
      if (!_order) {
86
	_order = new typename Graph::template NodeMap<int>(_graph);
87
      }
88
    }
89

	
90
    void destroyStructures() {
91
      if (_pred) {
92
	delete _pred;
93
      }
94
      if (_weight) {
95
	delete _weight;
96
      }
97
      if (_order) {
98
	delete _order;
99
      }
100
    }
101
  
102
  public:
103

	
104
    /// \brief Constructor
105
    ///
106
    /// Constructor
107
    /// \param graph The graph type.
108
    /// \param capacity The capacity map.
109
    GomoryHuTree(const Graph& graph, const Capacity& capacity) 
110
      : _graph(graph), _capacity(capacity),
111
	_pred(0), _weight(0), _order(0) 
112
    {
113
      checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
114
    }
115

	
116

	
117
    /// \brief Destructor
118
    ///
119
    /// Destructor
120
    ~GomoryHuTree() {
121
      destroyStructures();
122
    }
123

	
124
    /// \brief Initializes the internal data structures.
125
    ///
126
    /// Initializes the internal data structures.
127
    ///
128
    void init() {
129
      createStructures();
130

	
131
      _root = NodeIt(_graph);
132
      for (NodeIt n(_graph); n != INVALID; ++n) {
133
	_pred->set(n, _root);
134
	_order->set(n, -1);
135
      }
136
      _pred->set(_root, INVALID);
137
      _weight->set(_root, std::numeric_limits<Value>::max()); 
138
    }
139

	
140

	
141
    /// \brief Starts the algorithm
142
    ///
143
    /// Starts the algorithm.
144
    void start() {
145
      Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
146

	
147
      for (NodeIt n(_graph); n != INVALID; ++n) {
148
	if (n == _root) continue;
149

	
150
	Node pn = (*_pred)[n];
151
	fa.source(n);
152
	fa.target(pn);
153

	
154
	fa.runMinCut();
155

	
156
	_weight->set(n, fa.flowValue());
157

	
158
	for (NodeIt nn(_graph); nn != INVALID; ++nn) {
159
	  if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
160
	    _pred->set(nn, n);
161
	  }
162
	}
163
	if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
164
	  _pred->set(n, (*_pred)[pn]);
165
	  _pred->set(pn, n);
166
	  _weight->set(n, (*_weight)[pn]);
167
	  _weight->set(pn, fa.flowValue());	
168
	}
169
      }
170

	
171
      _order->set(_root, 0);
172
      int index = 1;
173

	
174
      for (NodeIt n(_graph); n != INVALID; ++n) {
175
	std::vector<Node> st;
176
	Node nn = n;
177
	while ((*_order)[nn] == -1) {
178
	  st.push_back(nn);
179
	  nn = (*_pred)[nn];
180
	}
181
	while (!st.empty()) {
182
	  _order->set(st.back(), index++);
183
	  st.pop_back();
184
	}
185
      }
186
    }
187

	
188
    /// \brief Runs the Gomory-Hu algorithm.  
189
    ///
190
    /// Runs the Gomory-Hu algorithm.
191
    /// \note gh.run() is just a shortcut of the following code.
192
    /// \code
193
    ///   ght.init();
194
    ///   ght.start();
195
    /// \endcode
196
    void run() {
197
      init();
198
      start();
199
    }
200

	
201
    /// \brief Returns the predecessor node in the Gomory-Hu tree.
202
    ///
203
    /// Returns the predecessor node in the Gomory-Hu tree. If the node is
204
    /// the root of the Gomory-Hu tree, then it returns \c INVALID.
205
    Node predNode(const Node& node) {
206
      return (*_pred)[node];
207
    }
208

	
209
    /// \brief Returns the weight of the predecessor arc in the
210
    /// Gomory-Hu tree.
211
    ///
212
    /// Returns the weight of the predecessor arc in the Gomory-Hu
213
    /// tree.  If the node is the root of the Gomory-Hu tree, the
214
    /// result is undefined.
215
    Value predValue(const Node& node) {
216
      return (*_weight)[node];
217
    }
218

	
219
    /// \brief Returns the minimum cut value between two nodes
220
    ///
221
    /// Returns the minimum cut value between two nodes. The
222
    /// algorithm finds the nearest common ancestor in the Gomory-Hu
223
    /// tree and calculates the minimum weight arc on the paths to
224
    /// the ancestor.
225
    Value minCutValue(const Node& s, const Node& t) const {
226
      Node sn = s, tn = t;
227
      Value value = std::numeric_limits<Value>::max();
228
      
229
      while (sn != tn) {
230
	if ((*_order)[sn] < (*_order)[tn]) {
231
	  if ((*_weight)[tn] < value) value = (*_weight)[tn];
232
	  tn = (*_pred)[tn];
233
	} else {
234
	  if ((*_weight)[sn] < value) value = (*_weight)[sn];
235
	  sn = (*_pred)[sn];
236
	}
237
      }
238
      return value;
239
    }
240

	
241
    /// \brief Returns the minimum cut between two nodes
242
    ///
243
    /// Returns the minimum cut value between two nodes. The
244
    /// algorithm finds the nearest common ancestor in the Gomory-Hu
245
    /// tree and calculates the minimum weight arc on the paths to
246
    /// the ancestor. Then it sets all nodes to the cut determined by
247
    /// this arc. The \c cutMap should be \ref concepts::ReadWriteMap
248
    /// "ReadWriteMap".
249
    template <typename CutMap>
250
    Value minCutMap(const Node& s, const Node& t, CutMap& cutMap) const {
251
      Node sn = s, tn = t;
252

	
253
      Node rn = INVALID;
254
      Value value = std::numeric_limits<Value>::max();
255
      
256
      while (sn != tn) {
257
	if ((*_order)[sn] < (*_order)[tn]) {
258
	  if ((*_weight)[tn] < value) {
259
	    rn = tn;
260
	    value = (*_weight)[tn];
261
	  }
262
	  tn = (*_pred)[tn];
263
	} else {
264
	  if ((*_weight)[sn] < value) {
265
	    rn = sn;
266
	    value = (*_weight)[sn];
267
	  }
268
	  sn = (*_pred)[sn];
269
	}
270
      }
271

	
272
      typename Graph::template NodeMap<bool> reached(_graph, false);
273
      reached.set(_root, true);
274
      cutMap.set(_root, false);
275
      reached.set(rn, true);
276
      cutMap.set(rn, true);
277

	
278
      for (NodeIt n(_graph); n != INVALID; ++n) {
279
	std::vector<Node> st;
280
	Node nn = n;
281
	while (!reached[nn]) {
282
	  st.push_back(nn);
283
	  nn = (*_pred)[nn];
284
	}
285
	while (!st.empty()) {
286
	  cutMap.set(st.back(), cutMap[nn]);
287
	  st.pop_back();
288
	}
289
      }
290
      
291
      return value;
292
    }
293

	
294
  };
295

	
296
}
297

	
298
#endif
Ignore white space 6 line context
1
#include <iostream>
2

	
3
#include "test_tools.h"
4
#include <lemon/smart_graph.h>
5
#include <lemon/adaptors.h>
6
#include <lemon/lgf_reader.h>
7
#include <lemon/lgf_writer.h>
8
#include <lemon/dimacs.h>
9
#include <lemon/time_measure.h>
10
#include <lemon/gomory_hu_tree.h>
11
#include <cstdlib>
12

	
13
using namespace std;
14
using namespace lemon;
15

	
16
typedef SmartGraph Graph;
17

	
18
char test_lgf[] =
19
  "@nodes\n"
20
  "label\n"
21
  "0\n"
22
  "1\n"
23
  "2\n"
24
  "3\n"
25
  "4\n"
26
  "@arcs\n"
27
  "     label capacity\n"
28
  "0 1  0     1\n"
29
  "1 2  1     1\n"
30
  "2 3  2     1\n"
31
  "0 3  4     5\n"
32
  "0 3  5     10\n"
33
  "0 3  6     7\n"
34
  "4 2  7     1\n"
35
  "@attributes\n"
36
  "source 0\n"
37
  "target 3\n";
38
  
39
GRAPH_TYPEDEFS(Graph);
40
typedef Graph::EdgeMap<int> IntEdgeMap;
41
typedef Graph::NodeMap<bool> BoolNodeMap;
42

	
43
int cutValue(const Graph& graph, const BoolNodeMap& cut,
44
	     const IntEdgeMap& capacity) {
45

	
46
  int sum = 0;
47
  for (EdgeIt e(graph); e != INVALID; ++e) {
48
    Node s = graph.u(e);
49
    Node t = graph.v(e);
50

	
51
    if (cut[s] != cut[t]) {
52
      sum += capacity[e];
53
    }
54
  }
55
  return sum;
56
}
57

	
58

	
59
int main() {
60
  Graph graph;
61
  IntEdgeMap capacity(graph);
62

	
63
  std::istringstream input(test_lgf);
64
  GraphReader<Graph>(graph, input).
65
    edgeMap("capacity", capacity).run();
66

	
67
  GomoryHuTree<Graph> ght(graph, capacity);
68
  ght.init();
69
  ght.run();
70

	
71
  for (NodeIt u(graph); u != INVALID; ++u) {
72
    for (NodeIt v(graph); v != u; ++v) {
73
      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
74
      pf.runMinCut();
75
      BoolNodeMap cm(graph);
76
      ght.minCutMap(u, v, cm);
77
      check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
78
      check(cm[u] != cm[v], "Wrong cut 3");
79
      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 2");
80
      
81
    }
82
  }
83
  
84
  return 0;
85
}
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
	$(GLPK_CFLAGS) \
21 21
	$(CPLEX_CFLAGS) \
22 22
	$(SOPLEX_CXXFLAGS) \
23 23
	$(CLP_CXXFLAGS)
24 24

	
25 25
lemon_libemon_la_LDFLAGS = \
26 26
	$(GLPK_LIBS) \
27 27
	$(CPLEX_LIBS) \
28 28
	$(SOPLEX_LIBS) \
29 29
	$(CLP_LIBS)
30 30

	
31 31
if HAVE_GLPK
32 32
lemon_libemon_la_SOURCES += lemon/glpk.cc
33 33
endif
34 34

	
35 35
if HAVE_CPLEX
36 36
lemon_libemon_la_SOURCES += lemon/cplex.cc
37 37
endif
38 38

	
39 39
if HAVE_SOPLEX
40 40
lemon_libemon_la_SOURCES += lemon/soplex.cc
41 41
endif
42 42

	
43 43
if HAVE_CLP
44 44
lemon_libemon_la_SOURCES += lemon/clp.cc
45 45
endif
46 46

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

	
100 101
bits_HEADERS += \
101 102
	lemon/bits/alteration_notifier.h \
102 103
	lemon/bits/array_map.h \
103 104
	lemon/bits/base_extender.h \
104 105
	lemon/bits/bezier.h \
105 106
	lemon/bits/default_map.h \
106 107
	lemon/bits/edge_set_extender.h \
107 108
	lemon/bits/enable_if.h \
108 109
	lemon/bits/graph_adaptor_extender.h \
109 110
	lemon/bits/graph_extender.h \
110 111
	lemon/bits/map_extender.h \
111 112
	lemon/bits/path_dump.h \
112 113
	lemon/bits/solver_bits.h \
113 114
	lemon/bits/traits.h \
114 115
	lemon/bits/variant.h \
115 116
	lemon/bits/vector_map.h
116 117

	
117 118
concept_HEADERS += \
118 119
	lemon/concepts/digraph.h \
119 120
	lemon/concepts/graph.h \
120 121
	lemon/concepts/graph_components.h \
121 122
	lemon/concepts/heap.h \
122 123
	lemon/concepts/maps.h \
123 124
	lemon/concepts/path.h
Ignore white space 6 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${CMAKE_SOURCE_DIR}
3 3
  ${CMAKE_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(${CMAKE_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
  gomory_hu_test
24 25
  graph_copy_test
25 26
  graph_test
26 27
  graph_utils_test
27 28
  hao_orlin_test
28 29
  heap_test
29 30
  kruskal_test
30 31
  maps_test
31 32
  max_matching_test
32 33
  min_cost_arborescence_test
33 34
  path_test
34 35
  preflow_test
35 36
  radix_sort_test
36 37
  random_test
37 38
  suurballe_test
38 39
  time_measure_test
39 40
  unionfind_test)
40 41

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

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

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

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

	
77 78
FOREACH(TEST_NAME ${TESTS})
78 79
  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
79 80
  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
80 81
  ADD_TEST(${TEST_NAME} ${TEST_NAME})
81 82
ENDFOREACH(TEST_NAME)
Ignore white space 1024 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
	test/gomory_hu_test \
20 21
	test/graph_copy_test \
21 22
	test/graph_test \
22 23
	test/graph_utils_test \
23 24
	test/hao_orlin_test \
24 25
	test/heap_test \
25 26
	test/kruskal_test \
26 27
	test/maps_test \
27 28
	test/max_matching_test \
28 29
	test/min_cost_arborescence_test \
29 30
	test/path_test \
30 31
	test/preflow_test \
31 32
	test/radix_sort_test \
32 33
	test/random_test \
33 34
	test/suurballe_test \
34 35
	test/test_tools_fail \
35 36
	test/test_tools_pass \
36 37
	test/time_measure_test \
37 38
	test/unionfind_test
38 39

	
39 40
if HAVE_LP
40 41
check_PROGRAMS += test/lp_test
41 42
endif HAVE_LP
42 43
if HAVE_MIP
43 44
check_PROGRAMS += test/mip_test
44 45
endif HAVE_MIP
45 46

	
46 47
TESTS += $(check_PROGRAMS)
47 48
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
48 49

	
49 50
test_adaptors_test_SOURCES = test/adaptors_test.cc
50 51
test_bfs_test_SOURCES = test/bfs_test.cc
51 52
test_circulation_test_SOURCES = test/circulation_test.cc
52 53
test_counter_test_SOURCES = test/counter_test.cc
53 54
test_dfs_test_SOURCES = test/dfs_test.cc
54 55
test_digraph_test_SOURCES = test/digraph_test.cc
55 56
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
56 57
test_dim_test_SOURCES = test/dim_test.cc
57 58
test_edge_set_test_SOURCES = test/edge_set_test.cc
58 59
test_error_test_SOURCES = test/error_test.cc
59 60
test_euler_test_SOURCES = test/euler_test.cc
61
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
60 62
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
61 63
test_graph_test_SOURCES = test/graph_test.cc
62 64
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
63 65
test_heap_test_SOURCES = test/heap_test.cc
64 66
test_kruskal_test_SOURCES = test/kruskal_test.cc
65 67
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
66 68
test_lp_test_SOURCES = test/lp_test.cc
67 69
test_maps_test_SOURCES = test/maps_test.cc
68 70
test_mip_test_SOURCES = test/mip_test.cc
69 71
test_max_matching_test_SOURCES = test/max_matching_test.cc
70 72
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
71 73
test_path_test_SOURCES = test/path_test.cc
72 74
test_preflow_test_SOURCES = test/preflow_test.cc
73 75
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
74 76
test_suurballe_test_SOURCES = test/suurballe_test.cc
75 77
test_random_test_SOURCES = test/random_test.cc
76 78
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
77 79
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
78 80
test_time_measure_test_SOURCES = test/time_measure_test.cc
79 81
test_unionfind_test_SOURCES = test/unionfind_test.cc
0 comments (0 inline)