test/vf2_test.cc
author Alpar Juttner <alpar@cs.elte.hu>
Thu, 14 May 2015 17:13:44 +0200
changeset 1143 f85ee41c84bc
parent 1141 a037254714b3
child 1186 3feba0ea1bda
permissions -rw-r--r--
Bugfix in Vf2 - missing initialization (#597)
madarasip@1141
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
madarasip@1141
     2
 *
madarasip@1141
     3
 * This file is a part of LEMON, a generic C++ optimization library.
madarasip@1141
     4
 *
madarasip@1141
     5
 * Copyright (C) 2015
madarasip@1141
     6
 * EMAXA Kutato-fejleszto Kft. (EMAXA Research Ltd.)
madarasip@1141
     7
 *
madarasip@1141
     8
 * Permission to use, modify and distribute this software is granted
madarasip@1141
     9
 * provided that this copyright notice appears in all copies. For
madarasip@1141
    10
 * precise terms see the accompanying LICENSE file.
madarasip@1141
    11
 *
madarasip@1141
    12
 * This software is provided "AS IS" with no warranty of any kind,
madarasip@1141
    13
 * express or implied, and with no claim as to its suitability for any
madarasip@1141
    14
 * purpose.
madarasip@1141
    15
 *
madarasip@1141
    16
 */
madarasip@1141
    17
madarasip@1141
    18
#include <lemon/vf2.h>
madarasip@1141
    19
#include <lemon/concepts/digraph.h>
madarasip@1141
    20
#include <lemon/smart_graph.h>
madarasip@1141
    21
#include <lemon/lgf_reader.h>
madarasip@1141
    22
#include <lemon/concepts/maps.h>
madarasip@1141
    23
madarasip@1141
    24
#include <test/test_tools.h>
madarasip@1141
    25
#include <sstream>
madarasip@1141
    26
madarasip@1141
    27
using namespace lemon;
madarasip@1141
    28
madarasip@1141
    29
char petersen_lgf[] =
madarasip@1141
    30
  "@nodes\n"
madarasip@1141
    31
  "label col1 col2\n"
madarasip@1141
    32
  "0 1 1\n"
madarasip@1141
    33
  "1 1 2\n"
madarasip@1141
    34
  "2 1 3\n"
madarasip@1141
    35
  "3 1 4\n"
madarasip@1141
    36
  "4 2 5\n"
madarasip@1141
    37
  "5 2 1\n"
madarasip@1141
    38
  "6 2 2\n"
madarasip@1141
    39
  "7 2 3\n"
madarasip@1141
    40
  "8 2 4\n"
madarasip@1141
    41
  "9 2 5\n"
madarasip@1141
    42
  "@arcs\n"
madarasip@1141
    43
  "     -\n"
madarasip@1141
    44
  "0 1\n"
madarasip@1141
    45
  "1 2\n"
madarasip@1141
    46
  "2 3\n"
madarasip@1141
    47
  "3 4\n"
madarasip@1141
    48
  "4 0\n"
madarasip@1141
    49
  "0 5\n"
madarasip@1141
    50
  "1 6\n"
madarasip@1141
    51
  "2 7\n"
madarasip@1141
    52
  "3 8\n"
madarasip@1141
    53
  "4 9\n"
madarasip@1141
    54
  "5 8\n"
madarasip@1141
    55
  "5 7\n"
madarasip@1141
    56
  "9 6\n"
madarasip@1141
    57
  "9 7\n"
madarasip@1141
    58
  "6 8\n";
madarasip@1141
    59
madarasip@1141
    60
char c5_lgf[] =
madarasip@1141
    61
  "@nodes\n"
madarasip@1141
    62
  "label col\n"
madarasip@1141
    63
  "0 1\n"
madarasip@1141
    64
  "1 2\n"
madarasip@1141
    65
  "2 3\n"
madarasip@1141
    66
  "3 4\n"
madarasip@1141
    67
  "4 5\n"
madarasip@1141
    68
  "@arcs\n"
madarasip@1141
    69
  "     -\n"
madarasip@1141
    70
  "0 1\n"
madarasip@1141
    71
  "1 2\n"
madarasip@1141
    72
  "2 3\n"
madarasip@1141
    73
  "3 4\n"
madarasip@1141
    74
  "4 0\n";
madarasip@1141
    75
madarasip@1141
    76
char c7_lgf[] =
madarasip@1141
    77
  "@nodes\n"
madarasip@1141
    78
  "label\n"
madarasip@1141
    79
  "0\n"
madarasip@1141
    80
  "1\n"
madarasip@1141
    81
  "2\n"
madarasip@1141
    82
  "3\n"
madarasip@1141
    83
  "4\n"
madarasip@1141
    84
  "5\n"
madarasip@1141
    85
  "6\n"
madarasip@1141
    86
  "@arcs\n"
madarasip@1141
    87
  "     -\n"
madarasip@1141
    88
  "0 1\n"
madarasip@1141
    89
  "1 2\n"
madarasip@1141
    90
  "2 3\n"
madarasip@1141
    91
  "3 4\n"
madarasip@1141
    92
  "4 5\n"
madarasip@1141
    93
  "5 6\n"
madarasip@1141
    94
  "6 0\n";
madarasip@1141
    95
madarasip@1141
    96
char c10_lgf[] =
madarasip@1141
    97
  "@nodes\n"
madarasip@1141
    98
  "label\n"
madarasip@1141
    99
  "0\n"
madarasip@1141
   100
  "1\n"
madarasip@1141
   101
  "2\n"
madarasip@1141
   102
  "3\n"
madarasip@1141
   103
  "4\n"
madarasip@1141
   104
  "5\n"
madarasip@1141
   105
  "6\n"
madarasip@1141
   106
  "7\n"
madarasip@1141
   107
  "8\n"
madarasip@1141
   108
  "9\n"
madarasip@1141
   109
  "@arcs\n"
madarasip@1141
   110
  "     -\n"
madarasip@1141
   111
  "0 1\n"
madarasip@1141
   112
  "1 2\n"
madarasip@1141
   113
  "2 3\n"
madarasip@1141
   114
  "3 4\n"
madarasip@1141
   115
  "4 5\n"
madarasip@1141
   116
  "5 6\n"
madarasip@1141
   117
  "6 7\n"
madarasip@1141
   118
  "7 8\n"
madarasip@1141
   119
  "8 9\n"
madarasip@1141
   120
  "9 0\n";
madarasip@1141
   121
madarasip@1141
   122
char p10_lgf[] =
madarasip@1141
   123
  "@nodes\n"
madarasip@1141
   124
  "label\n"
madarasip@1141
   125
  "0\n"
madarasip@1141
   126
  "1\n"
madarasip@1141
   127
  "2\n"
madarasip@1141
   128
  "3\n"
madarasip@1141
   129
  "4\n"
madarasip@1141
   130
  "5\n"
madarasip@1141
   131
  "6\n"
madarasip@1141
   132
  "7\n"
madarasip@1141
   133
  "8\n"
madarasip@1141
   134
  "9\n"
madarasip@1141
   135
  "@arcs\n"
madarasip@1141
   136
  "     -\n"
madarasip@1141
   137
  "0 1\n"
madarasip@1141
   138
  "1 2\n"
madarasip@1141
   139
  "2 3\n"
madarasip@1141
   140
  "3 4\n"
madarasip@1141
   141
  "4 5\n"
madarasip@1141
   142
  "5 6\n"
madarasip@1141
   143
  "6 7\n"
madarasip@1141
   144
  "7 8\n"
madarasip@1141
   145
  "8 9\n";
madarasip@1141
   146
madarasip@1141
   147
SmartGraph petersen, c5, c7, c10, p10;
madarasip@1141
   148
SmartGraph::NodeMap<int> petersen_col1(petersen);
madarasip@1141
   149
SmartGraph::NodeMap<int> petersen_col2(petersen);
madarasip@1141
   150
SmartGraph::NodeMap<int> c5_col(c5);
madarasip@1141
   151
madarasip@1141
   152
void make_graphs() {
madarasip@1141
   153
  std::stringstream ss(petersen_lgf);
madarasip@1141
   154
  graphReader(petersen, ss)
madarasip@1141
   155
    .nodeMap("col1",petersen_col1)
madarasip@1141
   156
    .nodeMap("col2",petersen_col2)
madarasip@1141
   157
    .run();
madarasip@1141
   158
madarasip@1141
   159
  ss.clear();
madarasip@1141
   160
  ss.str("");
madarasip@1141
   161
  ss<<c5_lgf;
madarasip@1141
   162
  //std::stringstream ss2(c5_lgf);
madarasip@1141
   163
  graphReader(c5, ss)
madarasip@1141
   164
    .nodeMap("col",c5_col)
madarasip@1141
   165
    .run();
madarasip@1141
   166
madarasip@1141
   167
  ss.clear();
madarasip@1141
   168
  ss.str("");
madarasip@1141
   169
  ss<<c7_lgf;
madarasip@1141
   170
  graphReader(c7, ss).run();
madarasip@1141
   171
madarasip@1141
   172
  ss.clear();
madarasip@1141
   173
  ss.str("");
madarasip@1141
   174
  ss<<c10_lgf;
madarasip@1141
   175
  graphReader(c10, ss).run();
madarasip@1141
   176
madarasip@1141
   177
  ss.clear();
madarasip@1141
   178
  ss.str("");
madarasip@1141
   179
  ss<<p10_lgf;
madarasip@1141
   180
  graphReader(p10, ss).run();
madarasip@1141
   181
madarasip@1141
   182
}
madarasip@1141
   183
madarasip@1141
   184
class EqComparable {
madarasip@1141
   185
public:
madarasip@1141
   186
  bool operator==(const EqComparable&) { return false; }
madarasip@1141
   187
};
madarasip@1141
   188
madarasip@1141
   189
template<class A, class B>
madarasip@1141
   190
class EqClass {
madarasip@1141
   191
public:
madarasip@1141
   192
  bool operator()(A, B) { return false; }
madarasip@1141
   193
};
madarasip@1141
   194
madarasip@1141
   195
template<class G1,class G2>
madarasip@1141
   196
void checkVf2Compile()
madarasip@1141
   197
{
madarasip@1141
   198
  G1 g;
madarasip@1141
   199
  G2 h;
madarasip@1141
   200
  concepts::ReadWriteMap<typename G1::Node, typename G2::Node> r;
madarasip@1141
   201
  bool succ;
madarasip@1141
   202
  ::lemon::ignore_unused_variable_warning(succ);
madarasip@1141
   203
madarasip@1141
   204
  succ = vf2(g,h).run();
madarasip@1141
   205
  succ = vf2(g,h).induced().run();
madarasip@1141
   206
  succ = vf2(g,h).iso().run();
madarasip@1141
   207
  succ = vf2(g,h).mapping(r).run();
madarasip@1141
   208
  succ = vf2(g,h).induced().mapping(r).run();
madarasip@1141
   209
  succ = vf2(g,h).iso().mapping(r).run();
madarasip@1141
   210
  concepts::ReadMap<typename G1::Node, EqComparable> l1;
madarasip@1141
   211
  concepts::ReadMap<typename G2::Node, EqComparable> l2;
madarasip@1141
   212
  succ = vf2(g,h).nodeLabels(l1,l2).mapping(r).run();
madarasip@1141
   213
  succ = vf2(g,h).nodeEq(EqClass<typename G1::Node,typename G2::Node>())
madarasip@1141
   214
    .mapping(r).run();
madarasip@1141
   215
}
madarasip@1141
   216
madarasip@1141
   217
void justCompile()
madarasip@1141
   218
{
madarasip@1141
   219
  checkVf2Compile<concepts::Graph,concepts::Graph>();
madarasip@1141
   220
  checkVf2Compile<concepts::Graph,SmartGraph>();
madarasip@1141
   221
  checkVf2Compile<SmartGraph,concepts::Graph>();
madarasip@1141
   222
}
madarasip@1141
   223
madarasip@1141
   224
template<class G1, class G2, class I>
madarasip@1141
   225
void checkSub(const G1 &g1, const G2 &g2, const I &i)
madarasip@1141
   226
{
madarasip@1141
   227
  {
madarasip@1141
   228
    std::set<typename G2::Node> image;
madarasip@1141
   229
    for(typename G1::NodeIt n(g1);n!=INVALID;++n)
madarasip@1141
   230
      {
madarasip@1141
   231
          check(i[n]!=INVALID, "Wrong isomorphism: incomplete mapping.");
madarasip@1141
   232
          check(image.count(i[n])==0,"Wrong isomorphism: not injective.");
madarasip@1141
   233
          image.insert(i[n]);
madarasip@1141
   234
      }
madarasip@1141
   235
  }
madarasip@1141
   236
  for(typename G1::EdgeIt e(g1);e!=INVALID;++e)
madarasip@1141
   237
    check(findEdge(g2,i[g1.u(e)],i[g1.v(e)])!=INVALID,
madarasip@1141
   238
          "Wrong isomorphism: missing edge(checkSub).");
madarasip@1141
   239
}
madarasip@1141
   240
madarasip@1141
   241
template<class G1, class G2, class I>
madarasip@1141
   242
void checkInd(const G1 &g1, const G2 &g2, const I &i)
madarasip@1141
   243
  {
madarasip@1141
   244
  std::set<typename G2::Node> image;
madarasip@1141
   245
  for(typename G1::NodeIt n(g1);n!=INVALID;++n)
madarasip@1141
   246
    {
madarasip@1141
   247
    check(i[n]!=INVALID, "Wrong isomorphism: incomplete mapping.");
madarasip@1141
   248
    check(image.count(i[n])==0,"Wrong isomorphism: not injective.");
madarasip@1141
   249
    image.insert(i[n]);
madarasip@1141
   250
    }
madarasip@1141
   251
  for(typename G1::NodeIt n(g1); n!=INVALID; ++n)
madarasip@1141
   252
    for(typename G1::NodeIt m(g1); m!=INVALID; ++m)
madarasip@1141
   253
      if((findEdge(g1,n,m)==INVALID) != (findEdge(g2,i[n],i[m])==INVALID))
madarasip@1141
   254
        {
madarasip@1141
   255
        std::cout << "Wrong isomorphism: edge mismatch";
madarasip@1141
   256
        exit(1);
madarasip@1141
   257
        }
madarasip@1141
   258
  }
madarasip@1141
   259
madarasip@1141
   260
template<class G1,class G2>
madarasip@1141
   261
int checkSub(const G1 &g1, const G2 &g2)
madarasip@1141
   262
{
madarasip@1141
   263
  typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
madarasip@1141
   264
  if(vf2(g1,g2).mapping(iso).run())
madarasip@1141
   265
    {
madarasip@1141
   266
      checkSub(g1,g2,iso);
madarasip@1141
   267
      return true;
madarasip@1141
   268
    }
madarasip@1141
   269
  else return false;
madarasip@1141
   270
}
madarasip@1141
   271
madarasip@1141
   272
template<class G1,class G2>
madarasip@1141
   273
int checkInd(const G1 &g1, const G2 &g2)
madarasip@1141
   274
{
madarasip@1141
   275
  typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
madarasip@1141
   276
  if(vf2(g1,g2).induced().mapping(iso).run())
madarasip@1141
   277
    {
madarasip@1141
   278
      checkInd(g1,g2,iso);
madarasip@1141
   279
      return true;
madarasip@1141
   280
    }
madarasip@1141
   281
  else return false;
madarasip@1141
   282
}
madarasip@1141
   283
madarasip@1141
   284
template<class G1,class G2>
madarasip@1141
   285
int checkIso(const G1 &g1, const G2 &g2)
madarasip@1141
   286
{
madarasip@1141
   287
  typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
madarasip@1141
   288
  if(vf2(g1,g2).iso().mapping(iso).run())
madarasip@1141
   289
    {
madarasip@1141
   290
      check(countNodes(g1)==countNodes(g2),
madarasip@1141
   291
            "Wrong iso alg.: they are not isomophic.");
madarasip@1141
   292
      checkInd(g1,g2,iso);
madarasip@1141
   293
      return true;
madarasip@1141
   294
    }
madarasip@1141
   295
  else return false;
madarasip@1141
   296
}
madarasip@1141
   297
madarasip@1141
   298
template<class G1, class G2, class L1, class L2, class I>
madarasip@1141
   299
void checkLabel(const G1 &g1, const G2 &,
madarasip@1141
   300
                const L1 &l1, const L2 &l2,const I &i)
madarasip@1141
   301
{
madarasip@1141
   302
  for(typename G1::NodeIt n(g1);n!=INVALID;++n)
madarasip@1141
   303
    {
madarasip@1141
   304
      check(l1[n]==l2[i[n]],"Wrong isomorphism: label mismatch.");
madarasip@1141
   305
    }
madarasip@1141
   306
}
madarasip@1141
   307
madarasip@1141
   308
template<class G1,class G2,class L1,class L2>
madarasip@1141
   309
int checkSub(const G1 &g1, const G2 &g2, const L1 &l1, const L2 &l2)
madarasip@1141
   310
{
madarasip@1141
   311
  typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
madarasip@1141
   312
  if(vf2(g1,g2).nodeLabels(l1,l2).mapping(iso).run())
madarasip@1141
   313
    {
madarasip@1141
   314
      checkSub(g1,g2,iso);
madarasip@1141
   315
      checkLabel(g1,g2,l1,l2,iso);
madarasip@1141
   316
      return true;
madarasip@1141
   317
    }
madarasip@1141
   318
  else return false;
madarasip@1141
   319
}
madarasip@1141
   320
madarasip@1141
   321
int main() {
madarasip@1141
   322
  make_graphs();
madarasip@1141
   323
  check(checkSub(c5,petersen), "There should exist a C5->Petersen mapping.");
madarasip@1141
   324
  check(!checkSub(c7,petersen),
madarasip@1141
   325
        "There should not exist a C7->Petersen mapping.");
madarasip@1141
   326
  check(checkSub(p10,petersen), "There should exist a P10->Petersen mapping.");
madarasip@1141
   327
  check(!checkSub(c10,petersen),
madarasip@1141
   328
        "There should not exist a C10->Petersen mapping.");
madarasip@1141
   329
  check(checkSub(petersen,petersen),
madarasip@1141
   330
        "There should exist a Petersen->Petersen mapping.");
madarasip@1141
   331
madarasip@1141
   332
  check(checkInd(c5,petersen),
madarasip@1141
   333
        "There should exist a C5->Petersen spanned mapping.");
madarasip@1141
   334
  check(!checkInd(c7,petersen),
madarasip@1141
   335
        "There should exist a C7->Petersen spanned mapping.");
madarasip@1141
   336
  check(!checkInd(p10,petersen),
madarasip@1141
   337
        "There should not exist a P10->Petersen spanned mapping.");
madarasip@1141
   338
  check(!checkInd(c10,petersen),
madarasip@1141
   339
        "There should not exist a C10->Petersen spanned mapping.");
madarasip@1141
   340
  check(checkInd(petersen,petersen),
madarasip@1141
   341
        "There should exist a Petersen->Petersen spanned mapping.");
madarasip@1141
   342
madarasip@1141
   343
  check(!checkSub(petersen,c10),
madarasip@1141
   344
        "There should not exist a Petersen->C10 mapping.");
madarasip@1141
   345
  check(checkSub(p10,c10),
madarasip@1141
   346
        "There should exist a P10->C10 mapping.");
madarasip@1141
   347
  check(!checkInd(p10,c10),
madarasip@1141
   348
        "There should not exist a P10->C10 spanned mapping.");
madarasip@1141
   349
  check(!checkSub(c10,p10),
madarasip@1141
   350
        "There should not exist a C10->P10 mapping.");
madarasip@1141
   351
madarasip@1141
   352
  check(!checkIso(p10,c10),
madarasip@1141
   353
        "P10 and C10 are not isomorphic.");
madarasip@1141
   354
  check(checkIso(c10,c10),
alpar@1143
   355
        "C10 and C10 are isomorphic.");
alpar@1143
   356
alpar@1143
   357
  check(!vf2(p10,c10).iso().run(),
alpar@1143
   358
        "P10 and C10 are not isomorphic.");
alpar@1143
   359
  check(vf2(c10,c10).iso().run(),
alpar@1143
   360
        "C10 and C10 are isomorphic.");
madarasip@1141
   361
madarasip@1141
   362
  check(!checkSub(c5,petersen,c5_col,petersen_col1),
madarasip@1141
   363
        "There should exist a C5->Petersen mapping.");
madarasip@1141
   364
  check(checkSub(c5,petersen,c5_col,petersen_col2),
madarasip@1141
   365
        "There should exist a C5->Petersen mapping.");
madarasip@1141
   366
}