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