test/min_cost_flow_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 24 Mar 2009 00:18:25 +0100
changeset 651 8c3112a66878
child 652 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@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
}