test/min_cost_flow_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 24 Feb 2009 09:46:02 +0100
changeset 648 e8349c6f12ca
child 652 5232721b3f14
permissions -rw-r--r--
Port NetworkSimplex from SVN -r3520 (#234)
kpeter@648
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
kpeter@648
     2
 *
kpeter@648
     3
 * This file is a part of LEMON, a generic C++ optimization library.
kpeter@648
     4
 *
kpeter@648
     5
 * Copyright (C) 2003-2009
kpeter@648
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@648
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@648
     8
 *
kpeter@648
     9
 * Permission to use, modify and distribute this software is granted
kpeter@648
    10
 * provided that this copyright notice appears in all copies. For
kpeter@648
    11
 * precise terms see the accompanying LICENSE file.
kpeter@648
    12
 *
kpeter@648
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@648
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@648
    15
 * purpose.
kpeter@648
    16
 *
kpeter@648
    17
 */
kpeter@648
    18
kpeter@648
    19
#include <iostream>
kpeter@648
    20
#include <fstream>
kpeter@648
    21
kpeter@648
    22
#include <lemon/list_graph.h>
kpeter@648
    23
#include <lemon/smart_graph.h>
kpeter@648
    24
#include <lemon/lgf_reader.h>
kpeter@648
    25
kpeter@648
    26
//#include <lemon/cycle_canceling.h>
kpeter@648
    27
//#include <lemon/capacity_scaling.h>
kpeter@648
    28
//#include <lemon/cost_scaling.h>
kpeter@648
    29
#include <lemon/network_simplex.h>
kpeter@648
    30
//#include <lemon/min_cost_flow.h>
kpeter@648
    31
//#include <lemon/min_cost_max_flow.h>
kpeter@648
    32
kpeter@648
    33
#include <lemon/concepts/digraph.h>
kpeter@648
    34
#include <lemon/concept_check.h>
kpeter@648
    35
kpeter@648
    36
#include "test_tools.h"
kpeter@648
    37
kpeter@648
    38
using namespace lemon;
kpeter@648
    39
kpeter@648
    40
char test_lgf[] =
kpeter@648
    41
  "@nodes\n"
kpeter@648
    42
  "label  sup1 sup2 sup3\n"
kpeter@648
    43
  "    1    20   27    0\n"
kpeter@648
    44
  "    2    -4    0    0\n"
kpeter@648
    45
  "    3     0    0    0\n"
kpeter@648
    46
  "    4     0    0    0\n"
kpeter@648
    47
  "    5     9    0    0\n"
kpeter@648
    48
  "    6    -6    0    0\n"
kpeter@648
    49
  "    7     0    0    0\n"
kpeter@648
    50
  "    8     0    0    0\n"
kpeter@648
    51
  "    9     3    0    0\n"
kpeter@648
    52
  "   10    -2    0    0\n"
kpeter@648
    53
  "   11     0    0    0\n"
kpeter@648
    54
  "   12   -20  -27    0\n"
kpeter@648
    55
  "\n"
kpeter@648
    56
  "@arcs\n"
kpeter@648
    57
  "       cost  cap low1 low2\n"
kpeter@648
    58
  " 1  2    70   11    0    8\n"
kpeter@648
    59
  " 1  3   150    3    0    1\n"
kpeter@648
    60
  " 1  4    80   15    0    2\n"
kpeter@648
    61
  " 2  8    80   12    0    0\n"
kpeter@648
    62
  " 3  5   140    5    0    3\n"
kpeter@648
    63
  " 4  6    60   10    0    1\n"
kpeter@648
    64
  " 4  7    80    2    0    0\n"
kpeter@648
    65
  " 4  8   110    3    0    0\n"
kpeter@648
    66
  " 5  7    60   14    0    0\n"
kpeter@648
    67
  " 5 11   120   12    0    0\n"
kpeter@648
    68
  " 6  3     0    3    0    0\n"
kpeter@648
    69
  " 6  9   140    4    0    0\n"
kpeter@648
    70
  " 6 10    90    8    0    0\n"
kpeter@648
    71
  " 7  1    30    5    0    0\n"
kpeter@648
    72
  " 8 12    60   16    0    4\n"
kpeter@648
    73
  " 9 12    50    6    0    0\n"
kpeter@648
    74
  "10 12    70   13    0    5\n"
kpeter@648
    75
  "10  2   100    7    0    0\n"
kpeter@648
    76
  "10  7    60   10    0    0\n"
kpeter@648
    77
  "11 10    20   14    0    6\n"
kpeter@648
    78
  "12 11    30   10    0    0\n"
kpeter@648
    79
  "\n"
kpeter@648
    80
  "@attributes\n"
kpeter@648
    81
  "source 1\n"
kpeter@648
    82
  "target 12\n";
kpeter@648
    83
kpeter@648
    84
kpeter@648
    85
// Check the interface of an MCF algorithm
kpeter@648
    86
template <typename GR, typename Value>
kpeter@648
    87
class McfClassConcept
kpeter@648
    88
{
kpeter@648
    89
public:
kpeter@648
    90
kpeter@648
    91
  template <typename MCF>
kpeter@648
    92
  struct Constraints {
kpeter@648
    93
    void constraints() {
kpeter@648
    94
      checkConcept<concepts::Digraph, GR>();
kpeter@648
    95
kpeter@648
    96
      MCF mcf_test1(g, lower, upper, cost, sup);
kpeter@648
    97
      MCF mcf_test2(g, upper, cost, sup);
kpeter@648
    98
      MCF mcf_test3(g, lower, upper, cost, n, n, k);
kpeter@648
    99
      MCF mcf_test4(g, upper, cost, n, n, k);
kpeter@648
   100
kpeter@648
   101
      // TODO: This part should be enabled and the next part
kpeter@648
   102
      // should be removed if map copying is supported
kpeter@648
   103
/*
kpeter@648
   104
      flow = mcf_test1.flowMap();
kpeter@648
   105
      mcf_test1.flowMap(flow);
kpeter@648
   106
kpeter@648
   107
      pot = mcf_test1.potentialMap();
kpeter@648
   108
      mcf_test1.potentialMap(pot);
kpeter@648
   109
*/
kpeter@648
   110
/**/
kpeter@648
   111
      const typename MCF::FlowMap &fm =
kpeter@648
   112
        mcf_test1.flowMap();
kpeter@648
   113
      mcf_test1.flowMap(flow);
kpeter@648
   114
      const typename MCF::PotentialMap &pm =
kpeter@648
   115
        mcf_test1.potentialMap();
kpeter@648
   116
      mcf_test1.potentialMap(pot);
kpeter@648
   117
      ignore_unused_variable_warning(fm);
kpeter@648
   118
      ignore_unused_variable_warning(pm);
kpeter@648
   119
/**/
kpeter@648
   120
kpeter@648
   121
      mcf_test1.run();
kpeter@648
   122
kpeter@648
   123
      v = mcf_test1.totalCost();
kpeter@648
   124
      v = mcf_test1.flow(a);
kpeter@648
   125
      v = mcf_test1.potential(n);
kpeter@648
   126
    }
kpeter@648
   127
kpeter@648
   128
    typedef typename GR::Node Node;
kpeter@648
   129
    typedef typename GR::Arc Arc;
kpeter@648
   130
    typedef concepts::ReadMap<Node, Value> NM;
kpeter@648
   131
    typedef concepts::ReadMap<Arc, Value> AM;
kpeter@648
   132
kpeter@648
   133
    const GR &g;
kpeter@648
   134
    const AM &lower;
kpeter@648
   135
    const AM &upper;
kpeter@648
   136
    const AM &cost;
kpeter@648
   137
    const NM &sup;
kpeter@648
   138
    const Node &n;
kpeter@648
   139
    const Arc &a;
kpeter@648
   140
    const Value &k;
kpeter@648
   141
    Value v;
kpeter@648
   142
kpeter@648
   143
    typename MCF::FlowMap &flow;
kpeter@648
   144
    typename MCF::PotentialMap &pot;
kpeter@648
   145
  };
kpeter@648
   146
kpeter@648
   147
};
kpeter@648
   148
kpeter@648
   149
kpeter@648
   150
// Check the feasibility of the given flow (primal soluiton)
kpeter@648
   151
template < typename GR, typename LM, typename UM,
kpeter@648
   152
           typename SM, typename FM >
kpeter@648
   153
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
kpeter@648
   154
                const SM& supply, const FM& flow )
kpeter@648
   155
{
kpeter@648
   156
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
kpeter@648
   157
kpeter@648
   158
  for (ArcIt e(gr); e != INVALID; ++e) {
kpeter@648
   159
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
kpeter@648
   160
  }
kpeter@648
   161
kpeter@648
   162
  for (NodeIt n(gr); n != INVALID; ++n) {
kpeter@648
   163
    typename SM::Value sum = 0;
kpeter@648
   164
    for (OutArcIt e(gr, n); e != INVALID; ++e)
kpeter@648
   165
      sum += flow[e];
kpeter@648
   166
    for (InArcIt e(gr, n); e != INVALID; ++e)
kpeter@648
   167
      sum -= flow[e];
kpeter@648
   168
    if (sum != supply[n]) return false;
kpeter@648
   169
  }
kpeter@648
   170
kpeter@648
   171
  return true;
kpeter@648
   172
}
kpeter@648
   173
kpeter@648
   174
// Check the feasibility of the given potentials (dual soluiton)
kpeter@648
   175
// using the Complementary Slackness optimality condition
kpeter@648
   176
template < typename GR, typename LM, typename UM,
kpeter@648
   177
           typename CM, typename FM, typename PM >
kpeter@648
   178
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
kpeter@648
   179
                     const CM& cost, const FM& flow, const PM& pi )
kpeter@648
   180
{
kpeter@648
   181
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
kpeter@648
   182
kpeter@648
   183
  bool opt = true;
kpeter@648
   184
  for (ArcIt e(gr); opt && e != INVALID; ++e) {
kpeter@648
   185
    typename CM::Value red_cost =
kpeter@648
   186
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
kpeter@648
   187
    opt = red_cost == 0 ||
kpeter@648
   188
          (red_cost > 0 && flow[e] == lower[e]) ||
kpeter@648
   189
          (red_cost < 0 && flow[e] == upper[e]);
kpeter@648
   190
  }
kpeter@648
   191
  return opt;
kpeter@648
   192
}
kpeter@648
   193
kpeter@648
   194
// Run a minimum cost flow algorithm and check the results
kpeter@648
   195
template < typename MCF, typename GR,
kpeter@648
   196
           typename LM, typename UM,
kpeter@648
   197
           typename CM, typename SM >
kpeter@648
   198
void checkMcf( const MCF& mcf, bool mcf_result,
kpeter@648
   199
               const GR& gr, const LM& lower, const UM& upper,
kpeter@648
   200
               const CM& cost, const SM& supply,
kpeter@648
   201
               bool result, typename CM::Value total,
kpeter@648
   202
               const std::string &test_id = "" )
kpeter@648
   203
{
kpeter@648
   204
  check(mcf_result == result, "Wrong result " + test_id);
kpeter@648
   205
  if (result) {
kpeter@648
   206
    check(checkFlow(gr, lower, upper, supply, mcf.flowMap()),
kpeter@648
   207
          "The flow is not feasible " + test_id);
kpeter@648
   208
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
kpeter@648
   209
    check(checkPotential(gr, lower, upper, cost, mcf.flowMap(),
kpeter@648
   210
                         mcf.potentialMap()),
kpeter@648
   211
          "Wrong potentials " + test_id);
kpeter@648
   212
  }
kpeter@648
   213
}
kpeter@648
   214
kpeter@648
   215
int main()
kpeter@648
   216
{
kpeter@648
   217
  // Check the interfaces
kpeter@648
   218
  {
kpeter@648
   219
    typedef int Value;
kpeter@648
   220
    // This typedef should be enabled if the standard maps are
kpeter@648
   221
    // reference maps in the graph concepts
kpeter@648
   222
    //typedef concepts::Digraph GR;
kpeter@648
   223
    typedef ListDigraph GR;
kpeter@648
   224
    typedef concepts::ReadMap<GR::Node, Value> NM;
kpeter@648
   225
    typedef concepts::ReadMap<GR::Arc, Value> AM;
kpeter@648
   226
kpeter@648
   227
    //checkConcept< McfClassConcept<GR, Value>,
kpeter@648
   228
    //              CycleCanceling<GR, AM, AM, AM, NM> >();
kpeter@648
   229
    //checkConcept< McfClassConcept<GR, Value>,
kpeter@648
   230
    //              CapacityScaling<GR, AM, AM, AM, NM> >();
kpeter@648
   231
    //checkConcept< McfClassConcept<GR, Value>,
kpeter@648
   232
    //              CostScaling<GR, AM, AM, AM, NM> >();
kpeter@648
   233
    checkConcept< McfClassConcept<GR, Value>,
kpeter@648
   234
                  NetworkSimplex<GR, AM, AM, AM, NM> >();
kpeter@648
   235
    //checkConcept< MinCostFlow<GR, Value>,
kpeter@648
   236
    //              NetworkSimplex<GR, AM, AM, AM, NM> >();
kpeter@648
   237
  }
kpeter@648
   238
kpeter@648
   239
  // Run various MCF tests
kpeter@648
   240
  typedef ListDigraph Digraph;
kpeter@648
   241
  DIGRAPH_TYPEDEFS(ListDigraph);
kpeter@648
   242
kpeter@648
   243
  // Read the test digraph
kpeter@648
   244
  Digraph gr;
kpeter@648
   245
  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), u(gr);
kpeter@648
   246
  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr);
kpeter@648
   247
  Node v, w;
kpeter@648
   248
kpeter@648
   249
  std::istringstream input(test_lgf);
kpeter@648
   250
  DigraphReader<Digraph>(gr, input)
kpeter@648
   251
    .arcMap("cost", c)
kpeter@648
   252
    .arcMap("cap", u)
kpeter@648
   253
    .arcMap("low1", l1)
kpeter@648
   254
    .arcMap("low2", l2)
kpeter@648
   255
    .nodeMap("sup1", s1)
kpeter@648
   256
    .nodeMap("sup2", s2)
kpeter@648
   257
    .nodeMap("sup3", s3)
kpeter@648
   258
    .node("source", v)
kpeter@648
   259
    .node("target", w)
kpeter@648
   260
    .run();
kpeter@648
   261
kpeter@648
   262
/*
kpeter@648
   263
  // A. Test CapacityScaling with scaling
kpeter@648
   264
  {
kpeter@648
   265
    CapacityScaling<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   266
    CapacityScaling<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   267
    CapacityScaling<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   268
    CapacityScaling<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   269
    CapacityScaling<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   270
    CapacityScaling<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   271
kpeter@648
   272
    checkMcf(mcf1, mcf1.run(), gr, l1, u, c, s1, true,  5240, "#A1");
kpeter@648
   273
    checkMcf(mcf2, mcf2.run(), gr, l1, u, c, s2, true,  7620, "#A2");
kpeter@648
   274
    checkMcf(mcf3, mcf3.run(), gr, l1, u, c, s3, true,     0, "#A3");
kpeter@648
   275
    checkMcf(mcf4, mcf4.run(), gr, l2, u, c, s1, true,  5970, "#A4");
kpeter@648
   276
    checkMcf(mcf5, mcf5.run(), gr, l2, u, c, s2, true,  8010, "#A5");
kpeter@648
   277
    checkMcf(mcf6, mcf6.run(), gr, l2, u, c, s3, false,    0, "#A6");
kpeter@648
   278
  }
kpeter@648
   279
kpeter@648
   280
  // B. Test CapacityScaling without scaling
kpeter@648
   281
  {
kpeter@648
   282
    CapacityScaling<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   283
    CapacityScaling<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   284
    CapacityScaling<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   285
    CapacityScaling<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   286
    CapacityScaling<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   287
    CapacityScaling<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   288
kpeter@648
   289
    checkMcf(mcf1, mcf1.run(false), gr, l1, u, c, s1, true,  5240, "#B1");
kpeter@648
   290
    checkMcf(mcf2, mcf2.run(false), gr, l1, u, c, s2, true,  7620, "#B2");
kpeter@648
   291
    checkMcf(mcf3, mcf3.run(false), gr, l1, u, c, s3, true,     0, "#B3");
kpeter@648
   292
    checkMcf(mcf4, mcf4.run(false), gr, l2, u, c, s1, true,  5970, "#B4");
kpeter@648
   293
    checkMcf(mcf5, mcf5.run(false), gr, l2, u, c, s2, true,  8010, "#B5");
kpeter@648
   294
    checkMcf(mcf6, mcf6.run(false), gr, l2, u, c, s3, false,    0, "#B6");
kpeter@648
   295
  }
kpeter@648
   296
kpeter@648
   297
  // C. Test CostScaling using partial augment-relabel method
kpeter@648
   298
  {
kpeter@648
   299
    CostScaling<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   300
    CostScaling<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   301
    CostScaling<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   302
    CostScaling<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   303
    CostScaling<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   304
    CostScaling<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   305
kpeter@648
   306
    checkMcf(mcf1, mcf1.run(), gr, l1, u, c, s1, true,  5240, "#C1");
kpeter@648
   307
    checkMcf(mcf2, mcf2.run(), gr, l1, u, c, s2, true,  7620, "#C2");
kpeter@648
   308
    checkMcf(mcf3, mcf3.run(), gr, l1, u, c, s3, true,     0, "#C3");
kpeter@648
   309
    checkMcf(mcf4, mcf4.run(), gr, l2, u, c, s1, true,  5970, "#C4");
kpeter@648
   310
    checkMcf(mcf5, mcf5.run(), gr, l2, u, c, s2, true,  8010, "#C5");
kpeter@648
   311
    checkMcf(mcf6, mcf6.run(), gr, l2, u, c, s3, false,    0, "#C6");
kpeter@648
   312
  }
kpeter@648
   313
kpeter@648
   314
  // D. Test CostScaling using push-relabel method
kpeter@648
   315
  {
kpeter@648
   316
    CostScaling<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   317
    CostScaling<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   318
    CostScaling<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   319
    CostScaling<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   320
    CostScaling<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   321
    CostScaling<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   322
kpeter@648
   323
    checkMcf(mcf1, mcf1.run(false), gr, l1, u, c, s1, true,  5240, "#D1");
kpeter@648
   324
    checkMcf(mcf2, mcf2.run(false), gr, l1, u, c, s2, true,  7620, "#D2");
kpeter@648
   325
    checkMcf(mcf3, mcf3.run(false), gr, l1, u, c, s3, true,     0, "#D3");
kpeter@648
   326
    checkMcf(mcf4, mcf4.run(false), gr, l2, u, c, s1, true,  5970, "#D4");
kpeter@648
   327
    checkMcf(mcf5, mcf5.run(false), gr, l2, u, c, s2, true,  8010, "#D5");
kpeter@648
   328
    checkMcf(mcf6, mcf6.run(false), gr, l2, u, c, s3, false,    0, "#D6");
kpeter@648
   329
  }
kpeter@648
   330
*/
kpeter@648
   331
kpeter@648
   332
  // E. Test NetworkSimplex with FIRST_ELIGIBLE_PIVOT
kpeter@648
   333
  {
kpeter@648
   334
    NetworkSimplex<Digraph>::PivotRuleEnum pr =
kpeter@648
   335
      NetworkSimplex<Digraph>::FIRST_ELIGIBLE_PIVOT;
kpeter@648
   336
    NetworkSimplex<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   337
    NetworkSimplex<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   338
    NetworkSimplex<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   339
    NetworkSimplex<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   340
    NetworkSimplex<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   341
    NetworkSimplex<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   342
kpeter@648
   343
    checkMcf(mcf1, mcf1.run(pr), gr, l1, u, c, s1, true,  5240, "#E1");
kpeter@648
   344
    checkMcf(mcf2, mcf2.run(pr), gr, l1, u, c, s2, true,  7620, "#E2");
kpeter@648
   345
    checkMcf(mcf3, mcf3.run(pr), gr, l1, u, c, s3, true,     0, "#E3");
kpeter@648
   346
    checkMcf(mcf4, mcf4.run(pr), gr, l2, u, c, s1, true,  5970, "#E4");
kpeter@648
   347
    checkMcf(mcf5, mcf5.run(pr), gr, l2, u, c, s2, true,  8010, "#E5");
kpeter@648
   348
    checkMcf(mcf6, mcf6.run(pr), gr, l2, u, c, s3, false,    0, "#E6");
kpeter@648
   349
  }
kpeter@648
   350
kpeter@648
   351
  // F. Test NetworkSimplex with BEST_ELIGIBLE_PIVOT
kpeter@648
   352
  {
kpeter@648
   353
    NetworkSimplex<Digraph>::PivotRuleEnum pr =
kpeter@648
   354
      NetworkSimplex<Digraph>::BEST_ELIGIBLE_PIVOT;
kpeter@648
   355
    NetworkSimplex<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   356
    NetworkSimplex<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   357
    NetworkSimplex<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   358
    NetworkSimplex<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   359
    NetworkSimplex<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   360
    NetworkSimplex<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   361
kpeter@648
   362
    checkMcf(mcf1, mcf1.run(pr), gr, l1, u, c, s1, true,  5240, "#F1");
kpeter@648
   363
    checkMcf(mcf2, mcf2.run(pr), gr, l1, u, c, s2, true,  7620, "#F2");
kpeter@648
   364
    checkMcf(mcf3, mcf3.run(pr), gr, l1, u, c, s3, true,     0, "#F3");
kpeter@648
   365
    checkMcf(mcf4, mcf4.run(pr), gr, l2, u, c, s1, true,  5970, "#F4");
kpeter@648
   366
    checkMcf(mcf5, mcf5.run(pr), gr, l2, u, c, s2, true,  8010, "#F5");
kpeter@648
   367
    checkMcf(mcf6, mcf6.run(pr), gr, l2, u, c, s3, false,    0, "#F6");
kpeter@648
   368
  }
kpeter@648
   369
kpeter@648
   370
  // G. Test NetworkSimplex with BLOCK_SEARCH_PIVOT
kpeter@648
   371
  {
kpeter@648
   372
    NetworkSimplex<Digraph>::PivotRuleEnum pr =
kpeter@648
   373
      NetworkSimplex<Digraph>::BLOCK_SEARCH_PIVOT;
kpeter@648
   374
    NetworkSimplex<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   375
    NetworkSimplex<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   376
    NetworkSimplex<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   377
    NetworkSimplex<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   378
    NetworkSimplex<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   379
    NetworkSimplex<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   380
kpeter@648
   381
    checkMcf(mcf1, mcf1.run(pr), gr, l1, u, c, s1, true,  5240, "#G1");
kpeter@648
   382
    checkMcf(mcf2, mcf2.run(pr), gr, l1, u, c, s2, true,  7620, "#G2");
kpeter@648
   383
    checkMcf(mcf3, mcf3.run(pr), gr, l1, u, c, s3, true,     0, "#G3");
kpeter@648
   384
    checkMcf(mcf4, mcf4.run(pr), gr, l2, u, c, s1, true,  5970, "#G4");
kpeter@648
   385
    checkMcf(mcf5, mcf5.run(pr), gr, l2, u, c, s2, true,  8010, "#G5");
kpeter@648
   386
    checkMcf(mcf6, mcf6.run(pr), gr, l2, u, c, s3, false,    0, "#G6");
kpeter@648
   387
  }
kpeter@648
   388
kpeter@648
   389
  // H. Test NetworkSimplex with CANDIDATE_LIST_PIVOT
kpeter@648
   390
  {
kpeter@648
   391
    NetworkSimplex<Digraph>::PivotRuleEnum pr =
kpeter@648
   392
      NetworkSimplex<Digraph>::CANDIDATE_LIST_PIVOT;
kpeter@648
   393
    NetworkSimplex<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   394
    NetworkSimplex<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   395
    NetworkSimplex<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   396
    NetworkSimplex<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   397
    NetworkSimplex<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   398
    NetworkSimplex<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   399
kpeter@648
   400
    checkMcf(mcf1, mcf1.run(pr), gr, l1, u, c, s1, true,  5240, "#H1");
kpeter@648
   401
    checkMcf(mcf2, mcf2.run(pr), gr, l1, u, c, s2, true,  7620, "#H2");
kpeter@648
   402
    checkMcf(mcf3, mcf3.run(pr), gr, l1, u, c, s3, true,     0, "#H3");
kpeter@648
   403
    checkMcf(mcf4, mcf4.run(pr), gr, l2, u, c, s1, true,  5970, "#H4");
kpeter@648
   404
    checkMcf(mcf5, mcf5.run(pr), gr, l2, u, c, s2, true,  8010, "#H5");
kpeter@648
   405
    checkMcf(mcf6, mcf6.run(pr), gr, l2, u, c, s3, false,    0, "#H6");
kpeter@648
   406
  }
kpeter@648
   407
kpeter@648
   408
  // I. Test NetworkSimplex with ALTERING_LIST_PIVOT
kpeter@648
   409
  {
kpeter@648
   410
    NetworkSimplex<Digraph>::PivotRuleEnum pr =
kpeter@648
   411
      NetworkSimplex<Digraph>::ALTERING_LIST_PIVOT;
kpeter@648
   412
    NetworkSimplex<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   413
    NetworkSimplex<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   414
    NetworkSimplex<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   415
    NetworkSimplex<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   416
    NetworkSimplex<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   417
    NetworkSimplex<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   418
kpeter@648
   419
    checkMcf(mcf1, mcf1.run(pr), gr, l1, u, c, s1, true,  5240, "#I1");
kpeter@648
   420
    checkMcf(mcf2, mcf2.run(pr), gr, l1, u, c, s2, true,  7620, "#I2");
kpeter@648
   421
    checkMcf(mcf3, mcf3.run(pr), gr, l1, u, c, s3, true,     0, "#I3");
kpeter@648
   422
    checkMcf(mcf4, mcf4.run(pr), gr, l2, u, c, s1, true,  5970, "#I4");
kpeter@648
   423
    checkMcf(mcf5, mcf5.run(pr), gr, l2, u, c, s2, true,  8010, "#I5");
kpeter@648
   424
    checkMcf(mcf6, mcf6.run(pr), gr, l2, u, c, s3, false,    0, "#I6");
kpeter@648
   425
  }
kpeter@648
   426
kpeter@648
   427
/*
kpeter@648
   428
  // J. Test MinCostFlow
kpeter@648
   429
  {
kpeter@648
   430
    MinCostFlow<Digraph> mcf1(gr, u, c, s1);
kpeter@648
   431
    MinCostFlow<Digraph> mcf2(gr, u, c, v, w, 27);
kpeter@648
   432
    MinCostFlow<Digraph> mcf3(gr, u, c, s3);
kpeter@648
   433
    MinCostFlow<Digraph> mcf4(gr, l2, u, c, s1);
kpeter@648
   434
    MinCostFlow<Digraph> mcf5(gr, l2, u, c, v, w, 27);
kpeter@648
   435
    MinCostFlow<Digraph> mcf6(gr, l2, u, c, s3);
kpeter@648
   436
kpeter@648
   437
    checkMcf(mcf1, mcf1.run(), gr, l1, u, c, s1, true,  5240, "#J1");
kpeter@648
   438
    checkMcf(mcf2, mcf2.run(), gr, l1, u, c, s2, true,  7620, "#J2");
kpeter@648
   439
    checkMcf(mcf3, mcf3.run(), gr, l1, u, c, s3, true,     0, "#J3");
kpeter@648
   440
    checkMcf(mcf4, mcf4.run(), gr, l2, u, c, s1, true,  5970, "#J4");
kpeter@648
   441
    checkMcf(mcf5, mcf5.run(), gr, l2, u, c, s2, true,  8010, "#J5");
kpeter@648
   442
    checkMcf(mcf6, mcf6.run(), gr, l2, u, c, s3, false,    0, "#J6");
kpeter@648
   443
  }
kpeter@648
   444
*/
kpeter@648
   445
/*
kpeter@648
   446
  // K. Test MinCostMaxFlow
kpeter@648
   447
  {
kpeter@648
   448
    MinCostMaxFlow<Digraph> mcmf(gr, u, c, v, w);
kpeter@648
   449
    mcmf.run();
kpeter@648
   450
    checkMcf(mcmf, true, gr, l1, u, c, s3, true, 7620, "#K1");
kpeter@648
   451
  }
kpeter@648
   452
*/
kpeter@648
   453
kpeter@648
   454
  return 0;
kpeter@648
   455
}