gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Adds tests for the new MCF algorithms (#180)
0 1 0
default
1 file changed with 66 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 1536 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 <fstream>
21 21
#include <limits>
22 22

	
23 23
#include <lemon/list_graph.h>
24 24
#include <lemon/lgf_reader.h>
25 25

	
26 26
#include <lemon/network_simplex.h>
27
#include <lemon/capacity_scaling.h>
28
#include <lemon/cost_scaling.h>
29
#include <lemon/cycle_canceling.h>
27 30

	
28 31
#include <lemon/concepts/digraph.h>
32
#include <lemon/concepts/heap.h>
29 33
#include <lemon/concept_check.h>
30 34

	
31 35
#include "test_tools.h"
32 36

	
33 37
using namespace lemon;
34 38

	
35 39
// Test networks
36 40
char test_lgf[] =
37 41
  "@nodes\n"
38 42
  "label  sup1 sup2 sup3 sup4 sup5 sup6\n"
39 43
  "    1    20   27    0   30   20   30\n"
40 44
  "    2    -4    0    0    0   -8   -3\n"
41 45
  "    3     0    0    0    0    0    0\n"
42 46
  "    4     0    0    0    0    0    0\n"
43 47
  "    5     9    0    0    0    6   11\n"
44 48
  "    6    -6    0    0    0   -5   -6\n"
45 49
  "    7     0    0    0    0    0    0\n"
46 50
  "    8     0    0    0    0    0    3\n"
47 51
  "    9     3    0    0    0    0    0\n"
48 52
  "   10    -2    0    0    0   -7   -2\n"
49 53
  "   11     0    0    0    0  -10    0\n"
50 54
  "   12   -20  -27    0  -30  -30  -20\n"
51 55
  "\n"                
52 56
  "@arcs\n"
53 57
  "       cost  cap low1 low2 low3\n"
54 58
  " 1  2    70   11    0    8    8\n"
55 59
  " 1  3   150    3    0    1    0\n"
56 60
  " 1  4    80   15    0    2    2\n"
57 61
  " 2  8    80   12    0    0    0\n"
58 62
  " 3  5   140    5    0    3    1\n"
59 63
  " 4  6    60   10    0    1    0\n"
60 64
  " 4  7    80    2    0    0    0\n"
61 65
  " 4  8   110    3    0    0    0\n"
62 66
  " 5  7    60   14    0    0    0\n"
63 67
  " 5 11   120   12    0    0    0\n"
64 68
  " 6  3     0    3    0    0    0\n"
65 69
  " 6  9   140    4    0    0    0\n"
66 70
  " 6 10    90    8    0    0    0\n"
67 71
  " 7  1    30    5    0    0   -5\n"
68 72
  " 8 12    60   16    0    4    3\n"
69 73
  " 9 12    50    6    0    0    0\n"
70 74
  "10 12    70   13    0    5    2\n"
71 75
  "10  2   100    7    0    0    0\n"
72 76
  "10  7    60   10    0    0   -3\n"
73 77
  "11 10    20   14    0    6  -20\n"
74 78
  "12 11    30   10    0    0  -10\n"
75 79
  "\n"
76 80
  "@attributes\n"
77 81
  "source 1\n"
78 82
  "target 12\n";
79 83

	
80 84
char test_neg1_lgf[] =
81 85
  "@nodes\n"
82 86
  "label   sup\n"
83 87
  "    1   100\n"
84 88
  "    2     0\n"
85 89
  "    3     0\n"
86 90
  "    4  -100\n"
87 91
  "    5     0\n"
88 92
  "    6     0\n"
89 93
  "    7     0\n"
90 94
  "@arcs\n"
91 95
  "      cost   low1   low2\n"
92 96
  "1 2    100      0      0\n"
93 97
  "1 3     30      0      0\n"
94 98
  "2 4     20      0      0\n"
95 99
  "3 4     80      0      0\n"
96 100
  "3 2     50      0      0\n"
97 101
  "5 3     10      0      0\n"
98 102
  "5 6     80      0   1000\n"
99 103
  "6 7     30      0  -1000\n"
100 104
  "7 5   -120      0      0\n";
101 105
  
102 106
char test_neg2_lgf[] =
103 107
  "@nodes\n"
104 108
  "label   sup\n"
105 109
  "    1   100\n"
106 110
  "    2  -300\n"
107 111
  "@arcs\n"
108 112
  "      cost\n"
109 113
  "1 2     -1\n";
110 114

	
111 115

	
112 116
// Test data
113 117
typedef ListDigraph Digraph;
114 118
DIGRAPH_TYPEDEFS(ListDigraph);
115 119

	
116 120
Digraph gr;
117 121
Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
118 122
Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
119 123
ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
120 124
Node v, w;
121 125

	
122 126
Digraph neg1_gr;
123 127
Digraph::ArcMap<int> neg1_c(neg1_gr), neg1_l1(neg1_gr), neg1_l2(neg1_gr);
124 128
ConstMap<Arc, int> neg1_u1(std::numeric_limits<int>::max()), neg1_u2(5000);
125 129
Digraph::NodeMap<int> neg1_s(neg1_gr);
126 130

	
127 131
Digraph neg2_gr;
128 132
Digraph::ArcMap<int> neg2_c(neg2_gr);
129 133
ConstMap<Arc, int> neg2_l(0), neg2_u(1000);
130 134
Digraph::NodeMap<int> neg2_s(neg2_gr);
131 135

	
132 136

	
133 137
enum SupplyType {
134 138
  EQ,
135 139
  GEQ,
136 140
  LEQ
137 141
};
138 142

	
139 143

	
140 144
// Check the interface of an MCF algorithm
141 145
template <typename GR, typename Value, typename Cost>
142 146
class McfClassConcept
143 147
{
144 148
public:
145 149

	
146 150
  template <typename MCF>
147 151
  struct Constraints {
148 152
    void constraints() {
149 153
      checkConcept<concepts::Digraph, GR>();
150 154
      
151 155
      const Constraints& me = *this;
152 156

	
153 157
      MCF mcf(me.g);
154 158
      const MCF& const_mcf = mcf;
155 159

	
156 160
      b = mcf.reset()
157 161
             .lowerMap(me.lower)
158 162
             .upperMap(me.upper)
159 163
             .costMap(me.cost)
160 164
             .supplyMap(me.sup)
161 165
             .stSupply(me.n, me.n, me.k)
162 166
             .run();
163 167

	
164 168
      c = const_mcf.totalCost();
165 169
      x = const_mcf.template totalCost<double>();
166 170
      v = const_mcf.flow(me.a);
167 171
      c = const_mcf.potential(me.n);
168 172
      const_mcf.flowMap(fm);
169 173
      const_mcf.potentialMap(pm);
170 174
    }
171 175

	
172 176
    typedef typename GR::Node Node;
173 177
    typedef typename GR::Arc Arc;
174 178
    typedef concepts::ReadMap<Node, Value> NM;
175 179
    typedef concepts::ReadMap<Arc, Value> VAM;
176 180
    typedef concepts::ReadMap<Arc, Cost> CAM;
177 181
    typedef concepts::WriteMap<Arc, Value> FlowMap;
178 182
    typedef concepts::WriteMap<Node, Cost> PotMap;
179 183
  
180 184
    GR g;
181 185
    VAM lower;
182 186
    VAM upper;
183 187
    CAM cost;
184 188
    NM sup;
185 189
    Node n;
186 190
    Arc a;
187 191
    Value k;
188 192

	
189 193
    FlowMap fm;
190 194
    PotMap pm;
191 195
    bool b;
192 196
    double x;
193 197
    typename MCF::Value v;
194 198
    typename MCF::Cost c;
195 199
  };
196 200

	
197 201
};
198 202

	
199 203

	
200 204
// Check the feasibility of the given flow (primal soluiton)
201 205
template < typename GR, typename LM, typename UM,
202 206
           typename SM, typename FM >
203 207
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
204 208
                const SM& supply, const FM& flow,
205 209
                SupplyType type = EQ )
206 210
{
207 211
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
208 212

	
209 213
  for (ArcIt e(gr); e != INVALID; ++e) {
210 214
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
211 215
  }
212 216

	
213 217
  for (NodeIt n(gr); n != INVALID; ++n) {
214 218
    typename SM::Value sum = 0;
215 219
    for (OutArcIt e(gr, n); e != INVALID; ++e)
216 220
      sum += flow[e];
217 221
    for (InArcIt e(gr, n); e != INVALID; ++e)
218 222
      sum -= flow[e];
219 223
    bool b = (type ==  EQ && sum == supply[n]) ||
220 224
             (type == GEQ && sum >= supply[n]) ||
221 225
             (type == LEQ && sum <= supply[n]);
222 226
    if (!b) return false;
223 227
  }
224 228

	
225 229
  return true;
226 230
}
227 231

	
228 232
// Check the feasibility of the given potentials (dual soluiton)
229 233
// using the "Complementary Slackness" optimality condition
230 234
template < typename GR, typename LM, typename UM,
231 235
           typename CM, typename SM, typename FM, typename PM >
232 236
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
233 237
                     const CM& cost, const SM& supply, const FM& flow, 
234 238
                     const PM& pi, SupplyType type )
235 239
{
236 240
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
237 241

	
238 242
  bool opt = true;
239 243
  for (ArcIt e(gr); opt && e != INVALID; ++e) {
240 244
    typename CM::Value red_cost =
241 245
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
242 246
    opt = red_cost == 0 ||
243 247
          (red_cost > 0 && flow[e] == lower[e]) ||
244 248
          (red_cost < 0 && flow[e] == upper[e]);
245 249
  }
246 250
  
247 251
  for (NodeIt n(gr); opt && n != INVALID; ++n) {
248 252
    typename SM::Value sum = 0;
249 253
    for (OutArcIt e(gr, n); e != INVALID; ++e)
250 254
      sum += flow[e];
251 255
    for (InArcIt e(gr, n); e != INVALID; ++e)
252 256
      sum -= flow[e];
253 257
    if (type != LEQ) {
254 258
      opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
255 259
    } else {
256 260
      opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
257 261
    }
258 262
  }
259 263
  
260 264
  return opt;
261 265
}
262 266

	
263 267
// Check whether the dual cost is equal to the primal cost
264 268
template < typename GR, typename LM, typename UM,
265 269
           typename CM, typename SM, typename PM >
266 270
bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
267 271
                    const CM& cost, const SM& supply, const PM& pi,
268 272
                    typename CM::Value total )
269 273
{
270 274
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
271 275

	
272 276
  typename CM::Value dual_cost = 0;
273 277
  SM red_supply(gr);
274 278
  for (NodeIt n(gr); n != INVALID; ++n) {
275 279
    red_supply[n] = supply[n];
276 280
  }
277 281
  for (ArcIt a(gr); a != INVALID; ++a) {
278 282
    if (lower[a] != 0) {
279 283
      dual_cost += lower[a] * cost[a];
280 284
      red_supply[gr.source(a)] -= lower[a];
281 285
      red_supply[gr.target(a)] += lower[a];
282 286
    }
283 287
  }
284 288
  
285 289
  for (NodeIt n(gr); n != INVALID; ++n) {
286 290
    dual_cost -= red_supply[n] * pi[n];
287 291
  }
288 292
  for (ArcIt a(gr); a != INVALID; ++a) {
289 293
    typename CM::Value red_cost =
290 294
      cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
291 295
    dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
292 296
  }
293 297
  
294 298
  return dual_cost == total;
295 299
}
296 300

	
297 301
// Run a minimum cost flow algorithm and check the results
298 302
template < typename MCF, typename GR,
299 303
           typename LM, typename UM,
300 304
           typename CM, typename SM,
301 305
           typename PT >
302 306
void checkMcf( const MCF& mcf, PT mcf_result,
303 307
               const GR& gr, const LM& lower, const UM& upper,
304 308
               const CM& cost, const SM& supply,
305 309
               PT result, bool optimal, typename CM::Value total,
306 310
               const std::string &test_id = "",
307 311
               SupplyType type = EQ )
308 312
{
309 313
  check(mcf_result == result, "Wrong result " + test_id);
310 314
  if (optimal) {
311 315
    typename GR::template ArcMap<typename SM::Value> flow(gr);
312 316
    typename GR::template NodeMap<typename CM::Value> pi(gr);
313 317
    mcf.flowMap(flow);
314 318
    mcf.potentialMap(pi);
315 319
    check(checkFlow(gr, lower, upper, supply, flow, type),
316 320
          "The flow is not feasible " + test_id);
317 321
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
318 322
    check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
319 323
          "Wrong potentials " + test_id);
320 324
    check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
321 325
          "Wrong dual cost " + test_id);
322 326
  }
323 327
}
324 328

	
325 329
template < typename MCF, typename Param >
326 330
void runMcfGeqTests( Param param,
327 331
                     const std::string &test_str = "",
328 332
                     bool full_neg_cost_support = false )
329 333
{
330 334
  MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr);
331 335
  
332 336
  // Basic tests
333 337
  mcf1.upperMap(u).costMap(c).supplyMap(s1);
334 338
  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s1,
335 339
           mcf1.OPTIMAL, true,     5240, test_str + "-1");
336 340
  mcf1.stSupply(v, w, 27);
337 341
  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s2,
338 342
           mcf1.OPTIMAL, true,     7620, test_str + "-2");
339 343
  mcf1.lowerMap(l2).supplyMap(s1);
340 344
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s1,
341 345
           mcf1.OPTIMAL, true,     5970, test_str + "-3");
342 346
  mcf1.stSupply(v, w, 27);
343 347
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s2,
344 348
           mcf1.OPTIMAL, true,     8010, test_str + "-4");
345 349
  mcf1.reset().supplyMap(s1);
346 350
  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s1,
347 351
           mcf1.OPTIMAL, true,       74, test_str + "-5");
348 352
  mcf1.lowerMap(l2).stSupply(v, w, 27);
349 353
  checkMcf(mcf1, mcf1.run(param), gr, l2, cu, cc, s2,
350 354
           mcf1.OPTIMAL, true,       94, test_str + "-6");
351 355
  mcf1.reset();
352 356
  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s3,
353 357
           mcf1.OPTIMAL, true,        0, test_str + "-7");
354 358
  mcf1.lowerMap(l2).upperMap(u);
355 359
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, cc, s3,
356 360
           mcf1.INFEASIBLE, false,    0, test_str + "-8");
357 361
  mcf1.lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
358 362
  checkMcf(mcf1, mcf1.run(param), gr, l3, u, c, s4,
359 363
           mcf1.OPTIMAL, true,     6360, test_str + "-9");
360 364

	
361 365
  // Tests for the GEQ form
362 366
  mcf1.reset().upperMap(u).costMap(c).supplyMap(s5);
363 367
  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s5,
364 368
           mcf1.OPTIMAL, true,     3530, test_str + "-10", GEQ);
365 369
  mcf1.lowerMap(l2);
366 370
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
367 371
           mcf1.OPTIMAL, true,     4540, test_str + "-11", GEQ);
368 372
  mcf1.supplyMap(s6);
369 373
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
370 374
           mcf1.INFEASIBLE, false,    0, test_str + "-12", GEQ);
371 375

	
372 376
  // Tests with negative costs
373 377
  mcf2.lowerMap(neg1_l1).costMap(neg1_c).supplyMap(neg1_s);
374 378
  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u1, neg1_c, neg1_s,
375 379
           mcf2.UNBOUNDED, false,     0, test_str + "-13");
376 380
  mcf2.upperMap(neg1_u2);
377 381
  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u2, neg1_c, neg1_s,
378 382
           mcf2.OPTIMAL, true,   -40000, test_str + "-14");
379 383
  mcf2.reset().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s);
380 384
  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l2, neg1_u1, neg1_c, neg1_s,
381 385
           mcf2.UNBOUNDED, false,     0, test_str + "-15");
382 386

	
383 387
  mcf3.costMap(neg2_c).supplyMap(neg2_s);
384 388
  if (full_neg_cost_support) {
385 389
    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
386 390
             mcf3.OPTIMAL, true,   -300, test_str + "-16", GEQ);
387 391
  } else {
388 392
    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
389 393
             mcf3.UNBOUNDED, false,   0, test_str + "-17", GEQ);
390 394
  }
391 395
  mcf3.upperMap(neg2_u);
392 396
  checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
393 397
           mcf3.OPTIMAL, true,     -300, test_str + "-18", GEQ);
394 398
}
395 399

	
396 400
template < typename MCF, typename Param >
397 401
void runMcfLeqTests( Param param,
398 402
                     const std::string &test_str = "" )
399 403
{
400 404
  // Tests for the LEQ form
401 405
  MCF mcf1(gr);
402 406
  mcf1.supplyType(mcf1.LEQ);
403 407
  mcf1.upperMap(u).costMap(c).supplyMap(s6);
404 408
  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s6,
405 409
           mcf1.OPTIMAL, true,   5080, test_str + "-19", LEQ);
406 410
  mcf1.lowerMap(l2);
407 411
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
408 412
           mcf1.OPTIMAL, true,   5930, test_str + "-20", LEQ);
409 413
  mcf1.supplyMap(s5);
410 414
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
411 415
           mcf1.INFEASIBLE, false,  0, test_str + "-21", LEQ);
412 416
}
413 417

	
414 418

	
415 419
int main()
416 420
{
417 421
  // Read the test networks
418 422
  std::istringstream input(test_lgf);
419 423
  DigraphReader<Digraph>(gr, input)
420 424
    .arcMap("cost", c)
421 425
    .arcMap("cap", u)
422 426
    .arcMap("low1", l1)
423 427
    .arcMap("low2", l2)
424 428
    .arcMap("low3", l3)
425 429
    .nodeMap("sup1", s1)
426 430
    .nodeMap("sup2", s2)
427 431
    .nodeMap("sup3", s3)
428 432
    .nodeMap("sup4", s4)
429 433
    .nodeMap("sup5", s5)
430 434
    .nodeMap("sup6", s6)
431 435
    .node("source", v)
432 436
    .node("target", w)
433 437
    .run();
434 438
  
435 439
  std::istringstream neg_inp1(test_neg1_lgf);
436 440
  DigraphReader<Digraph>(neg1_gr, neg_inp1)
437 441
    .arcMap("cost", neg1_c)
438 442
    .arcMap("low1", neg1_l1)
439 443
    .arcMap("low2", neg1_l2)
440 444
    .nodeMap("sup", neg1_s)
441 445
    .run();
442 446
  
443 447
  std::istringstream neg_inp2(test_neg2_lgf);
444 448
  DigraphReader<Digraph>(neg2_gr, neg_inp2)
445 449
    .arcMap("cost", neg2_c)
446 450
    .nodeMap("sup", neg2_s)
447 451
    .run();
448 452
  
449 453
  // Check the interface of NetworkSimplex
450 454
  {
451 455
    typedef concepts::Digraph GR;
452 456
    checkConcept< McfClassConcept<GR, int, int>,
453 457
                  NetworkSimplex<GR> >();
454 458
    checkConcept< McfClassConcept<GR, double, double>,
455 459
                  NetworkSimplex<GR, double> >();
456 460
    checkConcept< McfClassConcept<GR, int, double>,
457 461
                  NetworkSimplex<GR, int, double> >();
458 462
  }
459 463

	
464
  // Check the interface of CapacityScaling
465
  {
466
    typedef concepts::Digraph GR;
467
    checkConcept< McfClassConcept<GR, int, int>,
468
                  CapacityScaling<GR> >();
469
    checkConcept< McfClassConcept<GR, double, double>,
470
                  CapacityScaling<GR, double> >();
471
    checkConcept< McfClassConcept<GR, int, double>,
472
                  CapacityScaling<GR, int, double> >();
473
    typedef CapacityScaling<GR>::
474
      SetHeap<concepts::Heap<int, RangeMap<int> > >::Create CAS;
475
    checkConcept< McfClassConcept<GR, int, int>, CAS >();
476
  }
477

	
478
  // Check the interface of CostScaling
479
  {
480
    typedef concepts::Digraph GR;
481
    checkConcept< McfClassConcept<GR, int, int>,
482
                  CostScaling<GR> >();
483
    checkConcept< McfClassConcept<GR, double, double>,
484
                  CostScaling<GR, double> >();
485
    checkConcept< McfClassConcept<GR, int, double>,
486
                  CostScaling<GR, int, double> >();
487
    typedef CostScaling<GR>::
488
      SetLargeCost<double>::Create COS;
489
    checkConcept< McfClassConcept<GR, int, int>, COS >();
490
  }
491

	
492
  // Check the interface of CycleCanceling
493
  {
494
    typedef concepts::Digraph GR;
495
    checkConcept< McfClassConcept<GR, int, int>,
496
                  CycleCanceling<GR> >();
497
    checkConcept< McfClassConcept<GR, double, double>,
498
                  CycleCanceling<GR, double> >();
499
    checkConcept< McfClassConcept<GR, int, double>,
500
                  CycleCanceling<GR, int, double> >();
501
  }
502

	
460 503
  // Test NetworkSimplex
461 504
  { 
462 505
    typedef NetworkSimplex<Digraph> MCF;
463 506
    runMcfGeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE", true);
464 507
    runMcfLeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE");
465 508
    runMcfGeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE", true);
466 509
    runMcfLeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE");
467 510
    runMcfGeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS", true);
468 511
    runMcfLeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS");
469 512
    runMcfGeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL", true);
470 513
    runMcfLeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL");
471 514
    runMcfGeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL", true);
472 515
    runMcfLeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL");
473 516
  }
517
  
518
  // Test CapacityScaling
519
  {
520
    typedef CapacityScaling<Digraph> MCF;
521
    runMcfGeqTests<MCF>(0, "SSP");
522
    runMcfGeqTests<MCF>(2, "CAS");
523
  }
524

	
525
  // Test CostScaling
526
  {
527
    typedef CostScaling<Digraph> MCF;
528
    runMcfGeqTests<MCF>(MCF::PUSH, "COS-PR");
529
    runMcfGeqTests<MCF>(MCF::AUGMENT, "COS-AR");
530
    runMcfGeqTests<MCF>(MCF::PARTIAL_AUGMENT, "COS-PAR");
531
  }
532

	
533
  // Test CycleCanceling
534
  {
535
    typedef CycleCanceling<Digraph> MCF;
536
    runMcfGeqTests<MCF>(MCF::SIMPLE_CYCLE_CANCELING, "SCC");
537
    runMcfGeqTests<MCF>(MCF::MINIMUM_MEAN_CYCLE_CANCELING, "MMCC");
538
    runMcfGeqTests<MCF>(MCF::CANCEL_AND_TIGHTEN, "CAT");
539
  }
474 540

	
475 541
  return 0;
476 542
}
0 comments (0 inline)