test/bfs_test.cc
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 982 bb70ad62c95f
parent 463 88ed40ad0d4f
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.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@100
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@100
     4
 *
alpar@463
     5
 * Copyright (C) 2003-2009
alpar@100
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@100
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@100
     8
 *
alpar@100
     9
 * Permission to use, modify and distribute this software is granted
alpar@100
    10
 * provided that this copyright notice appears in all copies. For
alpar@100
    11
 * precise terms see the accompanying LICENSE file.
alpar@100
    12
 *
alpar@100
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@100
    14
 * express or implied, and with no claim as to its suitability for any
alpar@100
    15
 * purpose.
alpar@100
    16
 *
alpar@100
    17
 */
alpar@100
    18
kpeter@171
    19
#include <lemon/concepts/digraph.h>
kpeter@171
    20
#include <lemon/smart_graph.h>
alpar@100
    21
#include <lemon/list_graph.h>
deba@228
    22
#include <lemon/lgf_reader.h>
alpar@100
    23
#include <lemon/bfs.h>
alpar@100
    24
#include <lemon/path.h>
kpeter@171
    25
kpeter@171
    26
#include "graph_test.h"
kpeter@171
    27
#include "test_tools.h"
alpar@100
    28
alpar@100
    29
using namespace lemon;
alpar@100
    30
deba@228
    31
char test_lgf[] =
deba@228
    32
  "@nodes\n"
deba@228
    33
  "label\n"
deba@228
    34
  "0\n"
deba@228
    35
  "1\n"
deba@228
    36
  "2\n"
deba@228
    37
  "3\n"
deba@228
    38
  "4\n"
deba@228
    39
  "5\n"
deba@228
    40
  "@arcs\n"
deba@228
    41
  "     label\n"
deba@228
    42
  "0 1  0\n"
deba@228
    43
  "1 2  1\n"
deba@228
    44
  "2 3  2\n"
deba@228
    45
  "3 4  3\n"
deba@228
    46
  "0 3  4\n"
deba@228
    47
  "0 3  5\n"
deba@228
    48
  "5 2  6\n"
deba@228
    49
  "@attributes\n"
deba@228
    50
  "source 0\n"
deba@228
    51
  "target 4\n";
deba@228
    52
alpar@209
    53
void checkBfsCompile()
alpar@100
    54
{
alpar@100
    55
  typedef concepts::Digraph Digraph;
alpar@100
    56
  typedef Bfs<Digraph> BType;
kpeter@286
    57
  typedef Digraph::Node Node;
kpeter@286
    58
  typedef Digraph::Arc Arc;
alpar@209
    59
alpar@100
    60
  Digraph G;
kpeter@632
    61
  Node s, t, n;
kpeter@286
    62
  Arc e;
kpeter@632
    63
  int l, i;
alpar@100
    64
  bool b;
alpar@100
    65
  BType::DistMap d(G);
alpar@100
    66
  BType::PredMap p(G);
kpeter@286
    67
  Path<Digraph> pp;
kpeter@632
    68
  concepts::ReadMap<Node,bool> nm;
alpar@209
    69
kpeter@286
    70
  {
kpeter@286
    71
    BType bfs_test(G);
kpeter@632
    72
    const BType& const_bfs_test = bfs_test;
alpar@209
    73
kpeter@286
    74
    bfs_test.run(s);
kpeter@286
    75
    bfs_test.run(s,t);
kpeter@286
    76
    bfs_test.run();
alpar@209
    77
kpeter@632
    78
    bfs_test.init();
kpeter@632
    79
    bfs_test.addSource(s);
kpeter@632
    80
    n = bfs_test.processNextNode();
kpeter@632
    81
    n = bfs_test.processNextNode(t, b);
kpeter@632
    82
    n = bfs_test.processNextNode(nm, n);
kpeter@632
    83
    n = const_bfs_test.nextNode();
kpeter@632
    84
    b = const_bfs_test.emptyQueue();
kpeter@632
    85
    i = const_bfs_test.queueSize();
kpeter@632
    86
    
kpeter@632
    87
    bfs_test.start();
kpeter@632
    88
    bfs_test.start(t);
kpeter@632
    89
    bfs_test.start(nm);
kpeter@632
    90
kpeter@632
    91
    l  = const_bfs_test.dist(t);
kpeter@632
    92
    e  = const_bfs_test.predArc(t);
kpeter@632
    93
    s  = const_bfs_test.predNode(t);
kpeter@632
    94
    b  = const_bfs_test.reached(t);
kpeter@632
    95
    d  = const_bfs_test.distMap();
kpeter@632
    96
    p  = const_bfs_test.predMap();
kpeter@632
    97
    pp = const_bfs_test.path(t);
kpeter@286
    98
  }
kpeter@286
    99
  {
kpeter@286
   100
    BType
kpeter@286
   101
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
kpeter@286
   102
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
kpeter@286
   103
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
kpeter@632
   104
      ::SetStandardProcessedMap
kpeter@286
   105
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
kpeter@286
   106
      ::Create bfs_test(G);
kpeter@632
   107
      
kpeter@632
   108
    concepts::ReadWriteMap<Node,Arc> pred_map;
kpeter@632
   109
    concepts::ReadWriteMap<Node,int> dist_map;
kpeter@632
   110
    concepts::ReadWriteMap<Node,bool> reached_map;
kpeter@632
   111
    concepts::WriteMap<Node,bool> processed_map;
kpeter@632
   112
    
kpeter@632
   113
    bfs_test
kpeter@632
   114
      .predMap(pred_map)
kpeter@632
   115
      .distMap(dist_map)
kpeter@632
   116
      .reachedMap(reached_map)
kpeter@632
   117
      .processedMap(processed_map);
alpar@100
   118
kpeter@286
   119
    bfs_test.run(s);
kpeter@286
   120
    bfs_test.run(s,t);
kpeter@286
   121
    bfs_test.run();
kpeter@632
   122
    
kpeter@632
   123
    bfs_test.init();
kpeter@632
   124
    bfs_test.addSource(s);
kpeter@632
   125
    n = bfs_test.processNextNode();
kpeter@632
   126
    n = bfs_test.processNextNode(t, b);
kpeter@632
   127
    n = bfs_test.processNextNode(nm, n);
kpeter@632
   128
    n = bfs_test.nextNode();
kpeter@632
   129
    b = bfs_test.emptyQueue();
kpeter@632
   130
    i = bfs_test.queueSize();
kpeter@632
   131
    
kpeter@632
   132
    bfs_test.start();
kpeter@632
   133
    bfs_test.start(t);
kpeter@632
   134
    bfs_test.start(nm);
kpeter@286
   135
kpeter@286
   136
    l  = bfs_test.dist(t);
kpeter@286
   137
    e  = bfs_test.predArc(t);
kpeter@286
   138
    s  = bfs_test.predNode(t);
kpeter@286
   139
    b  = bfs_test.reached(t);
kpeter@286
   140
    pp = bfs_test.path(t);
kpeter@286
   141
  }
alpar@100
   142
}
alpar@100
   143
alpar@209
   144
void checkBfsFunctionCompile()
alpar@100
   145
{
alpar@100
   146
  typedef int VType;
alpar@100
   147
  typedef concepts::Digraph Digraph;
alpar@100
   148
  typedef Digraph::Arc Arc;
alpar@100
   149
  typedef Digraph::Node Node;
alpar@209
   150
alpar@100
   151
  Digraph g;
kpeter@278
   152
  bool b;
kpeter@278
   153
  bfs(g).run(Node());
kpeter@278
   154
  b=bfs(g).run(Node(),Node());
kpeter@278
   155
  bfs(g).run();
alpar@100
   156
  bfs(g)
kpeter@278
   157
    .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278
   158
    .distMap(concepts::ReadWriteMap<Node,VType>())
alpar@100
   159
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
alpar@100
   160
    .processedMap(concepts::WriteMap<Node,bool>())
alpar@100
   161
    .run(Node());
kpeter@278
   162
  b=bfs(g)
kpeter@278
   163
    .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278
   164
    .distMap(concepts::ReadWriteMap<Node,VType>())
kpeter@278
   165
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
kpeter@278
   166
    .processedMap(concepts::WriteMap<Node,bool>())
kpeter@278
   167
    .path(concepts::Path<Digraph>())
kpeter@278
   168
    .dist(VType())
kpeter@278
   169
    .run(Node(),Node());
kpeter@278
   170
  bfs(g)
kpeter@278
   171
    .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278
   172
    .distMap(concepts::ReadWriteMap<Node,VType>())
kpeter@278
   173
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
kpeter@278
   174
    .processedMap(concepts::WriteMap<Node,bool>())
kpeter@278
   175
    .run();
alpar@100
   176
}
alpar@100
   177
kpeter@171
   178
template <class Digraph>
kpeter@171
   179
void checkBfs() {
kpeter@171
   180
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
alpar@100
   181
alpar@100
   182
  Digraph G;
alpar@100
   183
  Node s, t;
alpar@209
   184
deba@228
   185
  std::istringstream input(test_lgf);
kpeter@293
   186
  digraphReader(G, input).
deba@228
   187
    node("source", s).
deba@228
   188
    node("target", t).
deba@228
   189
    run();
alpar@209
   190
alpar@100
   191
  Bfs<Digraph> bfs_test(G);
alpar@100
   192
  bfs_test.run(s);
alpar@209
   193
kpeter@278
   194
  check(bfs_test.dist(t)==2,"Bfs found a wrong path.");
alpar@100
   195
alpar@100
   196
  Path<Digraph> p = bfs_test.path(t);
deba@228
   197
  check(p.length()==2,"path() found a wrong path.");
alpar@100
   198
  check(checkPath(G, p),"path() found a wrong path.");
alpar@100
   199
  check(pathSource(G, p) == s,"path() found a wrong path.");
alpar@100
   200
  check(pathTarget(G, p) == t,"path() found a wrong path.");
alpar@209
   201
alpar@100
   202
deba@228
   203
  for(ArcIt a(G); a!=INVALID; ++a) {
deba@228
   204
    Node u=G.source(a);
deba@228
   205
    Node v=G.target(a);
alpar@100
   206
    check( !bfs_test.reached(u) ||
deba@222
   207
           (bfs_test.dist(v) <= bfs_test.dist(u)+1),
kpeter@278
   208
           "Wrong output. " << G.id(u) << "->" << G.id(v));
alpar@100
   209
  }
alpar@100
   210
deba@222
   211
  for(NodeIt v(G); v!=INVALID; ++v) {
deba@228
   212
    if (bfs_test.reached(v)) {
deba@228
   213
      check(v==s || bfs_test.predArc(v)!=INVALID, "Wrong tree.");
deba@228
   214
      if (bfs_test.predArc(v)!=INVALID ) {
deba@228
   215
        Arc a=bfs_test.predArc(v);
deba@228
   216
        Node u=G.source(a);
deba@228
   217
        check(u==bfs_test.predNode(v),"Wrong tree.");
deba@228
   218
        check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
deba@228
   219
              "Wrong distance. Difference: "
kpeter@278
   220
              << std::abs(bfs_test.dist(v) - bfs_test.dist(u) - 1));
deba@228
   221
      }
alpar@100
   222
    }
alpar@100
   223
  }
kpeter@278
   224
kpeter@278
   225
  {
kpeter@278
   226
    NullMap<Node,Arc> myPredMap;
kpeter@278
   227
    bfs(G).predMap(myPredMap).run(s);
kpeter@278
   228
  }
alpar@100
   229
}
alpar@100
   230
kpeter@171
   231
int main()
kpeter@171
   232
{
kpeter@171
   233
  checkBfs<ListDigraph>();
kpeter@171
   234
  checkBfs<SmartDigraph>();
kpeter@171
   235
  return 0;
kpeter@171
   236
}