test/connectivity_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 1047 ddd3c0d3d9bf
parent 696 76cbcb3e9bbb
child 1159 7fdaa05a69a1
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
kpeter@696
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
kpeter@696
     2
 *
kpeter@696
     3
 * This file is a part of LEMON, a generic C++ optimization library.
kpeter@696
     4
 *
alpar@956
     5
 * Copyright (C) 2003-2010
kpeter@696
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@696
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@696
     8
 *
kpeter@696
     9
 * Permission to use, modify and distribute this software is granted
kpeter@696
    10
 * provided that this copyright notice appears in all copies. For
kpeter@696
    11
 * precise terms see the accompanying LICENSE file.
kpeter@696
    12
 *
kpeter@696
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@696
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@696
    15
 * purpose.
kpeter@696
    16
 *
kpeter@696
    17
 */
kpeter@696
    18
kpeter@696
    19
#include <lemon/connectivity.h>
kpeter@696
    20
#include <lemon/list_graph.h>
kpeter@696
    21
#include <lemon/adaptors.h>
kpeter@696
    22
kpeter@696
    23
#include "test_tools.h"
kpeter@696
    24
kpeter@696
    25
using namespace lemon;
kpeter@696
    26
kpeter@696
    27
kpeter@696
    28
int main()
kpeter@696
    29
{
kpeter@696
    30
  typedef ListDigraph Digraph;
kpeter@696
    31
  typedef Undirector<Digraph> Graph;
alpar@956
    32
kpeter@696
    33
  {
kpeter@696
    34
    Digraph d;
kpeter@696
    35
    Digraph::NodeMap<int> order(d);
kpeter@696
    36
    Graph g(d);
alpar@956
    37
kpeter@696
    38
    check(stronglyConnected(d), "The empty digraph is strongly connected");
kpeter@696
    39
    check(countStronglyConnectedComponents(d) == 0,
kpeter@696
    40
          "The empty digraph has 0 strongly connected component");
kpeter@696
    41
    check(connected(g), "The empty graph is connected");
kpeter@696
    42
    check(countConnectedComponents(g) == 0,
kpeter@696
    43
          "The empty graph has 0 connected component");
kpeter@696
    44
kpeter@696
    45
    check(biNodeConnected(g), "The empty graph is bi-node-connected");
kpeter@696
    46
    check(countBiNodeConnectedComponents(g) == 0,
kpeter@696
    47
          "The empty graph has 0 bi-node-connected component");
kpeter@696
    48
    check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
kpeter@696
    49
    check(countBiEdgeConnectedComponents(g) == 0,
kpeter@696
    50
          "The empty graph has 0 bi-edge-connected component");
alpar@956
    51
kpeter@696
    52
    check(dag(d), "The empty digraph is DAG.");
kpeter@696
    53
    check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
kpeter@696
    54
    check(loopFree(d), "The empty digraph is loop-free.");
kpeter@696
    55
    check(parallelFree(d), "The empty digraph is parallel-free.");
kpeter@696
    56
    check(simpleGraph(d), "The empty digraph is simple.");
kpeter@696
    57
kpeter@696
    58
    check(acyclic(g), "The empty graph is acyclic.");
kpeter@696
    59
    check(tree(g), "The empty graph is tree.");
kpeter@696
    60
    check(bipartite(g), "The empty graph is bipartite.");
kpeter@696
    61
    check(loopFree(g), "The empty graph is loop-free.");
kpeter@696
    62
    check(parallelFree(g), "The empty graph is parallel-free.");
kpeter@696
    63
    check(simpleGraph(g), "The empty graph is simple.");
kpeter@696
    64
  }
kpeter@696
    65
kpeter@696
    66
  {
kpeter@696
    67
    Digraph d;
kpeter@696
    68
    Digraph::NodeMap<int> order(d);
kpeter@696
    69
    Graph g(d);
kpeter@696
    70
    Digraph::Node n = d.addNode();
kpeter@696
    71
kpeter@696
    72
    check(stronglyConnected(d), "This digraph is strongly connected");
kpeter@696
    73
    check(countStronglyConnectedComponents(d) == 1,
kpeter@696
    74
          "This digraph has 1 strongly connected component");
kpeter@696
    75
    check(connected(g), "This graph is connected");
kpeter@696
    76
    check(countConnectedComponents(g) == 1,
kpeter@696
    77
          "This graph has 1 connected component");
kpeter@696
    78
kpeter@696
    79
    check(biNodeConnected(g), "This graph is bi-node-connected");
kpeter@696
    80
    check(countBiNodeConnectedComponents(g) == 0,
kpeter@696
    81
          "This graph has 0 bi-node-connected component");
kpeter@696
    82
    check(biEdgeConnected(g), "This graph is bi-edge-connected");
kpeter@696
    83
    check(countBiEdgeConnectedComponents(g) == 1,
kpeter@696
    84
          "This graph has 1 bi-edge-connected component");
alpar@956
    85
kpeter@696
    86
    check(dag(d), "This digraph is DAG.");
kpeter@696
    87
    check(checkedTopologicalSort(d, order), "This digraph is DAG.");
kpeter@696
    88
    check(loopFree(d), "This digraph is loop-free.");
kpeter@696
    89
    check(parallelFree(d), "This digraph is parallel-free.");
kpeter@696
    90
    check(simpleGraph(d), "This digraph is simple.");
kpeter@696
    91
kpeter@696
    92
    check(acyclic(g), "This graph is acyclic.");
kpeter@696
    93
    check(tree(g), "This graph is tree.");
kpeter@696
    94
    check(bipartite(g), "This graph is bipartite.");
kpeter@696
    95
    check(loopFree(g), "This graph is loop-free.");
kpeter@696
    96
    check(parallelFree(g), "This graph is parallel-free.");
kpeter@696
    97
    check(simpleGraph(g), "This graph is simple.");
kpeter@696
    98
  }
kpeter@696
    99
kpeter@696
   100
  {
kpeter@696
   101
    Digraph d;
kpeter@696
   102
    Digraph::NodeMap<int> order(d);
kpeter@696
   103
    Graph g(d);
alpar@956
   104
kpeter@696
   105
    Digraph::Node n1 = d.addNode();
kpeter@696
   106
    Digraph::Node n2 = d.addNode();
kpeter@696
   107
    Digraph::Node n3 = d.addNode();
kpeter@696
   108
    Digraph::Node n4 = d.addNode();
kpeter@696
   109
    Digraph::Node n5 = d.addNode();
kpeter@696
   110
    Digraph::Node n6 = d.addNode();
alpar@956
   111
kpeter@696
   112
    d.addArc(n1, n3);
kpeter@696
   113
    d.addArc(n3, n2);
kpeter@696
   114
    d.addArc(n2, n1);
kpeter@696
   115
    d.addArc(n4, n2);
kpeter@696
   116
    d.addArc(n4, n3);
kpeter@696
   117
    d.addArc(n5, n6);
kpeter@696
   118
    d.addArc(n6, n5);
kpeter@696
   119
kpeter@696
   120
    check(!stronglyConnected(d), "This digraph is not strongly connected");
kpeter@696
   121
    check(countStronglyConnectedComponents(d) == 3,
kpeter@696
   122
          "This digraph has 3 strongly connected components");
kpeter@696
   123
    check(!connected(g), "This graph is not connected");
kpeter@696
   124
    check(countConnectedComponents(g) == 2,
kpeter@696
   125
          "This graph has 2 connected components");
kpeter@696
   126
kpeter@696
   127
    check(!dag(d), "This digraph is not DAG.");
kpeter@696
   128
    check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
kpeter@696
   129
    check(loopFree(d), "This digraph is loop-free.");
kpeter@696
   130
    check(parallelFree(d), "This digraph is parallel-free.");
kpeter@696
   131
    check(simpleGraph(d), "This digraph is simple.");
kpeter@696
   132
kpeter@696
   133
    check(!acyclic(g), "This graph is not acyclic.");
kpeter@696
   134
    check(!tree(g), "This graph is not tree.");
kpeter@696
   135
    check(!bipartite(g), "This graph is not bipartite.");
kpeter@696
   136
    check(loopFree(g), "This graph is loop-free.");
kpeter@696
   137
    check(!parallelFree(g), "This graph is not parallel-free.");
kpeter@696
   138
    check(!simpleGraph(g), "This graph is not simple.");
alpar@956
   139
kpeter@696
   140
    d.addArc(n3, n3);
alpar@956
   141
kpeter@696
   142
    check(!loopFree(d), "This digraph is not loop-free.");
kpeter@696
   143
    check(!loopFree(g), "This graph is not loop-free.");
kpeter@696
   144
    check(!simpleGraph(d), "This digraph is not simple.");
alpar@956
   145
kpeter@696
   146
    d.addArc(n3, n2);
alpar@956
   147
kpeter@696
   148
    check(!parallelFree(d), "This digraph is not parallel-free.");
kpeter@696
   149
  }
alpar@956
   150
kpeter@696
   151
  {
kpeter@696
   152
    Digraph d;
kpeter@696
   153
    Digraph::ArcMap<bool> cutarcs(d, false);
kpeter@696
   154
    Graph g(d);
alpar@956
   155
kpeter@696
   156
    Digraph::Node n1 = d.addNode();
kpeter@696
   157
    Digraph::Node n2 = d.addNode();
kpeter@696
   158
    Digraph::Node n3 = d.addNode();
kpeter@696
   159
    Digraph::Node n4 = d.addNode();
kpeter@696
   160
    Digraph::Node n5 = d.addNode();
kpeter@696
   161
    Digraph::Node n6 = d.addNode();
kpeter@696
   162
    Digraph::Node n7 = d.addNode();
kpeter@696
   163
    Digraph::Node n8 = d.addNode();
kpeter@696
   164
kpeter@696
   165
    d.addArc(n1, n2);
kpeter@696
   166
    d.addArc(n5, n1);
kpeter@696
   167
    d.addArc(n2, n8);
kpeter@696
   168
    d.addArc(n8, n5);
kpeter@696
   169
    d.addArc(n6, n4);
kpeter@696
   170
    d.addArc(n4, n6);
kpeter@696
   171
    d.addArc(n2, n5);
kpeter@696
   172
    d.addArc(n1, n8);
kpeter@696
   173
    d.addArc(n6, n7);
kpeter@696
   174
    d.addArc(n7, n6);
alpar@956
   175
kpeter@696
   176
    check(!stronglyConnected(d), "This digraph is not strongly connected");
kpeter@696
   177
    check(countStronglyConnectedComponents(d) == 3,
kpeter@696
   178
          "This digraph has 3 strongly connected components");
kpeter@696
   179
    Digraph::NodeMap<int> scomp1(d);
kpeter@696
   180
    check(stronglyConnectedComponents(d, scomp1) == 3,
kpeter@696
   181
          "This digraph has 3 strongly connected components");
kpeter@696
   182
    check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
kpeter@696
   183
          scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
kpeter@696
   184
    check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
kpeter@696
   185
          scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
kpeter@696
   186
    check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
kpeter@696
   187
          "Wrong stronglyConnectedComponents()");
kpeter@696
   188
    Digraph::ArcMap<bool> scut1(d, false);
kpeter@696
   189
    check(stronglyConnectedCutArcs(d, scut1) == 0,
kpeter@696
   190
          "This digraph has 0 strongly connected cut arc.");
kpeter@696
   191
    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
kpeter@696
   192
      check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
kpeter@696
   193
    }
kpeter@696
   194
kpeter@696
   195
    check(!connected(g), "This graph is not connected");
kpeter@696
   196
    check(countConnectedComponents(g) == 3,
kpeter@696
   197
          "This graph has 3 connected components");
kpeter@696
   198
    Graph::NodeMap<int> comp(g);
kpeter@696
   199
    check(connectedComponents(g, comp) == 3,
kpeter@696
   200
          "This graph has 3 connected components");
kpeter@696
   201
    check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
kpeter@696
   202
          comp[n3] != comp[n4], "Wrong connectedComponents()");
kpeter@696
   203
    check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
kpeter@696
   204
          comp[n1] == comp[n8], "Wrong connectedComponents()");
kpeter@696
   205
    check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
kpeter@696
   206
          "Wrong connectedComponents()");
kpeter@696
   207
kpeter@696
   208
    cutarcs[d.addArc(n3, n1)] = true;
kpeter@696
   209
    cutarcs[d.addArc(n3, n5)] = true;
kpeter@696
   210
    cutarcs[d.addArc(n3, n8)] = true;
kpeter@696
   211
    cutarcs[d.addArc(n8, n6)] = true;
kpeter@696
   212
    cutarcs[d.addArc(n8, n7)] = true;
kpeter@696
   213
kpeter@696
   214
    check(!stronglyConnected(d), "This digraph is not strongly connected");
kpeter@696
   215
    check(countStronglyConnectedComponents(d) == 3,
kpeter@696
   216
          "This digraph has 3 strongly connected components");
kpeter@696
   217
    Digraph::NodeMap<int> scomp2(d);
kpeter@696
   218
    check(stronglyConnectedComponents(d, scomp2) == 3,
kpeter@696
   219
          "This digraph has 3 strongly connected components");
kpeter@696
   220
    check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
kpeter@696
   221
    check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
kpeter@696
   222
          scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
kpeter@696
   223
    check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
kpeter@696
   224
          "Wrong stronglyConnectedComponents()");
kpeter@696
   225
    Digraph::ArcMap<bool> scut2(d, false);
kpeter@696
   226
    check(stronglyConnectedCutArcs(d, scut2) == 5,
kpeter@696
   227
          "This digraph has 5 strongly connected cut arcs.");
kpeter@696
   228
    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
kpeter@696
   229
      check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
kpeter@696
   230
    }
kpeter@696
   231
  }
kpeter@696
   232
kpeter@696
   233
  {
kpeter@696
   234
    // DAG example for topological sort from the book New Algorithms
kpeter@696
   235
    // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
kpeter@696
   236
    Digraph d;
kpeter@696
   237
    Digraph::NodeMap<int> order(d);
alpar@956
   238
kpeter@696
   239
    Digraph::Node belt = d.addNode();
kpeter@696
   240
    Digraph::Node trousers = d.addNode();
kpeter@696
   241
    Digraph::Node necktie = d.addNode();
kpeter@696
   242
    Digraph::Node coat = d.addNode();
kpeter@696
   243
    Digraph::Node socks = d.addNode();
kpeter@696
   244
    Digraph::Node shirt = d.addNode();
kpeter@696
   245
    Digraph::Node shoe = d.addNode();
kpeter@696
   246
    Digraph::Node watch = d.addNode();
kpeter@696
   247
    Digraph::Node pants = d.addNode();
kpeter@696
   248
kpeter@696
   249
    d.addArc(socks, shoe);
kpeter@696
   250
    d.addArc(pants, shoe);
kpeter@696
   251
    d.addArc(pants, trousers);
kpeter@696
   252
    d.addArc(trousers, shoe);
kpeter@696
   253
    d.addArc(trousers, belt);
kpeter@696
   254
    d.addArc(belt, coat);
kpeter@696
   255
    d.addArc(shirt, belt);
kpeter@696
   256
    d.addArc(shirt, necktie);
kpeter@696
   257
    d.addArc(necktie, coat);
alpar@956
   258
kpeter@696
   259
    check(dag(d), "This digraph is DAG.");
kpeter@696
   260
    topologicalSort(d, order);
kpeter@696
   261
    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
kpeter@696
   262
      check(order[d.source(a)] < order[d.target(a)],
kpeter@696
   263
            "Wrong topologicalSort()");
kpeter@696
   264
    }
kpeter@696
   265
  }
kpeter@696
   266
kpeter@696
   267
  {
kpeter@696
   268
    ListGraph g;
kpeter@696
   269
    ListGraph::NodeMap<bool> map(g);
alpar@956
   270
kpeter@696
   271
    ListGraph::Node n1 = g.addNode();
kpeter@696
   272
    ListGraph::Node n2 = g.addNode();
kpeter@696
   273
    ListGraph::Node n3 = g.addNode();
kpeter@696
   274
    ListGraph::Node n4 = g.addNode();
kpeter@696
   275
    ListGraph::Node n5 = g.addNode();
kpeter@696
   276
    ListGraph::Node n6 = g.addNode();
kpeter@696
   277
    ListGraph::Node n7 = g.addNode();
kpeter@696
   278
kpeter@696
   279
    g.addEdge(n1, n3);
kpeter@696
   280
    g.addEdge(n1, n4);
kpeter@696
   281
    g.addEdge(n2, n5);
kpeter@696
   282
    g.addEdge(n3, n6);
kpeter@696
   283
    g.addEdge(n4, n6);
kpeter@696
   284
    g.addEdge(n4, n7);
kpeter@696
   285
    g.addEdge(n5, n7);
alpar@956
   286
kpeter@696
   287
    check(bipartite(g), "This graph is bipartite");
kpeter@696
   288
    check(bipartitePartitions(g, map), "This graph is bipartite");
alpar@956
   289
kpeter@696
   290
    check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
kpeter@696
   291
          "Wrong bipartitePartitions()");
kpeter@696
   292
    check(map[n3] == map[n4] && map[n3] == map[n5],
kpeter@696
   293
          "Wrong bipartitePartitions()");
kpeter@696
   294
  }
kpeter@696
   295
kpeter@696
   296
  return 0;
kpeter@696
   297
}