test/gomory_hu_test.cc
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 982 bb70ad62c95f
parent 593 d6b40ebb2617
child 956 141f9c0db4a3
child 1081 f1398882a928
child 1171 7e368d9b67f7
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
tapolcai@590
     1
#include <iostream>
tapolcai@590
     2
tapolcai@590
     3
#include "test_tools.h"
tapolcai@590
     4
#include <lemon/smart_graph.h>
kpeter@643
     5
#include <lemon/concepts/graph.h>
kpeter@643
     6
#include <lemon/concepts/maps.h>
tapolcai@590
     7
#include <lemon/lgf_reader.h>
alpar@592
     8
#include <lemon/gomory_hu.h>
tapolcai@590
     9
#include <cstdlib>
tapolcai@590
    10
tapolcai@590
    11
using namespace std;
tapolcai@590
    12
using namespace lemon;
tapolcai@590
    13
tapolcai@590
    14
typedef SmartGraph Graph;
tapolcai@590
    15
tapolcai@590
    16
char test_lgf[] =
tapolcai@590
    17
  "@nodes\n"
tapolcai@590
    18
  "label\n"
tapolcai@590
    19
  "0\n"
tapolcai@590
    20
  "1\n"
tapolcai@590
    21
  "2\n"
tapolcai@590
    22
  "3\n"
tapolcai@590
    23
  "4\n"
tapolcai@590
    24
  "@arcs\n"
tapolcai@590
    25
  "     label capacity\n"
tapolcai@590
    26
  "0 1  0     1\n"
tapolcai@590
    27
  "1 2  1     1\n"
tapolcai@590
    28
  "2 3  2     1\n"
tapolcai@590
    29
  "0 3  4     5\n"
tapolcai@590
    30
  "0 3  5     10\n"
tapolcai@590
    31
  "0 3  6     7\n"
tapolcai@590
    32
  "4 2  7     1\n"
tapolcai@590
    33
  "@attributes\n"
tapolcai@590
    34
  "source 0\n"
tapolcai@590
    35
  "target 3\n";
tapolcai@590
    36
  
kpeter@643
    37
void checkGomoryHuCompile()
kpeter@643
    38
{
kpeter@643
    39
  typedef int Value;
kpeter@643
    40
  typedef concepts::Graph Graph;
kpeter@643
    41
kpeter@643
    42
  typedef Graph::Node Node;
kpeter@643
    43
  typedef Graph::Edge Edge;
kpeter@643
    44
  typedef concepts::ReadMap<Edge, Value> CapMap;
kpeter@643
    45
  typedef concepts::ReadWriteMap<Node, bool> CutMap;
kpeter@643
    46
kpeter@643
    47
  Graph g;
kpeter@643
    48
  Node n;
kpeter@643
    49
  CapMap cap;
kpeter@643
    50
  CutMap cut;
kpeter@643
    51
  Value v;
kpeter@643
    52
  int d;
kpeter@643
    53
kpeter@643
    54
  GomoryHu<Graph, CapMap> gh_test(g, cap);
kpeter@643
    55
  const GomoryHu<Graph, CapMap>&
kpeter@643
    56
    const_gh_test = gh_test;
kpeter@643
    57
kpeter@643
    58
  gh_test.run();
kpeter@643
    59
kpeter@643
    60
  n = const_gh_test.predNode(n);
kpeter@643
    61
  v = const_gh_test.predValue(n);
kpeter@643
    62
  d = const_gh_test.rootDist(n);
kpeter@643
    63
  v = const_gh_test.minCutValue(n, n);
kpeter@643
    64
  v = const_gh_test.minCutMap(n, n, cut);
kpeter@643
    65
}
kpeter@643
    66
tapolcai@590
    67
GRAPH_TYPEDEFS(Graph);
tapolcai@590
    68
typedef Graph::EdgeMap<int> IntEdgeMap;
tapolcai@590
    69
typedef Graph::NodeMap<bool> BoolNodeMap;
tapolcai@590
    70
tapolcai@590
    71
int cutValue(const Graph& graph, const BoolNodeMap& cut,
tapolcai@590
    72
	     const IntEdgeMap& capacity) {
tapolcai@590
    73
tapolcai@590
    74
  int sum = 0;
tapolcai@590
    75
  for (EdgeIt e(graph); e != INVALID; ++e) {
tapolcai@590
    76
    Node s = graph.u(e);
tapolcai@590
    77
    Node t = graph.v(e);
tapolcai@590
    78
tapolcai@590
    79
    if (cut[s] != cut[t]) {
tapolcai@590
    80
      sum += capacity[e];
tapolcai@590
    81
    }
tapolcai@590
    82
  }
tapolcai@590
    83
  return sum;
tapolcai@590
    84
}
tapolcai@590
    85
tapolcai@590
    86
tapolcai@590
    87
int main() {
tapolcai@590
    88
  Graph graph;
tapolcai@590
    89
  IntEdgeMap capacity(graph);
tapolcai@590
    90
tapolcai@590
    91
  std::istringstream input(test_lgf);
tapolcai@590
    92
  GraphReader<Graph>(graph, input).
tapolcai@590
    93
    edgeMap("capacity", capacity).run();
tapolcai@590
    94
alpar@592
    95
  GomoryHu<Graph> ght(graph, capacity);
tapolcai@590
    96
  ght.run();
tapolcai@590
    97
tapolcai@590
    98
  for (NodeIt u(graph); u != INVALID; ++u) {
tapolcai@590
    99
    for (NodeIt v(graph); v != u; ++v) {
tapolcai@590
   100
      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
tapolcai@590
   101
      pf.runMinCut();
tapolcai@590
   102
      BoolNodeMap cm(graph);
tapolcai@590
   103
      ght.minCutMap(u, v, cm);
tapolcai@590
   104
      check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
kpeter@643
   105
      check(cm[u] != cm[v], "Wrong cut 2");
kpeter@643
   106
      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
alpar@591
   107
alpar@591
   108
      int sum=0;
alpar@592
   109
      for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
alpar@591
   110
        sum+=capacity[a]; 
alpar@591
   111
      check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
alpar@591
   112
alpar@591
   113
      sum=0;
alpar@592
   114
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
alpar@591
   115
        sum++;
alpar@592
   116
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
alpar@591
   117
        sum++;
alpar@591
   118
      check(sum == countNodes(graph), "Problem with MinCutNodeIt");
tapolcai@590
   119
    }
tapolcai@590
   120
  }
tapolcai@590
   121
  
tapolcai@590
   122
  return 0;
tapolcai@590
   123
}