test/circulation_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 872 fa6f37d7a25b
parent 658 85cb3aa71cce
child 956 141f9c0db4a3
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
alpar@415
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@415
     2
 *
alpar@415
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@415
     4
 *
alpar@463
     5
 * Copyright (C) 2003-2009
alpar@415
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@415
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@415
     8
 *
alpar@415
     9
 * Permission to use, modify and distribute this software is granted
alpar@415
    10
 * provided that this copyright notice appears in all copies. For
alpar@415
    11
 * precise terms see the accompanying LICENSE file.
alpar@415
    12
 *
alpar@415
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@415
    14
 * express or implied, and with no claim as to its suitability for any
alpar@415
    15
 * purpose.
alpar@415
    16
 *
alpar@415
    17
 */
alpar@415
    18
alpar@415
    19
#include <iostream>
alpar@415
    20
alpar@415
    21
#include "test_tools.h"
alpar@415
    22
#include <lemon/list_graph.h>
alpar@415
    23
#include <lemon/circulation.h>
alpar@415
    24
#include <lemon/lgf_reader.h>
kpeter@418
    25
#include <lemon/concepts/digraph.h>
kpeter@418
    26
#include <lemon/concepts/maps.h>
alpar@415
    27
alpar@415
    28
using namespace lemon;
alpar@415
    29
alpar@415
    30
char test_lgf[] =
alpar@415
    31
  "@nodes\n"
kpeter@418
    32
  "label\n"
kpeter@418
    33
  "0\n"
kpeter@418
    34
  "1\n"
kpeter@418
    35
  "2\n"
kpeter@418
    36
  "3\n"
kpeter@418
    37
  "4\n"
kpeter@418
    38
  "5\n"
kpeter@418
    39
  "@arcs\n"
kpeter@418
    40
  "     lcap  ucap\n"
kpeter@418
    41
  "0 1  2  10\n"
kpeter@418
    42
  "0 2  2  6\n"
kpeter@418
    43
  "1 3  4  7\n"
kpeter@418
    44
  "1 4  0  5\n"
kpeter@418
    45
  "2 4  1  3\n"
kpeter@418
    46
  "3 5  3  8\n"
kpeter@418
    47
  "4 5  3  7\n"
alpar@415
    48
  "@attributes\n"
kpeter@418
    49
  "source 0\n"
kpeter@418
    50
  "sink   5\n";
kpeter@418
    51
kpeter@418
    52
void checkCirculationCompile()
kpeter@418
    53
{
kpeter@418
    54
  typedef int VType;
kpeter@418
    55
  typedef concepts::Digraph Digraph;
kpeter@418
    56
kpeter@418
    57
  typedef Digraph::Node Node;
kpeter@418
    58
  typedef Digraph::Arc Arc;
kpeter@418
    59
  typedef concepts::ReadMap<Arc,VType> CapMap;
kpeter@657
    60
  typedef concepts::ReadMap<Node,VType> SupplyMap;
kpeter@418
    61
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
kpeter@418
    62
  typedef concepts::WriteMap<Node,bool> BarrierMap;
kpeter@418
    63
kpeter@418
    64
  typedef Elevator<Digraph, Digraph::Node> Elev;
kpeter@418
    65
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
kpeter@418
    66
kpeter@418
    67
  Digraph g;
kpeter@418
    68
  Node n;
kpeter@418
    69
  Arc a;
kpeter@418
    70
  CapMap lcap, ucap;
kpeter@657
    71
  SupplyMap supply;
kpeter@418
    72
  FlowMap flow;
kpeter@418
    73
  BarrierMap bar;
kpeter@632
    74
  VType v;
kpeter@632
    75
  bool b;
kpeter@418
    76
alpar@658
    77
  typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
kpeter@632
    78
            ::SetFlowMap<FlowMap>
kpeter@632
    79
            ::SetElevator<Elev>
kpeter@632
    80
            ::SetStandardElevator<LinkedElev>
kpeter@632
    81
            ::Create CirculationType;
alpar@658
    82
  CirculationType circ_test(g, lcap, ucap, supply);
kpeter@632
    83
  const CirculationType& const_circ_test = circ_test;
kpeter@632
    84
   
kpeter@632
    85
  circ_test
alpar@658
    86
    .lowerMap(lcap)
alpar@658
    87
    .upperMap(ucap)
alpar@658
    88
    .supplyMap(supply)
kpeter@632
    89
    .flowMap(flow);
kpeter@736
    90
  
kpeter@736
    91
  const CirculationType::Elevator& elev = const_circ_test.elevator();
kpeter@736
    92
  circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
kpeter@736
    93
  CirculationType::Tolerance tol = const_circ_test.tolerance();
kpeter@736
    94
  circ_test.tolerance(tol);
kpeter@418
    95
kpeter@418
    96
  circ_test.init();
kpeter@418
    97
  circ_test.greedyInit();
kpeter@418
    98
  circ_test.start();
kpeter@418
    99
  circ_test.run();
kpeter@418
   100
kpeter@632
   101
  v = const_circ_test.flow(a);
kpeter@632
   102
  const FlowMap& fm = const_circ_test.flowMap();
kpeter@632
   103
  b = const_circ_test.barrier(n);
kpeter@632
   104
  const_circ_test.barrierMap(bar);
kpeter@632
   105
  
kpeter@632
   106
  ignore_unused_variable_warning(fm);
kpeter@418
   107
}
kpeter@418
   108
kpeter@418
   109
template <class G, class LM, class UM, class DM>
kpeter@418
   110
void checkCirculation(const G& g, const LM& lm, const UM& um,
kpeter@418
   111
                      const DM& dm, bool find)
kpeter@418
   112
{
kpeter@418
   113
  Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
kpeter@418
   114
  bool ret = circ.run();
kpeter@418
   115
  if (find) {
kpeter@418
   116
    check(ret, "A feasible solution should have been found.");
kpeter@418
   117
    check(circ.checkFlow(), "The found flow is corrupt.");
kpeter@418
   118
    check(!circ.checkBarrier(), "A barrier should not have been found.");
kpeter@418
   119
  } else {
kpeter@418
   120
    check(!ret, "A feasible solution should not have been found.");
kpeter@418
   121
    check(circ.checkBarrier(), "The found barrier is corrupt.");
kpeter@418
   122
  }
kpeter@418
   123
}
alpar@415
   124
alpar@415
   125
int main (int, char*[])
alpar@415
   126
{
kpeter@418
   127
  typedef ListDigraph Digraph;
kpeter@418
   128
  DIGRAPH_TYPEDEFS(Digraph);
alpar@415
   129
kpeter@418
   130
  Digraph g;
kpeter@418
   131
  IntArcMap lo(g), up(g);
kpeter@418
   132
  IntNodeMap delta(g, 0);
kpeter@418
   133
  Node s, t;
alpar@415
   134
kpeter@418
   135
  std::istringstream input(test_lgf);
kpeter@418
   136
  DigraphReader<Digraph>(g,input).
kpeter@418
   137
    arcMap("lcap", lo).
kpeter@418
   138
    arcMap("ucap", up).
kpeter@418
   139
    node("source",s).
kpeter@418
   140
    node("sink",t).
kpeter@418
   141
    run();
alpar@415
   142
kpeter@418
   143
  delta[s] = 7; delta[t] = -7;
kpeter@418
   144
  checkCirculation(g, lo, up, delta, true);
alpar@415
   145
kpeter@418
   146
  delta[s] = 13; delta[t] = -13;
kpeter@418
   147
  checkCirculation(g, lo, up, delta, true);
kpeter@418
   148
kpeter@418
   149
  delta[s] = 6; delta[t] = -6;
kpeter@418
   150
  checkCirculation(g, lo, up, delta, false);
kpeter@418
   151
kpeter@418
   152
  delta[s] = 14; delta[t] = -14;
kpeter@418
   153
  checkCirculation(g, lo, up, delta, false);
kpeter@418
   154
kpeter@418
   155
  delta[s] = 7; delta[t] = -13;
kpeter@418
   156
  checkCirculation(g, lo, up, delta, true);
kpeter@418
   157
kpeter@418
   158
  delta[s] = 5; delta[t] = -15;
kpeter@418
   159
  checkCirculation(g, lo, up, delta, true);
kpeter@418
   160
kpeter@418
   161
  delta[s] = 10; delta[t] = -11;
kpeter@418
   162
  checkCirculation(g, lo, up, delta, true);
kpeter@418
   163
kpeter@418
   164
  delta[s] = 11; delta[t] = -10;
kpeter@418
   165
  checkCirculation(g, lo, up, delta, false);
kpeter@418
   166
kpeter@418
   167
  return 0;
alpar@415
   168
}