test/bfs_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 440 88ed40ad0d4f
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.
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@440
     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@585
    61
  Node s, t, n;
kpeter@286
    62
  Arc e;
kpeter@585
    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@585
    68
  concepts::ReadMap<Node,bool> nm;
alpar@209
    69
kpeter@286
    70
  {
kpeter@286
    71
    BType bfs_test(G);
kpeter@585
    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@585
    78
    bfs_test.init();
kpeter@585
    79
    bfs_test.addSource(s);
kpeter@585
    80
    n = bfs_test.processNextNode();
kpeter@585
    81
    n = bfs_test.processNextNode(t, b);
kpeter@585
    82
    n = bfs_test.processNextNode(nm, n);
kpeter@585
    83
    n = const_bfs_test.nextNode();
kpeter@585
    84
    b = const_bfs_test.emptyQueue();
kpeter@585
    85
    i = const_bfs_test.queueSize();
kpeter@585
    86
    
kpeter@585
    87
    bfs_test.start();
kpeter@585
    88
    bfs_test.start(t);
kpeter@585
    89
    bfs_test.start(nm);
kpeter@585
    90
kpeter@585
    91
    l  = const_bfs_test.dist(t);
kpeter@585
    92
    e  = const_bfs_test.predArc(t);
kpeter@585
    93
    s  = const_bfs_test.predNode(t);
kpeter@585
    94
    b  = const_bfs_test.reached(t);
kpeter@585
    95
    d  = const_bfs_test.distMap();
kpeter@585
    96
    p  = const_bfs_test.predMap();
kpeter@585
    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@585
   104
      ::SetStandardProcessedMap
kpeter@286
   105
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
kpeter@286
   106
      ::Create bfs_test(G);
kpeter@585
   107
      
kpeter@585
   108
    concepts::ReadWriteMap<Node,Arc> pred_map;
kpeter@585
   109
    concepts::ReadWriteMap<Node,int> dist_map;
kpeter@585
   110
    concepts::ReadWriteMap<Node,bool> reached_map;
kpeter@585
   111
    concepts::WriteMap<Node,bool> processed_map;
kpeter@585
   112
    
kpeter@585
   113
    bfs_test
kpeter@585
   114
      .predMap(pred_map)
kpeter@585
   115
      .distMap(dist_map)
kpeter@585
   116
      .reachedMap(reached_map)
kpeter@585
   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@585
   122
    
kpeter@585
   123
    bfs_test.init();
kpeter@585
   124
    bfs_test.addSource(s);
kpeter@585
   125
    n = bfs_test.processNextNode();
kpeter@585
   126
    n = bfs_test.processNextNode(t, b);
kpeter@585
   127
    n = bfs_test.processNextNode(nm, n);
kpeter@585
   128
    n = bfs_test.nextNode();
kpeter@585
   129
    b = bfs_test.emptyQueue();
kpeter@585
   130
    i = bfs_test.queueSize();
kpeter@585
   131
    
kpeter@585
   132
    bfs_test.start();
kpeter@585
   133
    bfs_test.start(t);
kpeter@585
   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
}