test/dfs_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 877 141f9c0db4a3
parent 906 e24922c56bc2
child 966 c8fce9beb46a
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
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@877
     5
 * Copyright (C) 2003-2010
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/dfs.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
  "6\n"
deba@228
    41
  "@arcs\n"
deba@228
    42
  "     label\n"
deba@228
    43
  "0 1  0\n"
deba@228
    44
  "1 2  1\n"
deba@228
    45
  "2 3  2\n"
deba@228
    46
  "1 4  3\n"
deba@228
    47
  "4 2  4\n"
deba@228
    48
  "4 5  5\n"
deba@228
    49
  "5 0  6\n"
deba@228
    50
  "6 3  7\n"
deba@228
    51
  "@attributes\n"
deba@228
    52
  "source 0\n"
alpar@906
    53
  "target 5\n"
alpar@906
    54
  "source1 6\n"
alpar@906
    55
  "target1 3\n";
alpar@906
    56
deba@228
    57
alpar@209
    58
void checkDfsCompile()
alpar@100
    59
{
alpar@100
    60
  typedef concepts::Digraph Digraph;
alpar@100
    61
  typedef Dfs<Digraph> DType;
kpeter@286
    62
  typedef Digraph::Node Node;
kpeter@286
    63
  typedef Digraph::Arc Arc;
alpar@209
    64
alpar@100
    65
  Digraph G;
kpeter@286
    66
  Node s, t;
kpeter@286
    67
  Arc e;
kpeter@585
    68
  int l, i;
alpar@100
    69
  bool b;
alpar@100
    70
  DType::DistMap d(G);
alpar@100
    71
  DType::PredMap p(G);
kpeter@286
    72
  Path<Digraph> pp;
kpeter@585
    73
  concepts::ReadMap<Arc,bool> am;
alpar@209
    74
kpeter@286
    75
  {
kpeter@286
    76
    DType dfs_test(G);
kpeter@585
    77
    const DType& const_dfs_test = dfs_test;
alpar@209
    78
kpeter@286
    79
    dfs_test.run(s);
kpeter@286
    80
    dfs_test.run(s,t);
kpeter@286
    81
    dfs_test.run();
alpar@209
    82
kpeter@585
    83
    dfs_test.init();
kpeter@585
    84
    dfs_test.addSource(s);
kpeter@585
    85
    e = dfs_test.processNextArc();
kpeter@585
    86
    e = const_dfs_test.nextArc();
kpeter@585
    87
    b = const_dfs_test.emptyQueue();
kpeter@585
    88
    i = const_dfs_test.queueSize();
alpar@877
    89
kpeter@585
    90
    dfs_test.start();
kpeter@585
    91
    dfs_test.start(t);
kpeter@585
    92
    dfs_test.start(am);
kpeter@585
    93
kpeter@585
    94
    l  = const_dfs_test.dist(t);
kpeter@585
    95
    e  = const_dfs_test.predArc(t);
kpeter@585
    96
    s  = const_dfs_test.predNode(t);
kpeter@585
    97
    b  = const_dfs_test.reached(t);
kpeter@585
    98
    d  = const_dfs_test.distMap();
kpeter@585
    99
    p  = const_dfs_test.predMap();
kpeter@585
   100
    pp = const_dfs_test.path(t);
kpeter@286
   101
  }
kpeter@286
   102
  {
kpeter@286
   103
    DType
kpeter@286
   104
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
kpeter@286
   105
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
kpeter@286
   106
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
kpeter@585
   107
      ::SetStandardProcessedMap
kpeter@286
   108
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
kpeter@286
   109
      ::Create dfs_test(G);
alpar@100
   110
kpeter@585
   111
    concepts::ReadWriteMap<Node,Arc> pred_map;
kpeter@585
   112
    concepts::ReadWriteMap<Node,int> dist_map;
kpeter@585
   113
    concepts::ReadWriteMap<Node,bool> reached_map;
kpeter@585
   114
    concepts::WriteMap<Node,bool> processed_map;
alpar@877
   115
kpeter@585
   116
    dfs_test
kpeter@585
   117
      .predMap(pred_map)
kpeter@585
   118
      .distMap(dist_map)
kpeter@585
   119
      .reachedMap(reached_map)
kpeter@585
   120
      .processedMap(processed_map);
kpeter@585
   121
kpeter@286
   122
    dfs_test.run(s);
kpeter@286
   123
    dfs_test.run(s,t);
kpeter@286
   124
    dfs_test.run();
kpeter@585
   125
    dfs_test.init();
kpeter@585
   126
kpeter@585
   127
    dfs_test.addSource(s);
kpeter@585
   128
    e = dfs_test.processNextArc();
kpeter@585
   129
    e = dfs_test.nextArc();
kpeter@585
   130
    b = dfs_test.emptyQueue();
kpeter@585
   131
    i = dfs_test.queueSize();
alpar@877
   132
kpeter@585
   133
    dfs_test.start();
kpeter@585
   134
    dfs_test.start(t);
kpeter@585
   135
    dfs_test.start(am);
kpeter@286
   136
kpeter@286
   137
    l  = dfs_test.dist(t);
kpeter@286
   138
    e  = dfs_test.predArc(t);
kpeter@286
   139
    s  = dfs_test.predNode(t);
kpeter@286
   140
    b  = dfs_test.reached(t);
kpeter@286
   141
    pp = dfs_test.path(t);
kpeter@286
   142
  }
alpar@100
   143
}
alpar@100
   144
alpar@209
   145
void checkDfsFunctionCompile()
alpar@100
   146
{
alpar@100
   147
  typedef int VType;
alpar@100
   148
  typedef concepts::Digraph Digraph;
alpar@100
   149
  typedef Digraph::Arc Arc;
alpar@100
   150
  typedef Digraph::Node Node;
alpar@209
   151
alpar@100
   152
  Digraph g;
kpeter@278
   153
  bool b;
kpeter@278
   154
  dfs(g).run(Node());
kpeter@278
   155
  b=dfs(g).run(Node(),Node());
kpeter@278
   156
  dfs(g).run();
alpar@100
   157
  dfs(g)
kpeter@278
   158
    .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278
   159
    .distMap(concepts::ReadWriteMap<Node,VType>())
alpar@100
   160
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
alpar@100
   161
    .processedMap(concepts::WriteMap<Node,bool>())
alpar@209
   162
    .run(Node());
kpeter@278
   163
  b=dfs(g)
kpeter@278
   164
    .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278
   165
    .distMap(concepts::ReadWriteMap<Node,VType>())
kpeter@278
   166
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
kpeter@278
   167
    .processedMap(concepts::WriteMap<Node,bool>())
kpeter@278
   168
    .path(concepts::Path<Digraph>())
kpeter@278
   169
    .dist(VType())
kpeter@278
   170
    .run(Node(),Node());
kpeter@278
   171
  dfs(g)
kpeter@278
   172
    .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278
   173
    .distMap(concepts::ReadWriteMap<Node,VType>())
kpeter@278
   174
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
kpeter@278
   175
    .processedMap(concepts::WriteMap<Node,bool>())
kpeter@278
   176
    .run();
alpar@100
   177
}
alpar@100
   178
kpeter@171
   179
template <class Digraph>
kpeter@171
   180
void checkDfs() {
kpeter@171
   181
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
alpar@100
   182
alpar@100
   183
  Digraph G;
alpar@100
   184
  Node s, t;
alpar@906
   185
  Node s1, t1;
alpar@209
   186
deba@228
   187
  std::istringstream input(test_lgf);
kpeter@293
   188
  digraphReader(G, input).
deba@228
   189
    node("source", s).
deba@228
   190
    node("target", t).
alpar@906
   191
    node("source1", s1).
alpar@906
   192
    node("target1", t1).
deba@228
   193
    run();
alpar@209
   194
alpar@100
   195
  Dfs<Digraph> dfs_test(G);
alpar@209
   196
  dfs_test.run(s);
alpar@209
   197
alpar@100
   198
  Path<Digraph> p = dfs_test.path(t);
kpeter@171
   199
  check(p.length() == dfs_test.dist(t),"path() found a wrong path.");
alpar@100
   200
  check(checkPath(G, p),"path() found a wrong path.");
alpar@100
   201
  check(pathSource(G, p) == s,"path() found a wrong path.");
alpar@100
   202
  check(pathTarget(G, p) == t,"path() found a wrong path.");
alpar@209
   203
alpar@100
   204
  for(NodeIt v(G); v!=INVALID; ++v) {
deba@228
   205
    if (dfs_test.reached(v)) {
deba@228
   206
      check(v==s || dfs_test.predArc(v)!=INVALID, "Wrong tree.");
deba@228
   207
      if (dfs_test.predArc(v)!=INVALID ) {
deba@228
   208
        Arc e=dfs_test.predArc(v);
deba@228
   209
        Node u=G.source(e);
deba@228
   210
        check(u==dfs_test.predNode(v),"Wrong tree.");
deba@228
   211
        check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
deba@228
   212
              "Wrong distance. (" << dfs_test.dist(u) << "->"
kpeter@278
   213
              << dfs_test.dist(v) << ")");
deba@228
   214
      }
alpar@100
   215
    }
alpar@100
   216
  }
kpeter@278
   217
kpeter@278
   218
  {
alpar@906
   219
  Dfs<Digraph> dfs(G);
alpar@906
   220
  check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6.");
alpar@906
   221
  }
alpar@906
   222
  
alpar@906
   223
  {
kpeter@278
   224
    NullMap<Node,Arc> myPredMap;
kpeter@278
   225
    dfs(G).predMap(myPredMap).run(s);
kpeter@278
   226
  }
alpar@100
   227
}
alpar@100
   228
kpeter@171
   229
int main()
kpeter@171
   230
{
kpeter@171
   231
  checkDfs<ListDigraph>();
kpeter@171
   232
  checkDfs<SmartDigraph>();
kpeter@171
   233
  return 0;
kpeter@171
   234
}