test/min_cost_flow_test.cc
author alpar
Fri, 27 Jun 2008 06:37:14 +0000
changeset 2614 77bc9718ddd7
parent 2553 bfced05fa852
child 2621 814ba94d9989
permissions -rw-r--r--
Update the version number
alpar@906
     1
/* -*- C++ -*-
alpar@906
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@906
     8
 *
alpar@906
     9
 * Permission to use, modify and distribute this software is granted
alpar@906
    10
 * provided that this copyright notice appears in all copies. For
alpar@906
    11
 * precise terms see the accompanying LICENSE file.
alpar@906
    12
 *
alpar@906
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    14
 * express or implied, and with no claim as to its suitability for any
alpar@906
    15
 * purpose.
alpar@906
    16
 *
alpar@906
    17
 */
alpar@906
    18
alpar@899
    19
#include <iostream>
kpeter@2584
    20
#include <fstream>
kpeter@2584
    21
kpeter@2584
    22
#include <lemon/list_graph.h>
kpeter@2584
    23
#include <lemon/smart_graph.h>
kpeter@2584
    24
#include <lemon/graph_reader.h>
kpeter@2584
    25
#include <lemon/dimacs.h>
kpeter@2584
    26
#include <lemon/time_measure.h>
kpeter@2584
    27
kpeter@2584
    28
#include <lemon/cycle_canceling.h>
kpeter@2584
    29
#include <lemon/capacity_scaling.h>
kpeter@2584
    30
#include <lemon/cost_scaling.h>
kpeter@2584
    31
#include <lemon/network_simplex.h>
kpeter@2584
    32
kpeter@2584
    33
#include <lemon/min_cost_flow.h>
kpeter@2584
    34
#include <lemon/min_cost_max_flow.h>
kpeter@2584
    35
alpar@899
    36
#include "test_tools.h"
alpar@899
    37
alpar@921
    38
using namespace lemon;
alpar@899
    39
kpeter@2584
    40
// Checks the feasibility of a flow
kpeter@2584
    41
template < typename Graph, typename LowerMap, typename CapacityMap,
kpeter@2584
    42
           typename SupplyMap, typename FlowMap >
kpeter@2584
    43
bool checkFlow( const Graph& gr,
kpeter@2584
    44
                const LowerMap& lower, const CapacityMap& upper,
kpeter@2584
    45
                const SupplyMap& supply, const FlowMap& flow )
kpeter@2584
    46
{
kpeter@2584
    47
  GRAPH_TYPEDEFS(typename Graph);
kpeter@2584
    48
  for (EdgeIt e(gr); e != INVALID; ++e)
kpeter@2584
    49
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
alpar@899
    50
kpeter@2584
    51
  for (NodeIt n(gr); n != INVALID; ++n) {
kpeter@2584
    52
    typename SupplyMap::Value sum = 0;
kpeter@2584
    53
    for (OutEdgeIt e(gr, n); e != INVALID; ++e)
kpeter@2584
    54
      sum += flow[e];
kpeter@2584
    55
    for (InEdgeIt e(gr, n); e != INVALID; ++e)
kpeter@2584
    56
      sum -= flow[e];
kpeter@2584
    57
    if (sum != supply[n]) return false;
kpeter@2584
    58
  }
alpar@899
    59
kpeter@2584
    60
  return true;
kpeter@2584
    61
}
kpeter@2584
    62
kpeter@2584
    63
// Checks the optimalitiy of a flow
kpeter@2584
    64
template < typename Graph, typename LowerMap, typename CapacityMap,
kpeter@2584
    65
           typename CostMap, typename FlowMap, typename PotentialMap >
kpeter@2584
    66
bool checkOptimality( const Graph& gr, const LowerMap& lower,
kpeter@2584
    67
                      const CapacityMap& upper, const CostMap& cost,
kpeter@2584
    68
                      const FlowMap& flow, const PotentialMap& pi )
kpeter@2584
    69
{
kpeter@2584
    70
  GRAPH_TYPEDEFS(typename Graph);
kpeter@2584
    71
  // Checking the Complementary Slackness optimality condition
kpeter@2584
    72
  bool opt = true;
kpeter@2584
    73
  for (EdgeIt e(gr); e != INVALID; ++e) {
kpeter@2584
    74
    typename CostMap::Value red_cost =
kpeter@2584
    75
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
kpeter@2584
    76
    opt = red_cost == 0 ||
kpeter@2584
    77
          (red_cost > 0 && flow[e] == lower[e]) ||
kpeter@2584
    78
          (red_cost < 0 && flow[e] == upper[e]);
kpeter@2584
    79
    if (!opt) break;
kpeter@2584
    80
  }
kpeter@2584
    81
  return opt;
kpeter@2584
    82
}
kpeter@2584
    83
kpeter@2584
    84
// Runs a minimum cost flow algorithm and checks the results
kpeter@2584
    85
template < typename MinCostFlowImpl, typename Graph,
kpeter@2584
    86
           typename LowerMap, typename CapacityMap,
kpeter@2584
    87
           typename CostMap, typename SupplyMap >
kpeter@2584
    88
void checkMcf( std::string test_id,
kpeter@2584
    89
               const MinCostFlowImpl& mcf, const Graph& gr,
kpeter@2584
    90
               const LowerMap& lower, const CapacityMap& upper,
kpeter@2584
    91
               const CostMap& cost, const SupplyMap& supply,
kpeter@2584
    92
               bool mcf_result, bool result,
kpeter@2584
    93
               typename CostMap::Value total )
kpeter@2584
    94
{
kpeter@2584
    95
  check(mcf_result == result, "Wrong result " + test_id);
kpeter@2584
    96
  if (result) {
kpeter@2584
    97
    check(checkFlow(gr, lower, upper, supply, mcf.flowMap()),
kpeter@2584
    98
          "The flow is not feasible " + test_id);
kpeter@2584
    99
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
kpeter@2584
   100
    check(checkOptimality(gr, lower, upper, cost, mcf.flowMap(), mcf.potentialMap()),
kpeter@2584
   101
          "Wrong potentials " + test_id);
alpar@899
   102
  }
alpar@899
   103
}
alpar@899
   104
alpar@899
   105
int main()
alpar@899
   106
{
kpeter@2584
   107
  // Various tests on a small graph
kpeter@2584
   108
  {
kpeter@2584
   109
    typedef ListGraph Graph;
kpeter@2584
   110
    GRAPH_TYPEDEFS(ListGraph);
alpar@899
   111
kpeter@2584
   112
    // Reading the test graph
kpeter@2584
   113
    Graph gr;
kpeter@2584
   114
    Graph::EdgeMap<int> c(gr), l1(gr), l2(gr), u(gr);
kpeter@2584
   115
    Graph::NodeMap<int> s1(gr), s2(gr), s3(gr);
kpeter@2584
   116
    Node v, w;
alpar@899
   117
kpeter@2584
   118
    std::string fname;
kpeter@2584
   119
    if(getenv("srcdir"))
kpeter@2584
   120
      fname = std::string(getenv("srcdir"));
kpeter@2584
   121
    else fname = ".";
kpeter@2584
   122
    fname += "/test/min_cost_flow_test.lgf";
alpar@899
   123
kpeter@2584
   124
    std::ifstream input(fname.c_str());
kpeter@2584
   125
    check(input, "Input file '" << fname << "' not found");
kpeter@2584
   126
    GraphReader<Graph>(input, gr).
kpeter@2584
   127
      readEdgeMap("cost", c).
kpeter@2584
   128
      readEdgeMap("capacity", u).
kpeter@2584
   129
      readEdgeMap("lower1", l1).
kpeter@2584
   130
      readEdgeMap("lower2", l2).
kpeter@2584
   131
      readNodeMap("supply1", s1).
kpeter@2584
   132
      readNodeMap("supply2", s2).
kpeter@2584
   133
      readNodeMap("supply3", s3).
kpeter@2584
   134
      readNode("source", v).
kpeter@2584
   135
      readNode("target", w).
kpeter@2584
   136
      run();
kpeter@2584
   137
    input.close();
alpar@899
   138
kpeter@2584
   139
    // Testing CapacityScaling (scaling enabled)
kpeter@2584
   140
    {
kpeter@2584
   141
      CapacityScaling<Graph> mcf1(gr,u,c,s1);        checkMcf("#A1",mcf1,gr,l1,u,c,s1,mcf1.run(),true,    0);
kpeter@2584
   142
      CapacityScaling<Graph> mcf2(gr,u,c,s2);        checkMcf("#A2",mcf2,gr,l1,u,c,s2,mcf2.run(),true, 5240);
kpeter@2584
   143
      CapacityScaling<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#A3",mcf3,gr,l1,u,c,s3,mcf3.run(),true, 7620);
kpeter@2584
   144
      CapacityScaling<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#A4",mcf4,gr,l2,u,c,s1,mcf4.run(),false,   0);
kpeter@2584
   145
      CapacityScaling<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#A5",mcf5,gr,l2,u,c,s2,mcf5.run(),true, 5970);
kpeter@2584
   146
      CapacityScaling<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#A6",mcf6,gr,l2,u,c,s3,mcf6.run(),true, 8010);
kpeter@2584
   147
    }
kpeter@2584
   148
    // Testing CapacityScaling (scaling disabled)
kpeter@2584
   149
    {
kpeter@2584
   150
      CapacityScaling<Graph> mcf1(gr,u,c,s1);        checkMcf("#B1",mcf1,gr,l1,u,c,s1,mcf1.run(false),true,    0);
kpeter@2584
   151
      CapacityScaling<Graph> mcf2(gr,u,c,s2);        checkMcf("#B2",mcf2,gr,l1,u,c,s2,mcf2.run(false),true, 5240);
kpeter@2584
   152
      CapacityScaling<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#B3",mcf3,gr,l1,u,c,s3,mcf3.run(false),true, 7620);
kpeter@2584
   153
      CapacityScaling<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#B4",mcf4,gr,l2,u,c,s1,mcf4.run(false),false,   0);
kpeter@2584
   154
      CapacityScaling<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#B5",mcf5,gr,l2,u,c,s2,mcf5.run(false),true, 5970);
kpeter@2584
   155
      CapacityScaling<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#B6",mcf6,gr,l2,u,c,s3,mcf6.run(false),true, 8010);
kpeter@2584
   156
    }
alpar@899
   157
kpeter@2584
   158
    // Testing CostScaling
kpeter@2584
   159
    {
kpeter@2584
   160
      CostScaling<Graph> mcf1(gr,u,c,s1);        checkMcf("#C1",mcf1,gr,l1,u,c,s1,mcf1.run(),true,    0);
kpeter@2584
   161
      CostScaling<Graph> mcf2(gr,u,c,s2);        checkMcf("#C2",mcf2,gr,l1,u,c,s2,mcf2.run(),true, 5240);
kpeter@2584
   162
      CostScaling<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#C3",mcf3,gr,l1,u,c,s3,mcf3.run(),true, 7620);
kpeter@2584
   163
      CostScaling<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#C4",mcf4,gr,l2,u,c,s1,mcf4.run(),false,   0);
kpeter@2584
   164
      CostScaling<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#C5",mcf5,gr,l2,u,c,s2,mcf5.run(),true, 5970);
kpeter@2584
   165
      CostScaling<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#C6",mcf6,gr,l2,u,c,s3,mcf6.run(),true, 8010);
kpeter@2584
   166
    }
alpar@899
   167
kpeter@2584
   168
    // Testing NetworkSimplex (with the default pivot rule)
kpeter@2584
   169
    {
kpeter@2584
   170
      NetworkSimplex<Graph> mcf1(gr,u,c,s1);        checkMcf("#D1",mcf1,gr,l1,u,c,s1,mcf1.run(),true,    0);
kpeter@2584
   171
      NetworkSimplex<Graph> mcf2(gr,u,c,s2);        checkMcf("#D2",mcf2,gr,l1,u,c,s2,mcf2.run(),true, 5240);
kpeter@2584
   172
      NetworkSimplex<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#D3",mcf3,gr,l1,u,c,s3,mcf3.run(),true, 7620);
kpeter@2584
   173
      NetworkSimplex<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#D4",mcf4,gr,l2,u,c,s1,mcf4.run(),false,   0);
kpeter@2584
   174
      NetworkSimplex<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#D5",mcf5,gr,l2,u,c,s2,mcf5.run(),true, 5970);
kpeter@2584
   175
      NetworkSimplex<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#D6",mcf6,gr,l2,u,c,s3,mcf6.run(),true, 8010);
kpeter@2584
   176
    }
kpeter@2584
   177
    // Testing NetworkSimplex (with FIRST_ELIGIBLE_PIVOT)
kpeter@2584
   178
    {
kpeter@2584
   179
      NetworkSimplex<Graph>::PivotRuleEnum pr = NetworkSimplex<Graph>::FIRST_ELIGIBLE_PIVOT;
kpeter@2584
   180
      NetworkSimplex<Graph> mcf1(gr,u,c,s1);        checkMcf("#E1",mcf1,gr,l1,u,c,s1,mcf1.run(pr),true,    0);
kpeter@2584
   181
      NetworkSimplex<Graph> mcf2(gr,u,c,s2);        checkMcf("#E2",mcf2,gr,l1,u,c,s2,mcf2.run(pr),true, 5240);
kpeter@2584
   182
      NetworkSimplex<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#E3",mcf3,gr,l1,u,c,s3,mcf3.run(pr),true, 7620);
kpeter@2584
   183
      NetworkSimplex<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#E4",mcf4,gr,l2,u,c,s1,mcf4.run(pr),false,   0);
kpeter@2584
   184
      NetworkSimplex<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#E5",mcf5,gr,l2,u,c,s2,mcf5.run(pr),true, 5970);
kpeter@2584
   185
      NetworkSimplex<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#E6",mcf6,gr,l2,u,c,s3,mcf6.run(pr),true, 8010);
kpeter@2584
   186
    }
kpeter@2584
   187
    // Testing NetworkSimplex (with BEST_ELIGIBLE_PIVOT)
kpeter@2584
   188
    {
kpeter@2584
   189
      NetworkSimplex<Graph>::PivotRuleEnum pr = NetworkSimplex<Graph>::BEST_ELIGIBLE_PIVOT;
kpeter@2584
   190
      NetworkSimplex<Graph> mcf1(gr,u,c,s1);        checkMcf("#F1",mcf1,gr,l1,u,c,s1,mcf1.run(pr),true,    0);
kpeter@2584
   191
      NetworkSimplex<Graph> mcf2(gr,u,c,s2);        checkMcf("#F2",mcf2,gr,l1,u,c,s2,mcf2.run(pr),true, 5240);
kpeter@2584
   192
      NetworkSimplex<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#F3",mcf3,gr,l1,u,c,s3,mcf3.run(pr),true, 7620);
kpeter@2584
   193
      NetworkSimplex<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#F4",mcf4,gr,l2,u,c,s1,mcf4.run(pr),false,   0);
kpeter@2584
   194
      NetworkSimplex<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#F5",mcf5,gr,l2,u,c,s2,mcf5.run(pr),true, 5970);
kpeter@2584
   195
      NetworkSimplex<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#F6",mcf6,gr,l2,u,c,s3,mcf6.run(pr),true, 8010);
kpeter@2584
   196
    }
kpeter@2584
   197
    // Testing NetworkSimplex (with BLOCK_SEARCH_PIVOT)
kpeter@2584
   198
    {
kpeter@2584
   199
      NetworkSimplex<Graph>::PivotRuleEnum pr = NetworkSimplex<Graph>::BLOCK_SEARCH_PIVOT;
kpeter@2584
   200
      NetworkSimplex<Graph> mcf1(gr,u,c,s1);        checkMcf("#G1",mcf1,gr,l1,u,c,s1,mcf1.run(pr),true,    0);
kpeter@2584
   201
      NetworkSimplex<Graph> mcf2(gr,u,c,s2);        checkMcf("#G2",mcf2,gr,l1,u,c,s2,mcf2.run(pr),true, 5240);
kpeter@2584
   202
      NetworkSimplex<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#G3",mcf3,gr,l1,u,c,s3,mcf3.run(pr),true, 7620);
kpeter@2584
   203
      NetworkSimplex<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#G4",mcf4,gr,l2,u,c,s1,mcf4.run(pr),false,   0);
kpeter@2584
   204
      NetworkSimplex<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#G5",mcf5,gr,l2,u,c,s2,mcf5.run(pr),true, 5970);
kpeter@2584
   205
      NetworkSimplex<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#G6",mcf6,gr,l2,u,c,s3,mcf6.run(pr),true, 8010);
kpeter@2584
   206
    }
kpeter@2584
   207
    // Testing NetworkSimplex (with LIMITED_SEARCH_PIVOT)
kpeter@2584
   208
    {
kpeter@2584
   209
      NetworkSimplex<Graph>::PivotRuleEnum pr = NetworkSimplex<Graph>::LIMITED_SEARCH_PIVOT;
kpeter@2584
   210
      NetworkSimplex<Graph> mcf1(gr,u,c,s1);        checkMcf("#H1",mcf1,gr,l1,u,c,s1,mcf1.run(pr),true,    0);
kpeter@2584
   211
      NetworkSimplex<Graph> mcf2(gr,u,c,s2);        checkMcf("#H2",mcf2,gr,l1,u,c,s2,mcf2.run(pr),true, 5240);
kpeter@2584
   212
      NetworkSimplex<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#H3",mcf3,gr,l1,u,c,s3,mcf3.run(pr),true, 7620);
kpeter@2584
   213
      NetworkSimplex<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#H4",mcf4,gr,l2,u,c,s1,mcf4.run(pr),false,   0);
kpeter@2584
   214
      NetworkSimplex<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#H5",mcf5,gr,l2,u,c,s2,mcf5.run(pr),true, 5970);
kpeter@2584
   215
      NetworkSimplex<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#H6",mcf6,gr,l2,u,c,s3,mcf6.run(pr),true, 8010);
kpeter@2584
   216
    }
kpeter@2584
   217
    // Testing NetworkSimplex (with CANDIDATE_LIST_PIVOT)
kpeter@2584
   218
    {
kpeter@2584
   219
      NetworkSimplex<Graph>::PivotRuleEnum pr = NetworkSimplex<Graph>::CANDIDATE_LIST_PIVOT;
kpeter@2584
   220
      NetworkSimplex<Graph> mcf1(gr,u,c,s1);        checkMcf("#I1",mcf1,gr,l1,u,c,s1,mcf1.run(pr),true,    0);
kpeter@2584
   221
      NetworkSimplex<Graph> mcf2(gr,u,c,s2);        checkMcf("#I2",mcf2,gr,l1,u,c,s2,mcf2.run(pr),true, 5240);
kpeter@2584
   222
      NetworkSimplex<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#I3",mcf3,gr,l1,u,c,s3,mcf3.run(pr),true, 7620);
kpeter@2584
   223
      NetworkSimplex<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#I4",mcf4,gr,l2,u,c,s1,mcf4.run(pr),false,   0);
kpeter@2584
   224
      NetworkSimplex<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#I5",mcf5,gr,l2,u,c,s2,mcf5.run(pr),true, 5970);
kpeter@2584
   225
      NetworkSimplex<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#I6",mcf6,gr,l2,u,c,s3,mcf6.run(pr),true, 8010);
kpeter@2584
   226
    }
alpar@899
   227
kpeter@2584
   228
    // Testing CycleCanceling (with BellmanFord)
kpeter@2584
   229
    {
kpeter@2584
   230
      CycleCanceling<Graph> mcf1(gr,u,c,s1);        checkMcf("#J1",mcf1,gr,l1,u,c,s1,mcf1.run(),true,    0);
kpeter@2584
   231
      CycleCanceling<Graph> mcf2(gr,u,c,s2);        checkMcf("#J2",mcf2,gr,l1,u,c,s2,mcf2.run(),true, 5240);
kpeter@2584
   232
      CycleCanceling<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#J3",mcf3,gr,l1,u,c,s3,mcf3.run(),true, 7620);
kpeter@2584
   233
      CycleCanceling<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#J4",mcf4,gr,l2,u,c,s1,mcf4.run(),false,   0);
kpeter@2584
   234
      CycleCanceling<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#J5",mcf5,gr,l2,u,c,s2,mcf5.run(),true, 5970);
kpeter@2584
   235
      CycleCanceling<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#J6",mcf6,gr,l2,u,c,s3,mcf6.run(),true, 8010);
kpeter@2584
   236
    }
kpeter@2584
   237
    // Testing CycleCanceling (with MinMeanCycle)
kpeter@2584
   238
    {
kpeter@2584
   239
      CycleCanceling<Graph> mcf1(gr,u,c,s1);        checkMcf("#K1",mcf1,gr,l1,u,c,s1,mcf1.run(true),true,    0);
kpeter@2584
   240
      CycleCanceling<Graph> mcf2(gr,u,c,s2);        checkMcf("#K2",mcf2,gr,l1,u,c,s2,mcf2.run(true),true, 5240);
kpeter@2584
   241
      CycleCanceling<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#K3",mcf3,gr,l1,u,c,s3,mcf3.run(true),true, 7620);
kpeter@2584
   242
      CycleCanceling<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#K4",mcf4,gr,l2,u,c,s1,mcf4.run(true),false,   0);
kpeter@2584
   243
      CycleCanceling<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#K5",mcf5,gr,l2,u,c,s2,mcf5.run(true),true, 5970);
kpeter@2584
   244
      CycleCanceling<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#K6",mcf6,gr,l2,u,c,s3,mcf6.run(true),true, 8010);
kpeter@2584
   245
    }
alpar@899
   246
kpeter@2584
   247
    // Testing MinCostFlow
kpeter@2584
   248
    {
kpeter@2584
   249
      MinCostFlow<Graph> mcf1(gr,u,c,s1);        checkMcf("#L1",mcf1,gr,l1,u,c,s1,mcf1.run(),true,    0);
kpeter@2584
   250
      MinCostFlow<Graph> mcf2(gr,u,c,s2);        checkMcf("#L2",mcf2,gr,l1,u,c,s2,mcf2.run(),true, 5240);
kpeter@2584
   251
      MinCostFlow<Graph> mcf3(gr,u,c,v,w,27);    checkMcf("#L3",mcf3,gr,l1,u,c,s3,mcf3.run(),true, 7620);
kpeter@2584
   252
      MinCostFlow<Graph> mcf4(gr,l2,u,c,s1);     checkMcf("#L4",mcf4,gr,l2,u,c,s1,mcf4.run(),false,   0);
kpeter@2584
   253
      MinCostFlow<Graph> mcf5(gr,l2,u,c,s2);     checkMcf("#L5",mcf5,gr,l2,u,c,s2,mcf5.run(),true, 5970);
kpeter@2584
   254
      MinCostFlow<Graph> mcf6(gr,l2,u,c,v,w,27); checkMcf("#L6",mcf6,gr,l2,u,c,s3,mcf6.run(),true, 8010);
kpeter@2584
   255
    }
alpar@899
   256
kpeter@2584
   257
    // Testing MinCostMaxFlow
kpeter@2584
   258
    {
kpeter@2584
   259
      MinCostMaxFlow<Graph> mcmf(gr,u,c,v,w);
kpeter@2584
   260
      mcmf.run();
kpeter@2584
   261
      checkMcf("#M1",mcmf,gr,l1,u,c,s3,true,true,7620);
kpeter@2584
   262
    }
kpeter@2584
   263
  }
alpar@899
   264
kpeter@2584
   265
  // Benchmark test on a DIMACS network
kpeter@2584
   266
  {
kpeter@2584
   267
    typedef SmartGraph Graph;
kpeter@2584
   268
    GRAPH_TYPEDEFS(SmartGraph);
alpar@899
   269
kpeter@2584
   270
    // Reading the test graph
kpeter@2584
   271
    Graph graph;
kpeter@2584
   272
    Graph::EdgeMap<int> lower(graph), capacity(graph), cost(graph);
kpeter@2584
   273
    Graph::NodeMap<int> supply(graph);
alpar@899
   274
kpeter@2584
   275
    std::string fname;
kpeter@2584
   276
    if(getenv("srcdir"))
kpeter@2584
   277
      fname = std::string(getenv("srcdir"));
kpeter@2584
   278
    else fname = ".";
kpeter@2584
   279
    fname += "/test/min_cost_flow_test.net";
marci@941
   280
kpeter@2584
   281
    std::ifstream input(fname.c_str());
kpeter@2584
   282
    check(input, "Input file '" << fname << "' not found");
kpeter@2584
   283
    readDimacs(input, graph, lower, capacity, cost, supply);
kpeter@2584
   284
    input.close();
alpar@899
   285
kpeter@2584
   286
    // NetworkSimplex
kpeter@2584
   287
    {
kpeter@2584
   288
      Timer t;
kpeter@2584
   289
      NetworkSimplex<Graph> mcf(graph, lower, capacity, cost, supply);
kpeter@2584
   290
      bool res = mcf.run();
kpeter@2584
   291
      t.stop();
kpeter@2584
   292
      checkMcf("#T3", mcf, graph, lower, capacity, cost, supply, res, true, 196587626);
kpeter@2584
   293
      std::cout << "NetworkSimplex";
kpeter@2584
   294
      std::cout << std::endl << t << std::endl;
kpeter@2584
   295
    }
kpeter@2584
   296
    // CapacityScaling
kpeter@2584
   297
    {
kpeter@2584
   298
      Timer t;
kpeter@2584
   299
      CapacityScaling<Graph> mcf(graph, lower, capacity, cost, supply);
kpeter@2584
   300
      bool res = mcf.run();
kpeter@2584
   301
      t.stop();
kpeter@2584
   302
      checkMcf("#T1", mcf, graph, lower, capacity, cost, supply, res, true, 196587626);
kpeter@2584
   303
      std::cout << "CapacityScaling";
kpeter@2584
   304
      std::cout << std::endl << t << std::endl;
kpeter@2584
   305
    }
kpeter@2584
   306
    // CostScaling
kpeter@2584
   307
    {
kpeter@2584
   308
      Timer t;
kpeter@2584
   309
      CostScaling<Graph> mcf(graph, lower, capacity, cost, supply);
kpeter@2584
   310
      bool res = mcf.run();
kpeter@2584
   311
      t.stop();
kpeter@2584
   312
      checkMcf("#T2", mcf, graph, lower, capacity, cost, supply, res, true, 196587626);
kpeter@2584
   313
      std::cout << "CostScaling";
kpeter@2584
   314
      std::cout << std::endl << t << std::endl;
kpeter@2584
   315
    }
kpeter@2584
   316
    // CycleCanceling
kpeter@2584
   317
    {
kpeter@2584
   318
      Timer t;
kpeter@2584
   319
      CycleCanceling<Graph> mcf(graph, lower, capacity, cost, supply);
kpeter@2584
   320
      bool res = mcf.run();
kpeter@2584
   321
      t.stop();
kpeter@2584
   322
      checkMcf("#T4", mcf, graph, lower, capacity, cost, supply, res, true, 196587626);
kpeter@2584
   323
      std::cout << "CycleCanceling";
kpeter@2584
   324
      std::cout << std::endl << t << std::endl;
kpeter@2584
   325
    }
kpeter@2584
   326
  }
alpar@899
   327
kpeter@2584
   328
  return 0;
alpar@899
   329
}