test/graph_test.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 17 Apr 2009 18:04:36 +0200
changeset 609 e6927fe719e6
parent 374 49d9a36b3b84
child 1019 4c89e925cfe2
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.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
kpeter@171
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
kpeter@171
     4
 *
alpar@440
     5
 * Copyright (C) 2003-2009
kpeter@171
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@171
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@171
     8
 *
kpeter@171
     9
 * Permission to use, modify and distribute this software is granted
kpeter@171
    10
 * provided that this copyright notice appears in all copies. For
kpeter@171
    11
 * precise terms see the accompanying LICENSE file.
kpeter@171
    12
 *
kpeter@171
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@171
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@171
    15
 * purpose.
kpeter@171
    16
 *
kpeter@171
    17
 */
kpeter@171
    18
kpeter@171
    19
#ifndef LEMON_TEST_GRAPH_TEST_H
kpeter@171
    20
#define LEMON_TEST_GRAPH_TEST_H
kpeter@171
    21
deba@228
    22
#include <set>
deba@228
    23
deba@220
    24
#include <lemon/core.h>
deba@228
    25
#include <lemon/maps.h>
deba@228
    26
kpeter@171
    27
#include "test_tools.h"
kpeter@171
    28
kpeter@171
    29
namespace lemon {
kpeter@171
    30
kpeter@171
    31
  template<class Graph>
kpeter@171
    32
  void checkGraphNodeList(const Graph &G, int cnt)
kpeter@171
    33
  {
kpeter@171
    34
    typename Graph::NodeIt n(G);
kpeter@171
    35
    for(int i=0;i<cnt;i++) {
kpeter@171
    36
      check(n!=INVALID,"Wrong Node list linking.");
kpeter@171
    37
      ++n;
kpeter@171
    38
    }
kpeter@171
    39
    check(n==INVALID,"Wrong Node list linking.");
kpeter@171
    40
    check(countNodes(G)==cnt,"Wrong Node number.");
kpeter@171
    41
  }
kpeter@171
    42
kpeter@171
    43
  template<class Graph>
kpeter@171
    44
  void checkGraphArcList(const Graph &G, int cnt)
kpeter@171
    45
  {
kpeter@171
    46
    typename Graph::ArcIt e(G);
kpeter@171
    47
    for(int i=0;i<cnt;i++) {
kpeter@171
    48
      check(e!=INVALID,"Wrong Arc list linking.");
deba@228
    49
      check(G.oppositeNode(G.source(e), e) == G.target(e),
deba@228
    50
            "Wrong opposite node");
deba@228
    51
      check(G.oppositeNode(G.target(e), e) == G.source(e),
deba@228
    52
            "Wrong opposite node");
kpeter@171
    53
      ++e;
kpeter@171
    54
    }
kpeter@171
    55
    check(e==INVALID,"Wrong Arc list linking.");
kpeter@171
    56
    check(countArcs(G)==cnt,"Wrong Arc number.");
kpeter@171
    57
  }
kpeter@171
    58
kpeter@171
    59
  template<class Graph>
kpeter@171
    60
  void checkGraphOutArcList(const Graph &G, typename Graph::Node n, int cnt)
kpeter@171
    61
  {
kpeter@171
    62
    typename Graph::OutArcIt e(G,n);
kpeter@171
    63
    for(int i=0;i<cnt;i++) {
kpeter@171
    64
      check(e!=INVALID,"Wrong OutArc list linking.");
kpeter@171
    65
      check(n==G.source(e),"Wrong OutArc list linking.");
deba@228
    66
      check(n==G.baseNode(e),"Wrong OutArc list linking.");
deba@228
    67
      check(G.target(e)==G.runningNode(e),"Wrong OutArc list linking.");
kpeter@171
    68
      ++e;
kpeter@171
    69
    }
kpeter@171
    70
    check(e==INVALID,"Wrong OutArc list linking.");
kpeter@171
    71
    check(countOutArcs(G,n)==cnt,"Wrong OutArc number.");
kpeter@171
    72
  }
kpeter@171
    73
kpeter@171
    74
  template<class Graph>
kpeter@171
    75
  void checkGraphInArcList(const Graph &G, typename Graph::Node n, int cnt)
kpeter@171
    76
  {
kpeter@171
    77
    typename Graph::InArcIt e(G,n);
kpeter@171
    78
    for(int i=0;i<cnt;i++) {
kpeter@171
    79
      check(e!=INVALID,"Wrong InArc list linking.");
kpeter@171
    80
      check(n==G.target(e),"Wrong InArc list linking.");
deba@228
    81
      check(n==G.baseNode(e),"Wrong OutArc list linking.");
deba@228
    82
      check(G.source(e)==G.runningNode(e),"Wrong OutArc list linking.");
kpeter@171
    83
      ++e;
kpeter@171
    84
    }
kpeter@171
    85
    check(e==INVALID,"Wrong InArc list linking.");
kpeter@171
    86
    check(countInArcs(G,n)==cnt,"Wrong InArc number.");
kpeter@171
    87
  }
kpeter@171
    88
kpeter@171
    89
  template<class Graph>
kpeter@171
    90
  void checkGraphEdgeList(const Graph &G, int cnt)
kpeter@171
    91
  {
kpeter@171
    92
    typename Graph::EdgeIt e(G);
kpeter@171
    93
    for(int i=0;i<cnt;i++) {
kpeter@171
    94
      check(e!=INVALID,"Wrong Edge list linking.");
deba@228
    95
      check(G.oppositeNode(G.u(e), e) == G.v(e), "Wrong opposite node");
deba@228
    96
      check(G.oppositeNode(G.v(e), e) == G.u(e), "Wrong opposite node");
kpeter@171
    97
      ++e;
kpeter@171
    98
    }
kpeter@171
    99
    check(e==INVALID,"Wrong Edge list linking.");
kpeter@171
   100
    check(countEdges(G)==cnt,"Wrong Edge number.");
kpeter@171
   101
  }
kpeter@171
   102
kpeter@171
   103
  template<class Graph>
kpeter@171
   104
  void checkGraphIncEdgeList(const Graph &G, typename Graph::Node n, int cnt)
kpeter@171
   105
  {
kpeter@171
   106
    typename Graph::IncEdgeIt e(G,n);
kpeter@171
   107
    for(int i=0;i<cnt;i++) {
kpeter@171
   108
      check(e!=INVALID,"Wrong IncEdge list linking.");
kpeter@171
   109
      check(n==G.u(e) || n==G.v(e),"Wrong IncEdge list linking.");
deba@228
   110
      check(n==G.baseNode(e),"Wrong OutArc list linking.");
deba@228
   111
      check(G.u(e)==G.runningNode(e) || G.v(e)==G.runningNode(e),
deba@228
   112
            "Wrong OutArc list linking.");
kpeter@171
   113
      ++e;
kpeter@171
   114
    }
kpeter@171
   115
    check(e==INVALID,"Wrong IncEdge list linking.");
kpeter@171
   116
    check(countIncEdges(G,n)==cnt,"Wrong IncEdge number.");
kpeter@171
   117
  }
kpeter@171
   118
deba@228
   119
  template <class Graph>
kpeter@374
   120
  void checkGraphIncEdgeArcLists(const Graph &G, typename Graph::Node n,
kpeter@374
   121
                                 int cnt)
kpeter@374
   122
  {
kpeter@374
   123
    checkGraphIncEdgeList(G, n, cnt);
kpeter@374
   124
    checkGraphOutArcList(G, n, cnt);
kpeter@374
   125
    checkGraphInArcList(G, n, cnt);
kpeter@374
   126
  }
kpeter@374
   127
kpeter@374
   128
  template <class Graph>
deba@228
   129
  void checkGraphConArcList(const Graph &G, int cnt) {
deba@228
   130
    int i = 0;
deba@228
   131
    for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
deba@228
   132
      for (typename Graph::NodeIt v(G); v != INVALID; ++v) {
deba@228
   133
        for (ConArcIt<Graph> a(G, u, v); a != INVALID; ++a) {
deba@228
   134
          check(G.source(a) == u, "Wrong iterator.");
deba@228
   135
          check(G.target(a) == v, "Wrong iterator.");
deba@228
   136
          ++i;
deba@228
   137
        }
deba@228
   138
      }
deba@228
   139
    }
deba@228
   140
    check(cnt == i, "Wrong iterator.");
kpeter@171
   141
  }
kpeter@171
   142
kpeter@171
   143
  template <class Graph>
deba@228
   144
  void checkGraphConEdgeList(const Graph &G, int cnt) {
deba@228
   145
    int i = 0;
deba@228
   146
    for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
deba@228
   147
      for (typename Graph::NodeIt v(G); v != INVALID; ++v) {
deba@228
   148
        for (ConEdgeIt<Graph> e(G, u, v); e != INVALID; ++e) {
deba@228
   149
          check((G.u(e) == u && G.v(e) == v) ||
deba@228
   150
                (G.u(e) == v && G.v(e) == u), "Wrong iterator.");
deba@228
   151
          i += u == v ? 2 : 1;
deba@228
   152
        }
deba@228
   153
      }
deba@228
   154
    }
deba@228
   155
    check(2 * cnt == i, "Wrong iterator.");
kpeter@171
   156
  }
kpeter@171
   157
deba@228
   158
  template <typename Graph>
deba@228
   159
  void checkArcDirections(const Graph& G) {
deba@228
   160
    for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
deba@228
   161
      check(G.source(a) == G.target(G.oppositeArc(a)), "Wrong direction");
deba@228
   162
      check(G.target(a) == G.source(G.oppositeArc(a)), "Wrong direction");
deba@228
   163
      check(G.direct(a, G.direction(a)) == a, "Wrong direction");
kpeter@171
   164
    }
kpeter@171
   165
  }
kpeter@171
   166
deba@228
   167
  template <typename Graph>
deba@228
   168
  void checkNodeIds(const Graph& G) {
deba@228
   169
    std::set<int> values;
deba@228
   170
    for (typename Graph::NodeIt n(G); n != INVALID; ++n) {
deba@228
   171
      check(G.nodeFromId(G.id(n)) == n, "Wrong id");
deba@228
   172
      check(values.find(G.id(n)) == values.end(), "Wrong id");
deba@228
   173
      check(G.id(n) <= G.maxNodeId(), "Wrong maximum id");
deba@228
   174
      values.insert(G.id(n));
kpeter@171
   175
    }
kpeter@171
   176
  }
kpeter@171
   177
deba@228
   178
  template <typename Graph>
deba@228
   179
  void checkArcIds(const Graph& G) {
deba@228
   180
    std::set<int> values;
deba@228
   181
    for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
deba@228
   182
      check(G.arcFromId(G.id(a)) == a, "Wrong id");
deba@228
   183
      check(values.find(G.id(a)) == values.end(), "Wrong id");
deba@228
   184
      check(G.id(a) <= G.maxArcId(), "Wrong maximum id");
deba@228
   185
      values.insert(G.id(a));
deba@228
   186
    }
kpeter@171
   187
  }
alpar@209
   188
deba@228
   189
  template <typename Graph>
deba@228
   190
  void checkEdgeIds(const Graph& G) {
deba@228
   191
    std::set<int> values;
deba@228
   192
    for (typename Graph::EdgeIt e(G); e != INVALID; ++e) {
deba@228
   193
      check(G.edgeFromId(G.id(e)) == e, "Wrong id");
deba@228
   194
      check(values.find(G.id(e)) == values.end(), "Wrong id");
deba@228
   195
      check(G.id(e) <= G.maxEdgeId(), "Wrong maximum id");
deba@228
   196
      values.insert(G.id(e));
deba@228
   197
    }
kpeter@171
   198
  }
kpeter@171
   199
deba@228
   200
  template <typename Graph>
deba@228
   201
  void checkGraphNodeMap(const Graph& G) {
deba@228
   202
    typedef typename Graph::Node Node;
deba@228
   203
    typedef typename Graph::NodeIt NodeIt;
deba@228
   204
deba@228
   205
    typedef typename Graph::template NodeMap<int> IntNodeMap;
deba@228
   206
    IntNodeMap map(G, 42);
deba@228
   207
    for (NodeIt it(G); it != INVALID; ++it) {
deba@228
   208
      check(map[it] == 42, "Wrong map constructor.");
deba@228
   209
    }
deba@228
   210
    int s = 0;
deba@228
   211
    for (NodeIt it(G); it != INVALID; ++it) {
deba@228
   212
      map[it] = 0;
deba@228
   213
      check(map[it] == 0, "Wrong operator[].");
deba@228
   214
      map.set(it, s);
deba@228
   215
      check(map[it] == s, "Wrong set.");
deba@228
   216
      ++s;
deba@228
   217
    }
deba@228
   218
    s = s * (s - 1) / 2;
deba@228
   219
    for (NodeIt it(G); it != INVALID; ++it) {
deba@228
   220
      s -= map[it];
deba@228
   221
    }
deba@228
   222
    check(s == 0, "Wrong sum.");
deba@228
   223
kpeter@263
   224
    // map = constMap<Node>(12);
kpeter@263
   225
    // for (NodeIt it(G); it != INVALID; ++it) {
kpeter@263
   226
    //   check(map[it] == 12, "Wrong operator[].");
kpeter@263
   227
    // }
deba@228
   228
  }
deba@228
   229
deba@228
   230
  template <typename Graph>
deba@228
   231
  void checkGraphArcMap(const Graph& G) {
deba@228
   232
    typedef typename Graph::Arc Arc;
deba@228
   233
    typedef typename Graph::ArcIt ArcIt;
deba@228
   234
deba@228
   235
    typedef typename Graph::template ArcMap<int> IntArcMap;
deba@228
   236
    IntArcMap map(G, 42);
deba@228
   237
    for (ArcIt it(G); it != INVALID; ++it) {
deba@228
   238
      check(map[it] == 42, "Wrong map constructor.");
deba@228
   239
    }
deba@228
   240
    int s = 0;
deba@228
   241
    for (ArcIt it(G); it != INVALID; ++it) {
deba@228
   242
      map[it] = 0;
deba@228
   243
      check(map[it] == 0, "Wrong operator[].");
deba@228
   244
      map.set(it, s);
deba@228
   245
      check(map[it] == s, "Wrong set.");
deba@228
   246
      ++s;
deba@228
   247
    }
deba@228
   248
    s = s * (s - 1) / 2;
deba@228
   249
    for (ArcIt it(G); it != INVALID; ++it) {
deba@228
   250
      s -= map[it];
deba@228
   251
    }
deba@228
   252
    check(s == 0, "Wrong sum.");
deba@228
   253
kpeter@263
   254
    // map = constMap<Arc>(12);
kpeter@263
   255
    // for (ArcIt it(G); it != INVALID; ++it) {
kpeter@263
   256
    //   check(map[it] == 12, "Wrong operator[].");
kpeter@263
   257
    // }
deba@228
   258
  }
deba@228
   259
deba@228
   260
  template <typename Graph>
deba@228
   261
  void checkGraphEdgeMap(const Graph& G) {
deba@228
   262
    typedef typename Graph::Edge Edge;
deba@228
   263
    typedef typename Graph::EdgeIt EdgeIt;
deba@228
   264
deba@228
   265
    typedef typename Graph::template EdgeMap<int> IntEdgeMap;
deba@228
   266
    IntEdgeMap map(G, 42);
deba@228
   267
    for (EdgeIt it(G); it != INVALID; ++it) {
deba@228
   268
      check(map[it] == 42, "Wrong map constructor.");
deba@228
   269
    }
deba@228
   270
    int s = 0;
deba@228
   271
    for (EdgeIt it(G); it != INVALID; ++it) {
deba@228
   272
      map[it] = 0;
deba@228
   273
      check(map[it] == 0, "Wrong operator[].");
deba@228
   274
      map.set(it, s);
deba@228
   275
      check(map[it] == s, "Wrong set.");
deba@228
   276
      ++s;
deba@228
   277
    }
deba@228
   278
    s = s * (s - 1) / 2;
deba@228
   279
    for (EdgeIt it(G); it != INVALID; ++it) {
deba@228
   280
      s -= map[it];
deba@228
   281
    }
deba@228
   282
    check(s == 0, "Wrong sum.");
deba@228
   283
kpeter@263
   284
    // map = constMap<Edge>(12);
kpeter@263
   285
    // for (EdgeIt it(G); it != INVALID; ++it) {
kpeter@263
   286
    //   check(map[it] == 12, "Wrong operator[].");
kpeter@263
   287
    // }
deba@228
   288
  }
deba@228
   289
deba@228
   290
kpeter@171
   291
} //namespace lemon
kpeter@171
   292
kpeter@171
   293
#endif