test/euler_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 03 Apr 2009 18:59:15 +0200
changeset 655 6ac5d9ae1d3d
parent 569 22f932bbb305
child 639 2ebfdb89ec66
permissions -rw-r--r--
Support real types + numerical stability fix in NS (#254)

- Real types are supported by appropriate inicialization.
- A feature of the XTI spanning tree structure is removed to ensure
numerical stability (could cause problems using integer types).
The node potentials are updated always on the lower subtree,
in order to prevent overflow problems.
The former method isn't notably faster during to our tests.
ladanyi@569
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
ladanyi@569
     2
 *
ladanyi@569
     3
 * This file is a part of LEMON, a generic C++ optimization library.
ladanyi@569
     4
 *
ladanyi@569
     5
 * Copyright (C) 2003-2009
ladanyi@569
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
ladanyi@569
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
ladanyi@569
     8
 *
ladanyi@569
     9
 * Permission to use, modify and distribute this software is granted
ladanyi@569
    10
 * provided that this copyright notice appears in all copies. For
ladanyi@569
    11
 * precise terms see the accompanying LICENSE file.
ladanyi@569
    12
 *
ladanyi@569
    13
 * This software is provided "AS IS" with no warranty of any kind,
ladanyi@569
    14
 * express or implied, and with no claim as to its suitability for any
ladanyi@569
    15
 * purpose.
ladanyi@569
    16
 *
ladanyi@569
    17
 */
ladanyi@569
    18
ladanyi@569
    19
#include <lemon/euler.h>
ladanyi@569
    20
#include <lemon/list_graph.h>
ladanyi@569
    21
#include <test/test_tools.h>
ladanyi@569
    22
ladanyi@569
    23
using namespace lemon;
ladanyi@569
    24
ladanyi@569
    25
template <typename Digraph>
ladanyi@569
    26
void checkDiEulerIt(const Digraph& g)
ladanyi@569
    27
{
kpeter@578
    28
  typename Digraph::template ArcMap<int> visitationNumber(g, 0);
ladanyi@569
    29
ladanyi@569
    30
  DiEulerIt<Digraph> e(g);
ladanyi@569
    31
  typename Digraph::Node firstNode = g.source(e);
kpeter@578
    32
  typename Digraph::Node lastNode = g.target(e);
ladanyi@569
    33
ladanyi@569
    34
  for (; e != INVALID; ++e)
ladanyi@569
    35
  {
ladanyi@569
    36
    if (e != INVALID)
ladanyi@569
    37
    {
ladanyi@569
    38
      lastNode = g.target(e);
ladanyi@569
    39
    }
ladanyi@569
    40
    ++visitationNumber[e];
ladanyi@569
    41
  }
ladanyi@569
    42
ladanyi@569
    43
  check(firstNode == lastNode,
ladanyi@569
    44
      "checkDiEulerIt: first and last node are not the same");
ladanyi@569
    45
ladanyi@569
    46
  for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
ladanyi@569
    47
  {
ladanyi@569
    48
    check(visitationNumber[a] == 1,
ladanyi@569
    49
        "checkDiEulerIt: not visited or multiple times visited arc found");
ladanyi@569
    50
  }
ladanyi@569
    51
}
ladanyi@569
    52
ladanyi@569
    53
template <typename Graph>
ladanyi@569
    54
void checkEulerIt(const Graph& g)
ladanyi@569
    55
{
kpeter@578
    56
  typename Graph::template EdgeMap<int> visitationNumber(g, 0);
ladanyi@569
    57
ladanyi@569
    58
  EulerIt<Graph> e(g);
ladanyi@569
    59
  typename Graph::Node firstNode = g.u(e);
kpeter@578
    60
  typename Graph::Node lastNode = g.v(e);
ladanyi@569
    61
ladanyi@569
    62
  for (; e != INVALID; ++e)
ladanyi@569
    63
  {
ladanyi@569
    64
    if (e != INVALID)
ladanyi@569
    65
    {
ladanyi@569
    66
      lastNode = g.v(e);
ladanyi@569
    67
    }
ladanyi@569
    68
    ++visitationNumber[e];
ladanyi@569
    69
  }
ladanyi@569
    70
ladanyi@569
    71
  check(firstNode == lastNode,
ladanyi@569
    72
      "checkEulerIt: first and last node are not the same");
ladanyi@569
    73
ladanyi@569
    74
  for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
ladanyi@569
    75
  {
ladanyi@569
    76
    check(visitationNumber[e] == 1,
ladanyi@569
    77
        "checkEulerIt: not visited or multiple times visited edge found");
ladanyi@569
    78
  }
ladanyi@569
    79
}
ladanyi@569
    80
ladanyi@569
    81
int main()
ladanyi@569
    82
{
ladanyi@569
    83
  typedef ListDigraph Digraph;
ladanyi@569
    84
  typedef ListGraph Graph;
ladanyi@569
    85
ladanyi@569
    86
  Digraph digraphWithEulerianCircuit;
ladanyi@569
    87
  {
ladanyi@569
    88
    Digraph& g = digraphWithEulerianCircuit;
ladanyi@569
    89
ladanyi@569
    90
    Digraph::Node n0 = g.addNode();
ladanyi@569
    91
    Digraph::Node n1 = g.addNode();
ladanyi@569
    92
    Digraph::Node n2 = g.addNode();
ladanyi@569
    93
ladanyi@569
    94
    g.addArc(n0, n1);
ladanyi@569
    95
    g.addArc(n1, n0);
ladanyi@569
    96
    g.addArc(n1, n2);
ladanyi@569
    97
    g.addArc(n2, n1);
ladanyi@569
    98
  }
ladanyi@569
    99
ladanyi@569
   100
  Digraph digraphWithoutEulerianCircuit;
ladanyi@569
   101
  {
ladanyi@569
   102
    Digraph& g = digraphWithoutEulerianCircuit;
ladanyi@569
   103
ladanyi@569
   104
    Digraph::Node n0 = g.addNode();
ladanyi@569
   105
    Digraph::Node n1 = g.addNode();
ladanyi@569
   106
    Digraph::Node n2 = g.addNode();
ladanyi@569
   107
ladanyi@569
   108
    g.addArc(n0, n1);
ladanyi@569
   109
    g.addArc(n1, n0);
ladanyi@569
   110
    g.addArc(n1, n2);
ladanyi@569
   111
  }
ladanyi@569
   112
ladanyi@569
   113
  Graph graphWithEulerianCircuit;
ladanyi@569
   114
  {
ladanyi@569
   115
    Graph& g = graphWithEulerianCircuit;
ladanyi@569
   116
ladanyi@569
   117
    Graph::Node n0 = g.addNode();
ladanyi@569
   118
    Graph::Node n1 = g.addNode();
ladanyi@569
   119
    Graph::Node n2 = g.addNode();
ladanyi@569
   120
ladanyi@569
   121
    g.addEdge(n0, n1);
ladanyi@569
   122
    g.addEdge(n1, n2);
ladanyi@569
   123
    g.addEdge(n2, n0);
ladanyi@569
   124
  }
ladanyi@569
   125
ladanyi@569
   126
  Graph graphWithoutEulerianCircuit;
ladanyi@569
   127
  {
ladanyi@569
   128
    Graph& g = graphWithoutEulerianCircuit;
ladanyi@569
   129
ladanyi@569
   130
    Graph::Node n0 = g.addNode();
ladanyi@569
   131
    Graph::Node n1 = g.addNode();
ladanyi@569
   132
    Graph::Node n2 = g.addNode();
ladanyi@569
   133
ladanyi@569
   134
    g.addEdge(n0, n1);
ladanyi@569
   135
    g.addEdge(n1, n2);
ladanyi@569
   136
  }
ladanyi@569
   137
ladanyi@569
   138
  checkDiEulerIt(digraphWithEulerianCircuit);
ladanyi@569
   139
ladanyi@569
   140
  checkEulerIt(graphWithEulerianCircuit);
ladanyi@569
   141
ladanyi@569
   142
  check(eulerian(digraphWithEulerianCircuit),
ladanyi@569
   143
      "this graph should have an Eulerian circuit");
ladanyi@569
   144
  check(!eulerian(digraphWithoutEulerianCircuit),
ladanyi@569
   145
      "this graph should not have an Eulerian circuit");
ladanyi@569
   146
ladanyi@569
   147
  check(eulerian(graphWithEulerianCircuit),
ladanyi@569
   148
      "this graph should have an Eulerian circuit");
ladanyi@569
   149
  check(!eulerian(graphWithoutEulerianCircuit),
ladanyi@569
   150
      "this graph should have an Eulerian circuit");
ladanyi@569
   151
ladanyi@569
   152
  return 0;
ladanyi@569
   153
}