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