test/connectivity_test.cc
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 891 bb70ad62c95f
child 877 141f9c0db4a3
child 997 761fe0846f49
permissions -rw-r--r--
Fix critical bug in preflow (#372)

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