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