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