test/euler_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Sat, 25 Apr 2009 02:12:41 +0200
changeset 623 7c1324b35d89
parent 531 ba7bafdc458d
child 877 141f9c0db4a3
child 997 761fe0846f49
permissions -rw-r--r--
Modify the interface of Suurballe (#266, #181)

- Move the parameters s and t from the constructor to the run()
function. It makes the interface capable for multiple run(s,t,k)
calls (possible improvement in the future) and it is more similar
to Dijkstra.
- Simliarly init() and findFlow(k) were replaced by init(s) and
findFlow(t,k). The separation of parameters s and t is for the
future plans of supporting multiple targets with one source node.
For more information see #181.
- LEMON_ASSERT for the Length type (check if it is integer).
- Doc improvements.
- Rearrange query functions.
- Extend test file.
     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-2009
     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/euler.h>
    20 #include <lemon/list_graph.h>
    21 #include <lemon/adaptors.h>
    22 #include "test_tools.h"
    23 
    24 using namespace lemon;
    25 
    26 template <typename Digraph>
    27 void checkDiEulerIt(const Digraph& g,
    28                     const typename Digraph::Node& start = INVALID)
    29 {
    30   typename Digraph::template ArcMap<int> visitationNumber(g, 0);
    31 
    32   DiEulerIt<Digraph> e(g, start);
    33   if (e == INVALID) return;
    34   typename Digraph::Node firstNode = g.source(e);
    35   typename Digraph::Node lastNode = g.target(e);
    36   if (start != INVALID) {
    37     check(firstNode == start, "checkDiEulerIt: Wrong first node");
    38   }
    39 
    40   for (; e != INVALID; ++e) {
    41     if (e != INVALID) lastNode = g.target(e);
    42     ++visitationNumber[e];
    43   }
    44 
    45   check(firstNode == lastNode,
    46       "checkDiEulerIt: First and last nodes are not the same");
    47 
    48   for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
    49   {
    50     check(visitationNumber[a] == 1,
    51         "checkDiEulerIt: Not visited or multiple times visited arc found");
    52   }
    53 }
    54 
    55 template <typename Graph>
    56 void checkEulerIt(const Graph& g,
    57                   const typename Graph::Node& start = INVALID)
    58 {
    59   typename Graph::template EdgeMap<int> visitationNumber(g, 0);
    60 
    61   EulerIt<Graph> e(g, start);
    62   if (e == INVALID) return;
    63   typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
    64   typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
    65   if (start != INVALID) {
    66     check(firstNode == start, "checkEulerIt: Wrong first node");
    67   }
    68 
    69   for (; e != INVALID; ++e) {
    70     if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
    71     ++visitationNumber[e];
    72   }
    73 
    74   check(firstNode == lastNode,
    75       "checkEulerIt: First and last nodes are not the same");
    76 
    77   for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
    78   {
    79     check(visitationNumber[e] == 1,
    80         "checkEulerIt: Not visited or multiple times visited edge found");
    81   }
    82 }
    83 
    84 int main()
    85 {
    86   typedef ListDigraph Digraph;
    87   typedef Undirector<Digraph> Graph;
    88   
    89   {
    90     Digraph d;
    91     Graph g(d);
    92     
    93     checkDiEulerIt(d);
    94     checkDiEulerIt(g);
    95     checkEulerIt(g);
    96 
    97     check(eulerian(d), "This graph is Eulerian");
    98     check(eulerian(g), "This graph is Eulerian");
    99   }
   100   {
   101     Digraph d;
   102     Graph g(d);
   103     Digraph::Node n = d.addNode();
   104 
   105     checkDiEulerIt(d);
   106     checkDiEulerIt(g);
   107     checkEulerIt(g);
   108 
   109     check(eulerian(d), "This graph is Eulerian");
   110     check(eulerian(g), "This graph is Eulerian");
   111   }
   112   {
   113     Digraph d;
   114     Graph g(d);
   115     Digraph::Node n = d.addNode();
   116     d.addArc(n, n);
   117 
   118     checkDiEulerIt(d);
   119     checkDiEulerIt(g);
   120     checkEulerIt(g);
   121 
   122     check(eulerian(d), "This graph is Eulerian");
   123     check(eulerian(g), "This graph is Eulerian");
   124   }
   125   {
   126     Digraph d;
   127     Graph g(d);
   128     Digraph::Node n1 = d.addNode();
   129     Digraph::Node n2 = d.addNode();
   130     Digraph::Node n3 = d.addNode();
   131     
   132     d.addArc(n1, n2);
   133     d.addArc(n2, n1);
   134     d.addArc(n2, n3);
   135     d.addArc(n3, n2);
   136 
   137     checkDiEulerIt(d);
   138     checkDiEulerIt(d, n2);
   139     checkDiEulerIt(g);
   140     checkDiEulerIt(g, n2);
   141     checkEulerIt(g);
   142     checkEulerIt(g, n2);
   143 
   144     check(eulerian(d), "This graph is Eulerian");
   145     check(eulerian(g), "This graph is Eulerian");
   146   }
   147   {
   148     Digraph d;
   149     Graph g(d);
   150     Digraph::Node n1 = d.addNode();
   151     Digraph::Node n2 = d.addNode();
   152     Digraph::Node n3 = d.addNode();
   153     Digraph::Node n4 = d.addNode();
   154     Digraph::Node n5 = d.addNode();
   155     Digraph::Node n6 = d.addNode();
   156     
   157     d.addArc(n1, n2);
   158     d.addArc(n2, n4);
   159     d.addArc(n1, n3);
   160     d.addArc(n3, n4);
   161     d.addArc(n4, n1);
   162     d.addArc(n3, n5);
   163     d.addArc(n5, n2);
   164     d.addArc(n4, n6);
   165     d.addArc(n2, n6);
   166     d.addArc(n6, n1);
   167     d.addArc(n6, n3);
   168 
   169     checkDiEulerIt(d);
   170     checkDiEulerIt(d, n1);
   171     checkDiEulerIt(d, n5);
   172 
   173     checkDiEulerIt(g);
   174     checkDiEulerIt(g, n1);
   175     checkDiEulerIt(g, n5);
   176     checkEulerIt(g);
   177     checkEulerIt(g, n1);
   178     checkEulerIt(g, n5);
   179 
   180     check(eulerian(d), "This graph is Eulerian");
   181     check(eulerian(g), "This graph is Eulerian");
   182   }
   183   {
   184     Digraph d;
   185     Graph g(d);
   186     Digraph::Node n0 = d.addNode();
   187     Digraph::Node n1 = d.addNode();
   188     Digraph::Node n2 = d.addNode();
   189     Digraph::Node n3 = d.addNode();
   190     Digraph::Node n4 = d.addNode();
   191     Digraph::Node n5 = d.addNode();
   192     
   193     d.addArc(n1, n2);
   194     d.addArc(n2, n3);
   195     d.addArc(n3, n1);
   196 
   197     checkDiEulerIt(d);
   198     checkDiEulerIt(d, n2);
   199 
   200     checkDiEulerIt(g);
   201     checkDiEulerIt(g, n2);
   202     checkEulerIt(g);
   203     checkEulerIt(g, n2);
   204 
   205     check(!eulerian(d), "This graph is not Eulerian");
   206     check(!eulerian(g), "This graph is not Eulerian");
   207   }
   208   {
   209     Digraph d;
   210     Graph g(d);
   211     Digraph::Node n1 = d.addNode();
   212     Digraph::Node n2 = d.addNode();
   213     Digraph::Node n3 = d.addNode();
   214     
   215     d.addArc(n1, n2);
   216     d.addArc(n2, n3);
   217 
   218     check(!eulerian(d), "This graph is not Eulerian");
   219     check(!eulerian(g), "This graph is not Eulerian");
   220   }
   221 
   222   return 0;
   223 }