test/gomory_hu_test.cc
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 891 bb70ad62c95f
parent 546 d6b40ebb2617
child 877 141f9c0db4a3
child 1007 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@543
     1
#include <iostream>
tapolcai@543
     2
tapolcai@543
     3
#include "test_tools.h"
tapolcai@543
     4
#include <lemon/smart_graph.h>
kpeter@596
     5
#include <lemon/concepts/graph.h>
kpeter@596
     6
#include <lemon/concepts/maps.h>
tapolcai@543
     7
#include <lemon/lgf_reader.h>
alpar@545
     8
#include <lemon/gomory_hu.h>
tapolcai@543
     9
#include <cstdlib>
tapolcai@543
    10
tapolcai@543
    11
using namespace std;
tapolcai@543
    12
using namespace lemon;
tapolcai@543
    13
tapolcai@543
    14
typedef SmartGraph Graph;
tapolcai@543
    15
tapolcai@543
    16
char test_lgf[] =
tapolcai@543
    17
  "@nodes\n"
tapolcai@543
    18
  "label\n"
tapolcai@543
    19
  "0\n"
tapolcai@543
    20
  "1\n"
tapolcai@543
    21
  "2\n"
tapolcai@543
    22
  "3\n"
tapolcai@543
    23
  "4\n"
tapolcai@543
    24
  "@arcs\n"
tapolcai@543
    25
  "     label capacity\n"
tapolcai@543
    26
  "0 1  0     1\n"
tapolcai@543
    27
  "1 2  1     1\n"
tapolcai@543
    28
  "2 3  2     1\n"
tapolcai@543
    29
  "0 3  4     5\n"
tapolcai@543
    30
  "0 3  5     10\n"
tapolcai@543
    31
  "0 3  6     7\n"
tapolcai@543
    32
  "4 2  7     1\n"
tapolcai@543
    33
  "@attributes\n"
tapolcai@543
    34
  "source 0\n"
tapolcai@543
    35
  "target 3\n";
tapolcai@543
    36
  
kpeter@596
    37
void checkGomoryHuCompile()
kpeter@596
    38
{
kpeter@596
    39
  typedef int Value;
kpeter@596
    40
  typedef concepts::Graph Graph;
kpeter@596
    41
kpeter@596
    42
  typedef Graph::Node Node;
kpeter@596
    43
  typedef Graph::Edge Edge;
kpeter@596
    44
  typedef concepts::ReadMap<Edge, Value> CapMap;
kpeter@596
    45
  typedef concepts::ReadWriteMap<Node, bool> CutMap;
kpeter@596
    46
kpeter@596
    47
  Graph g;
kpeter@596
    48
  Node n;
kpeter@596
    49
  CapMap cap;
kpeter@596
    50
  CutMap cut;
kpeter@596
    51
  Value v;
kpeter@596
    52
  int d;
kpeter@596
    53
kpeter@596
    54
  GomoryHu<Graph, CapMap> gh_test(g, cap);
kpeter@596
    55
  const GomoryHu<Graph, CapMap>&
kpeter@596
    56
    const_gh_test = gh_test;
kpeter@596
    57
kpeter@596
    58
  gh_test.run();
kpeter@596
    59
kpeter@596
    60
  n = const_gh_test.predNode(n);
kpeter@596
    61
  v = const_gh_test.predValue(n);
kpeter@596
    62
  d = const_gh_test.rootDist(n);
kpeter@596
    63
  v = const_gh_test.minCutValue(n, n);
kpeter@596
    64
  v = const_gh_test.minCutMap(n, n, cut);
kpeter@596
    65
}
kpeter@596
    66
tapolcai@543
    67
GRAPH_TYPEDEFS(Graph);
tapolcai@543
    68
typedef Graph::EdgeMap<int> IntEdgeMap;
tapolcai@543
    69
typedef Graph::NodeMap<bool> BoolNodeMap;
tapolcai@543
    70
tapolcai@543
    71
int cutValue(const Graph& graph, const BoolNodeMap& cut,
tapolcai@543
    72
	     const IntEdgeMap& capacity) {
tapolcai@543
    73
tapolcai@543
    74
  int sum = 0;
tapolcai@543
    75
  for (EdgeIt e(graph); e != INVALID; ++e) {
tapolcai@543
    76
    Node s = graph.u(e);
tapolcai@543
    77
    Node t = graph.v(e);
tapolcai@543
    78
tapolcai@543
    79
    if (cut[s] != cut[t]) {
tapolcai@543
    80
      sum += capacity[e];
tapolcai@543
    81
    }
tapolcai@543
    82
  }
tapolcai@543
    83
  return sum;
tapolcai@543
    84
}
tapolcai@543
    85
tapolcai@543
    86
tapolcai@543
    87
int main() {
tapolcai@543
    88
  Graph graph;
tapolcai@543
    89
  IntEdgeMap capacity(graph);
tapolcai@543
    90
tapolcai@543
    91
  std::istringstream input(test_lgf);
tapolcai@543
    92
  GraphReader<Graph>(graph, input).
tapolcai@543
    93
    edgeMap("capacity", capacity).run();
tapolcai@543
    94
alpar@545
    95
  GomoryHu<Graph> ght(graph, capacity);
tapolcai@543
    96
  ght.run();
tapolcai@543
    97
tapolcai@543
    98
  for (NodeIt u(graph); u != INVALID; ++u) {
tapolcai@543
    99
    for (NodeIt v(graph); v != u; ++v) {
tapolcai@543
   100
      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
tapolcai@543
   101
      pf.runMinCut();
tapolcai@543
   102
      BoolNodeMap cm(graph);
tapolcai@543
   103
      ght.minCutMap(u, v, cm);
tapolcai@543
   104
      check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
kpeter@596
   105
      check(cm[u] != cm[v], "Wrong cut 2");
kpeter@596
   106
      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
alpar@544
   107
alpar@544
   108
      int sum=0;
alpar@545
   109
      for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
alpar@544
   110
        sum+=capacity[a]; 
alpar@544
   111
      check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
alpar@544
   112
alpar@544
   113
      sum=0;
alpar@545
   114
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
alpar@544
   115
        sum++;
alpar@545
   116
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
alpar@544
   117
        sum++;
alpar@544
   118
      check(sum == countNodes(graph), "Problem with MinCutNodeIt");
tapolcai@543
   119
    }
tapolcai@543
   120
  }
tapolcai@543
   121
  
tapolcai@543
   122
  return 0;
tapolcai@543
   123
}