test/min_cost_flow_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 24 Mar 2009 00:18:25 +0100
changeset 596 8c3112a66878
child 597 5232721b3f14
permissions -rw-r--r--
Use XTI implementation instead of ATI in NetworkSimplex (#234)

XTI (eXtended Threaded Index) is an imporved version of the widely
known ATI (Augmented Threaded Index) method for storing and updating
the spanning tree structure in Network Simplex algorithms.

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