test/hao_orlin_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 872 fa6f37d7a25b
parent 643 293551ad254f
child 956 141f9c0db4a3
child 1081 f1398882a928
child 1171 7e368d9b67f7
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.
deba@426
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@426
     2
 *
deba@426
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@426
     4
 *
alpar@463
     5
 * Copyright (C) 2003-2009
deba@426
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@426
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@426
     8
 *
deba@426
     9
 * Permission to use, modify and distribute this software is granted
deba@426
    10
 * provided that this copyright notice appears in all copies. For
deba@426
    11
 * precise terms see the accompanying LICENSE file.
deba@426
    12
 *
deba@426
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@426
    14
 * express or implied, and with no claim as to its suitability for any
deba@426
    15
 * purpose.
deba@426
    16
 *
deba@426
    17
 */
deba@426
    18
deba@426
    19
#include <sstream>
deba@426
    20
deba@426
    21
#include <lemon/smart_graph.h>
kpeter@643
    22
#include <lemon/adaptors.h>
kpeter@643
    23
#include <lemon/concepts/digraph.h>
kpeter@643
    24
#include <lemon/concepts/maps.h>
kpeter@643
    25
#include <lemon/lgf_reader.h>
deba@426
    26
#include <lemon/hao_orlin.h>
deba@426
    27
deba@426
    28
#include "test_tools.h"
deba@426
    29
deba@426
    30
using namespace lemon;
deba@426
    31
using namespace std;
deba@426
    32
deba@426
    33
const std::string lgf =
deba@426
    34
  "@nodes\n"
deba@426
    35
  "label\n"
deba@426
    36
  "0\n"
deba@426
    37
  "1\n"
deba@426
    38
  "2\n"
deba@426
    39
  "3\n"
deba@426
    40
  "4\n"
deba@426
    41
  "5\n"
deba@426
    42
  "@edges\n"
kpeter@643
    43
  "     cap1 cap2 cap3\n"
kpeter@643
    44
  "0 1  1    1    1   \n"
kpeter@643
    45
  "0 2  2    2    4   \n"
kpeter@643
    46
  "1 2  4    4    4   \n"
kpeter@643
    47
  "3 4  1    1    1   \n"
kpeter@643
    48
  "3 5  2    2    4   \n"
kpeter@643
    49
  "4 5  4    4    4   \n"
kpeter@643
    50
  "5 4  4    4    4   \n"
kpeter@643
    51
  "2 3  1    6    6   \n"
kpeter@643
    52
  "4 0  1    6    6   \n";
kpeter@643
    53
kpeter@643
    54
void checkHaoOrlinCompile()
kpeter@643
    55
{
kpeter@643
    56
  typedef int Value;
kpeter@643
    57
  typedef concepts::Digraph Digraph;
kpeter@643
    58
kpeter@643
    59
  typedef Digraph::Node Node;
kpeter@643
    60
  typedef Digraph::Arc Arc;
kpeter@643
    61
  typedef concepts::ReadMap<Arc, Value> CapMap;
kpeter@643
    62
  typedef concepts::WriteMap<Node, bool> CutMap;
kpeter@643
    63
kpeter@643
    64
  Digraph g;
kpeter@643
    65
  Node n;
kpeter@643
    66
  CapMap cap;
kpeter@643
    67
  CutMap cut;
kpeter@643
    68
  Value v;
kpeter@643
    69
kpeter@643
    70
  HaoOrlin<Digraph, CapMap> ho_test(g, cap);
kpeter@643
    71
  const HaoOrlin<Digraph, CapMap>&
kpeter@643
    72
    const_ho_test = ho_test;
kpeter@643
    73
kpeter@643
    74
  ho_test.init();
kpeter@643
    75
  ho_test.init(n);
kpeter@643
    76
  ho_test.calculateOut();
kpeter@643
    77
  ho_test.calculateIn();
kpeter@643
    78
  ho_test.run();
kpeter@643
    79
  ho_test.run(n);
kpeter@643
    80
kpeter@643
    81
  v = const_ho_test.minCutValue();
kpeter@643
    82
  v = const_ho_test.minCutMap(cut);
kpeter@643
    83
}
kpeter@643
    84
kpeter@643
    85
template <typename Graph, typename CapMap, typename CutMap>
kpeter@643
    86
typename CapMap::Value 
kpeter@643
    87
  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
kpeter@643
    88
{
kpeter@643
    89
  typename CapMap::Value sum = 0;
kpeter@643
    90
  for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
kpeter@643
    91
    if (cut[graph.source(a)] && !cut[graph.target(a)])
kpeter@643
    92
      sum += cap[a];
kpeter@643
    93
  }
kpeter@643
    94
  return sum;
kpeter@643
    95
}
deba@426
    96
deba@426
    97
int main() {
kpeter@643
    98
  SmartDigraph graph;
kpeter@643
    99
  SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
kpeter@643
   100
  SmartDigraph::NodeMap<bool> cut(graph);
deba@426
   101
kpeter@643
   102
  istringstream input(lgf);
kpeter@643
   103
  digraphReader(graph, input)
kpeter@643
   104
    .arcMap("cap1", cap1)
kpeter@643
   105
    .arcMap("cap2", cap2)
kpeter@643
   106
    .arcMap("cap3", cap3)
kpeter@643
   107
    .run();
deba@426
   108
kpeter@643
   109
  {
kpeter@643
   110
    HaoOrlin<SmartDigraph> ho(graph, cap1);
kpeter@643
   111
    ho.run();
kpeter@643
   112
    ho.minCutMap(cut);
kpeter@643
   113
    
deba@644
   114
    check(ho.minCutValue() == 1, "Wrong cut value");
deba@644
   115
    check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
kpeter@643
   116
  }
kpeter@643
   117
  {
kpeter@643
   118
    HaoOrlin<SmartDigraph> ho(graph, cap2);
kpeter@643
   119
    ho.run();
kpeter@643
   120
    ho.minCutMap(cut);
deba@644
   121
deba@644
   122
    check(ho.minCutValue() == 1, "Wrong cut value");
deba@644
   123
    check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
kpeter@643
   124
  }
kpeter@643
   125
  {
kpeter@643
   126
    HaoOrlin<SmartDigraph> ho(graph, cap3);
kpeter@643
   127
    ho.run();
kpeter@643
   128
    ho.minCutMap(cut);
kpeter@643
   129
    
deba@644
   130
    check(ho.minCutValue() == 1, "Wrong cut value");
deba@644
   131
    check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
kpeter@643
   132
  }
kpeter@643
   133
  
kpeter@643
   134
  typedef Undirector<SmartDigraph> UGraph;
kpeter@643
   135
  UGraph ugraph(graph);
kpeter@643
   136
  
kpeter@643
   137
  {
kpeter@643
   138
    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
kpeter@643
   139
    ho.run();
kpeter@643
   140
    ho.minCutMap(cut);
kpeter@643
   141
    
deba@644
   142
    check(ho.minCutValue() == 2, "Wrong cut value");
deba@644
   143
    check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
kpeter@643
   144
  }
kpeter@643
   145
  {
kpeter@643
   146
    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
kpeter@643
   147
    ho.run();
kpeter@643
   148
    ho.minCutMap(cut);
kpeter@643
   149
    
deba@644
   150
    check(ho.minCutValue() == 5, "Wrong cut value");
deba@644
   151
    check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
kpeter@643
   152
  }
kpeter@643
   153
  {
kpeter@643
   154
    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
kpeter@643
   155
    ho.run();
kpeter@643
   156
    ho.minCutMap(cut);
kpeter@643
   157
    
kpeter@643
   158
    check(ho.minCutValue() == 5, "Wrong cut value");
deba@644
   159
    check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
kpeter@643
   160
  }
deba@426
   161
deba@426
   162
  return 0;
deba@426
   163
}