1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
6 * EMAXA Kutato-fejleszto Kft. (EMAXA Research Ltd.)
8 * Permission to use, modify and distribute this software is granted
9 * provided that this copyright notice appears in all copies. For
10 * precise terms see the accompanying LICENSE file.
12 * This software is provided "AS IS" with no warranty of any kind,
13 * express or implied, and with no claim as to its suitability for any
18 #include <lemon/vf2.h>
19 #include <lemon/concepts/digraph.h>
20 #include <lemon/smart_graph.h>
21 #include <lemon/lgf_reader.h>
22 #include <lemon/concepts/maps.h>
24 #include <test/test_tools.h>
27 using namespace lemon;
147 SmartGraph petersen, c5, c7, c10, p10;
148 SmartGraph::NodeMap<int> petersen_col1(petersen);
149 SmartGraph::NodeMap<int> petersen_col2(petersen);
150 SmartGraph::NodeMap<int> c5_col(c5);
153 std::stringstream ss(petersen_lgf);
154 graphReader(petersen, ss)
155 .nodeMap("col1",petersen_col1)
156 .nodeMap("col2",petersen_col2)
162 //std::stringstream ss2(c5_lgf);
164 .nodeMap("col",c5_col)
170 graphReader(c7, ss).run();
175 graphReader(c10, ss).run();
180 graphReader(p10, ss).run();
186 bool operator==(const EqComparable&) { return false; }
189 template<class A, class B>
192 bool operator()(A, B) { return false; }
195 template<class G1,class G2>
196 void checkVf2Compile()
200 concepts::ReadWriteMap<typename G1::Node, typename G2::Node> r;
202 ::lemon::ignore_unused_variable_warning(succ);
204 succ = vf2(g,h).run();
205 succ = vf2(g,h).induced().run();
206 succ = vf2(g,h).iso().run();
207 succ = vf2(g,h).mapping(r).run();
208 succ = vf2(g,h).induced().mapping(r).run();
209 succ = vf2(g,h).iso().mapping(r).run();
210 concepts::ReadMap<typename G1::Node, EqComparable> l1;
211 concepts::ReadMap<typename G2::Node, EqComparable> l2;
212 succ = vf2(g,h).nodeLabels(l1,l2).mapping(r).run();
213 succ = vf2(g,h).nodeEq(EqClass<typename G1::Node,typename G2::Node>())
219 checkVf2Compile<concepts::Graph,concepts::Graph>();
220 checkVf2Compile<concepts::Graph,SmartGraph>();
221 checkVf2Compile<SmartGraph,concepts::Graph>();
224 template<class G1, class G2, class I>
225 void checkSub(const G1 &g1, const G2 &g2, const I &i)
228 std::set<typename G2::Node> image;
229 for(typename G1::NodeIt n(g1);n!=INVALID;++n)
231 check(i[n]!=INVALID, "Wrong isomorphism: incomplete mapping.");
232 check(image.count(i[n])==0,"Wrong isomorphism: not injective.");
236 for(typename G1::EdgeIt e(g1);e!=INVALID;++e)
237 check(findEdge(g2,i[g1.u(e)],i[g1.v(e)])!=INVALID,
238 "Wrong isomorphism: missing edge(checkSub).");
241 template<class G1, class G2, class I>
242 void checkInd(const G1 &g1, const G2 &g2, const I &i)
244 std::set<typename G2::Node> image;
245 for(typename G1::NodeIt n(g1);n!=INVALID;++n)
247 check(i[n]!=INVALID, "Wrong isomorphism: incomplete mapping.");
248 check(image.count(i[n])==0,"Wrong isomorphism: not injective.");
251 for(typename G1::NodeIt n(g1); n!=INVALID; ++n)
252 for(typename G1::NodeIt m(g1); m!=INVALID; ++m)
253 if((findEdge(g1,n,m)==INVALID) != (findEdge(g2,i[n],i[m])==INVALID))
255 std::cout << "Wrong isomorphism: edge mismatch";
260 template<class G1,class G2>
261 int checkSub(const G1 &g1, const G2 &g2)
263 typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
264 if(vf2(g1,g2).mapping(iso).run())
272 template<class G1,class G2>
273 int checkInd(const G1 &g1, const G2 &g2)
275 typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
276 if(vf2(g1,g2).induced().mapping(iso).run())
284 template<class G1,class G2>
285 int checkIso(const G1 &g1, const G2 &g2)
287 typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
288 if(vf2(g1,g2).iso().mapping(iso).run())
290 check(countNodes(g1)==countNodes(g2),
291 "Wrong iso alg.: they are not isomophic.");
298 template<class G1, class G2, class L1, class L2, class I>
299 void checkLabel(const G1 &g1, const G2 &,
300 const L1 &l1, const L2 &l2,const I &i)
302 for(typename G1::NodeIt n(g1);n!=INVALID;++n)
304 check(l1[n]==l2[i[n]],"Wrong isomorphism: label mismatch.");
308 template<class G1,class G2,class L1,class L2>
309 int checkSub(const G1 &g1, const G2 &g2, const L1 &l1, const L2 &l2)
311 typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
312 if(vf2(g1,g2).nodeLabels(l1,l2).mapping(iso).run())
315 checkLabel(g1,g2,l1,l2,iso);
323 check(checkSub(c5,petersen), "There should exist a C5->Petersen mapping.");
324 check(!checkSub(c7,petersen),
325 "There should not exist a C7->Petersen mapping.");
326 check(checkSub(p10,petersen), "There should exist a P10->Petersen mapping.");
327 check(!checkSub(c10,petersen),
328 "There should not exist a C10->Petersen mapping.");
329 check(checkSub(petersen,petersen),
330 "There should exist a Petersen->Petersen mapping.");
332 check(checkInd(c5,petersen),
333 "There should exist a C5->Petersen spanned mapping.");
334 check(!checkInd(c7,petersen),
335 "There should exist a C7->Petersen spanned mapping.");
336 check(!checkInd(p10,petersen),
337 "There should not exist a P10->Petersen spanned mapping.");
338 check(!checkInd(c10,petersen),
339 "There should not exist a C10->Petersen spanned mapping.");
340 check(checkInd(petersen,petersen),
341 "There should exist a Petersen->Petersen spanned mapping.");
343 check(!checkSub(petersen,c10),
344 "There should not exist a Petersen->C10 mapping.");
345 check(checkSub(p10,c10),
346 "There should exist a P10->C10 mapping.");
347 check(!checkInd(p10,c10),
348 "There should not exist a P10->C10 spanned mapping.");
349 check(!checkSub(c10,p10),
350 "There should not exist a C10->P10 mapping.");
352 check(!checkIso(p10,c10),
353 "P10 and C10 are not isomorphic.");
354 check(checkIso(c10,c10),
355 "C10 and C10 are not isomorphic.");
357 check(!checkSub(c5,petersen,c5_col,petersen_col1),
358 "There should exist a C5->Petersen mapping.");
359 check(checkSub(c5,petersen,c5_col,petersen_col2),
360 "There should exist a C5->Petersen mapping.");