test/euler_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 17 Apr 2009 18:04:36 +0200
changeset 601 e6927fe719e6
parent 506 22f932bbb305
child 584 2ebfdb89ec66
permissions -rw-r--r--
Support >= and <= constraints in NetworkSimplex (#219, #234)

By default the same inequality constraints are supported as by
Circulation (the GEQ form), but the LEQ form can also be selected
using the problemType() function.

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