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