ladanyi@522: /* -*- mode: C++; indent-tabs-mode: nil; -*-
ladanyi@522:  *
ladanyi@522:  * This file is a part of LEMON, a generic C++ optimization library.
ladanyi@522:  *
ladanyi@522:  * Copyright (C) 2003-2009
ladanyi@522:  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
ladanyi@522:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
ladanyi@522:  *
ladanyi@522:  * Permission to use, modify and distribute this software is granted
ladanyi@522:  * provided that this copyright notice appears in all copies. For
ladanyi@522:  * precise terms see the accompanying LICENSE file.
ladanyi@522:  *
ladanyi@522:  * This software is provided "AS IS" with no warranty of any kind,
ladanyi@522:  * express or implied, and with no claim as to its suitability for any
ladanyi@522:  * purpose.
ladanyi@522:  *
ladanyi@522:  */
ladanyi@522: 
ladanyi@522: #include <lemon/euler.h>
ladanyi@522: #include <lemon/list_graph.h>
ladanyi@522: #include <test/test_tools.h>
ladanyi@522: 
ladanyi@522: using namespace lemon;
ladanyi@522: 
ladanyi@522: template <typename Digraph>
ladanyi@522: void checkDiEulerIt(const Digraph& g)
ladanyi@522: {
kpeter@531:   typename Digraph::template ArcMap<int> visitationNumber(g, 0);
ladanyi@522: 
ladanyi@522:   DiEulerIt<Digraph> e(g);
ladanyi@522:   typename Digraph::Node firstNode = g.source(e);
kpeter@531:   typename Digraph::Node lastNode = g.target(e);
ladanyi@522: 
ladanyi@522:   for (; e != INVALID; ++e)
ladanyi@522:   {
ladanyi@522:     if (e != INVALID)
ladanyi@522:     {
ladanyi@522:       lastNode = g.target(e);
ladanyi@522:     }
ladanyi@522:     ++visitationNumber[e];
ladanyi@522:   }
ladanyi@522: 
ladanyi@522:   check(firstNode == lastNode,
ladanyi@522:       "checkDiEulerIt: first and last node are not the same");
ladanyi@522: 
ladanyi@522:   for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
ladanyi@522:   {
ladanyi@522:     check(visitationNumber[a] == 1,
ladanyi@522:         "checkDiEulerIt: not visited or multiple times visited arc found");
ladanyi@522:   }
ladanyi@522: }
ladanyi@522: 
ladanyi@522: template <typename Graph>
ladanyi@522: void checkEulerIt(const Graph& g)
ladanyi@522: {
kpeter@531:   typename Graph::template EdgeMap<int> visitationNumber(g, 0);
ladanyi@522: 
ladanyi@522:   EulerIt<Graph> e(g);
ladanyi@522:   typename Graph::Node firstNode = g.u(e);
kpeter@531:   typename Graph::Node lastNode = g.v(e);
ladanyi@522: 
ladanyi@522:   for (; e != INVALID; ++e)
ladanyi@522:   {
ladanyi@522:     if (e != INVALID)
ladanyi@522:     {
ladanyi@522:       lastNode = g.v(e);
ladanyi@522:     }
ladanyi@522:     ++visitationNumber[e];
ladanyi@522:   }
ladanyi@522: 
ladanyi@522:   check(firstNode == lastNode,
ladanyi@522:       "checkEulerIt: first and last node are not the same");
ladanyi@522: 
ladanyi@522:   for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
ladanyi@522:   {
ladanyi@522:     check(visitationNumber[e] == 1,
ladanyi@522:         "checkEulerIt: not visited or multiple times visited edge found");
ladanyi@522:   }
ladanyi@522: }
ladanyi@522: 
ladanyi@522: int main()
ladanyi@522: {
ladanyi@522:   typedef ListDigraph Digraph;
ladanyi@522:   typedef ListGraph Graph;
ladanyi@522: 
ladanyi@522:   Digraph digraphWithEulerianCircuit;
ladanyi@522:   {
ladanyi@522:     Digraph& g = digraphWithEulerianCircuit;
ladanyi@522: 
ladanyi@522:     Digraph::Node n0 = g.addNode();
ladanyi@522:     Digraph::Node n1 = g.addNode();
ladanyi@522:     Digraph::Node n2 = g.addNode();
ladanyi@522: 
ladanyi@522:     g.addArc(n0, n1);
ladanyi@522:     g.addArc(n1, n0);
ladanyi@522:     g.addArc(n1, n2);
ladanyi@522:     g.addArc(n2, n1);
ladanyi@522:   }
ladanyi@522: 
ladanyi@522:   Digraph digraphWithoutEulerianCircuit;
ladanyi@522:   {
ladanyi@522:     Digraph& g = digraphWithoutEulerianCircuit;
ladanyi@522: 
ladanyi@522:     Digraph::Node n0 = g.addNode();
ladanyi@522:     Digraph::Node n1 = g.addNode();
ladanyi@522:     Digraph::Node n2 = g.addNode();
ladanyi@522: 
ladanyi@522:     g.addArc(n0, n1);
ladanyi@522:     g.addArc(n1, n0);
ladanyi@522:     g.addArc(n1, n2);
ladanyi@522:   }
ladanyi@522: 
ladanyi@522:   Graph graphWithEulerianCircuit;
ladanyi@522:   {
ladanyi@522:     Graph& g = graphWithEulerianCircuit;
ladanyi@522: 
ladanyi@522:     Graph::Node n0 = g.addNode();
ladanyi@522:     Graph::Node n1 = g.addNode();
ladanyi@522:     Graph::Node n2 = g.addNode();
ladanyi@522: 
ladanyi@522:     g.addEdge(n0, n1);
ladanyi@522:     g.addEdge(n1, n2);
ladanyi@522:     g.addEdge(n2, n0);
ladanyi@522:   }
ladanyi@522: 
ladanyi@522:   Graph graphWithoutEulerianCircuit;
ladanyi@522:   {
ladanyi@522:     Graph& g = graphWithoutEulerianCircuit;
ladanyi@522: 
ladanyi@522:     Graph::Node n0 = g.addNode();
ladanyi@522:     Graph::Node n1 = g.addNode();
ladanyi@522:     Graph::Node n2 = g.addNode();
ladanyi@522: 
ladanyi@522:     g.addEdge(n0, n1);
ladanyi@522:     g.addEdge(n1, n2);
ladanyi@522:   }
ladanyi@522: 
ladanyi@522:   checkDiEulerIt(digraphWithEulerianCircuit);
ladanyi@522: 
ladanyi@522:   checkEulerIt(graphWithEulerianCircuit);
ladanyi@522: 
ladanyi@522:   check(eulerian(digraphWithEulerianCircuit),
ladanyi@522:       "this graph should have an Eulerian circuit");
ladanyi@522:   check(!eulerian(digraphWithoutEulerianCircuit),
ladanyi@522:       "this graph should not have an Eulerian circuit");
ladanyi@522: 
ladanyi@522:   check(eulerian(graphWithEulerianCircuit),
ladanyi@522:       "this graph should have an Eulerian circuit");
ladanyi@522:   check(!eulerian(graphWithoutEulerianCircuit),
ladanyi@522:       "this graph should have an Eulerian circuit");
ladanyi@522: 
ladanyi@522:   return 0;
ladanyi@522: }