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