alpar@209: /* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@100:  *
alpar@209:  * This file is a part of LEMON, a generic C++ optimization library.
alpar@100:  *
alpar@100:  * Copyright (C) 2003-2008
alpar@100:  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@100:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@100:  *
alpar@100:  * Permission to use, modify and distribute this software is granted
alpar@100:  * provided that this copyright notice appears in all copies. For
alpar@100:  * precise terms see the accompanying LICENSE file.
alpar@100:  *
alpar@100:  * This software is provided "AS IS" with no warranty of any kind,
alpar@100:  * express or implied, and with no claim as to its suitability for any
alpar@100:  * purpose.
alpar@100:  *
alpar@100:  */
alpar@100: 
kpeter@171: #include <lemon/concepts/digraph.h>
kpeter@171: #include <lemon/smart_graph.h>
alpar@100: #include <lemon/list_graph.h>
deba@228: #include <lemon/lgf_reader.h>
alpar@100: #include <lemon/bfs.h>
alpar@100: #include <lemon/path.h>
kpeter@171: 
kpeter@171: #include "graph_test.h"
kpeter@171: #include "test_tools.h"
alpar@100: 
alpar@100: using namespace lemon;
alpar@100: 
deba@228: char test_lgf[] =
deba@228:   "@nodes\n"
deba@228:   "label\n"
deba@228:   "0\n"
deba@228:   "1\n"
deba@228:   "2\n"
deba@228:   "3\n"
deba@228:   "4\n"
deba@228:   "5\n"
deba@228:   "@arcs\n"
deba@228:   "     label\n"
deba@228:   "0 1  0\n"
deba@228:   "1 2  1\n"
deba@228:   "2 3  2\n"
deba@228:   "3 4  3\n"
deba@228:   "0 3  4\n"
deba@228:   "0 3  5\n"
deba@228:   "5 2  6\n"
deba@228:   "@attributes\n"
deba@228:   "source 0\n"
deba@228:   "target 4\n";
deba@228: 
alpar@209: void checkBfsCompile()
alpar@100: {
alpar@100:   typedef concepts::Digraph Digraph;
alpar@100:   typedef Bfs<Digraph> BType;
kpeter@286:   typedef Digraph::Node Node;
kpeter@286:   typedef Digraph::Arc Arc;
alpar@209: 
alpar@100:   Digraph G;
kpeter@286:   Node s, t;
kpeter@286:   Arc e;
alpar@100:   int l;
alpar@100:   bool b;
alpar@100:   BType::DistMap d(G);
alpar@100:   BType::PredMap p(G);
kpeter@286:   Path<Digraph> pp;
alpar@209: 
kpeter@286:   {
kpeter@286:     BType bfs_test(G);
alpar@209: 
kpeter@286:     bfs_test.run(s);
kpeter@286:     bfs_test.run(s,t);
kpeter@286:     bfs_test.run();
alpar@209: 
kpeter@286:     l  = bfs_test.dist(t);
kpeter@286:     e  = bfs_test.predArc(t);
kpeter@286:     s  = bfs_test.predNode(t);
kpeter@286:     b  = bfs_test.reached(t);
kpeter@286:     d  = bfs_test.distMap();
kpeter@286:     p  = bfs_test.predMap();
kpeter@286:     pp = bfs_test.path(t);
kpeter@286:   }
kpeter@286:   {
kpeter@286:     BType
kpeter@286:       ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
kpeter@286:       ::SetDistMap<concepts::ReadWriteMap<Node,int> >
kpeter@286:       ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
kpeter@286:       ::SetProcessedMap<concepts::WriteMap<Node,bool> >
kpeter@286:       ::SetStandardProcessedMap
kpeter@286:       ::Create bfs_test(G);
alpar@100: 
kpeter@286:     bfs_test.run(s);
kpeter@286:     bfs_test.run(s,t);
kpeter@286:     bfs_test.run();
kpeter@286: 
kpeter@286:     l  = bfs_test.dist(t);
kpeter@286:     e  = bfs_test.predArc(t);
kpeter@286:     s  = bfs_test.predNode(t);
kpeter@286:     b  = bfs_test.reached(t);
kpeter@286:     pp = bfs_test.path(t);
kpeter@286:   }
alpar@100: }
alpar@100: 
alpar@209: void checkBfsFunctionCompile()
alpar@100: {
alpar@100:   typedef int VType;
alpar@100:   typedef concepts::Digraph Digraph;
alpar@100:   typedef Digraph::Arc Arc;
alpar@100:   typedef Digraph::Node Node;
alpar@209: 
alpar@100:   Digraph g;
kpeter@278:   bool b;
kpeter@278:   bfs(g).run(Node());
kpeter@278:   b=bfs(g).run(Node(),Node());
kpeter@278:   bfs(g).run();
alpar@100:   bfs(g)
kpeter@278:     .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278:     .distMap(concepts::ReadWriteMap<Node,VType>())
alpar@100:     .reachedMap(concepts::ReadWriteMap<Node,bool>())
alpar@100:     .processedMap(concepts::WriteMap<Node,bool>())
alpar@100:     .run(Node());
kpeter@278:   b=bfs(g)
kpeter@278:     .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278:     .distMap(concepts::ReadWriteMap<Node,VType>())
kpeter@278:     .reachedMap(concepts::ReadWriteMap<Node,bool>())
kpeter@278:     .processedMap(concepts::WriteMap<Node,bool>())
kpeter@278:     .path(concepts::Path<Digraph>())
kpeter@278:     .dist(VType())
kpeter@278:     .run(Node(),Node());
kpeter@278:   bfs(g)
kpeter@278:     .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278:     .distMap(concepts::ReadWriteMap<Node,VType>())
kpeter@278:     .reachedMap(concepts::ReadWriteMap<Node,bool>())
kpeter@278:     .processedMap(concepts::WriteMap<Node,bool>())
kpeter@278:     .run();
alpar@100: }
alpar@100: 
kpeter@171: template <class Digraph>
kpeter@171: void checkBfs() {
kpeter@171:   TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
alpar@100: 
alpar@100:   Digraph G;
alpar@100:   Node s, t;
alpar@209: 
deba@228:   std::istringstream input(test_lgf);
kpeter@293:   digraphReader(G, input).
deba@228:     node("source", s).
deba@228:     node("target", t).
deba@228:     run();
alpar@209: 
alpar@100:   Bfs<Digraph> bfs_test(G);
alpar@100:   bfs_test.run(s);
alpar@209: 
kpeter@278:   check(bfs_test.dist(t)==2,"Bfs found a wrong path.");
alpar@100: 
alpar@100:   Path<Digraph> p = bfs_test.path(t);
deba@228:   check(p.length()==2,"path() found a wrong path.");
alpar@100:   check(checkPath(G, p),"path() found a wrong path.");
alpar@100:   check(pathSource(G, p) == s,"path() found a wrong path.");
alpar@100:   check(pathTarget(G, p) == t,"path() found a wrong path.");
alpar@209: 
alpar@100: 
deba@228:   for(ArcIt a(G); a!=INVALID; ++a) {
deba@228:     Node u=G.source(a);
deba@228:     Node v=G.target(a);
alpar@100:     check( !bfs_test.reached(u) ||
deba@222:            (bfs_test.dist(v) <= bfs_test.dist(u)+1),
kpeter@278:            "Wrong output. " << G.id(u) << "->" << G.id(v));
alpar@100:   }
alpar@100: 
deba@222:   for(NodeIt v(G); v!=INVALID; ++v) {
deba@228:     if (bfs_test.reached(v)) {
deba@228:       check(v==s || bfs_test.predArc(v)!=INVALID, "Wrong tree.");
deba@228:       if (bfs_test.predArc(v)!=INVALID ) {
deba@228:         Arc a=bfs_test.predArc(v);
deba@228:         Node u=G.source(a);
deba@228:         check(u==bfs_test.predNode(v),"Wrong tree.");
deba@228:         check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
deba@228:               "Wrong distance. Difference: "
kpeter@278:               << std::abs(bfs_test.dist(v) - bfs_test.dist(u) - 1));
deba@228:       }
alpar@100:     }
alpar@100:   }
kpeter@278: 
kpeter@278:   {
kpeter@278:     NullMap<Node,Arc> myPredMap;
kpeter@278:     bfs(G).predMap(myPredMap).run(s);
kpeter@278:   }
alpar@100: }
alpar@100: 
kpeter@171: int main()
kpeter@171: {
kpeter@171:   checkBfs<ListDigraph>();
kpeter@171:   checkBfs<SmartDigraph>();
kpeter@171:   return 0;
kpeter@171: }