lemon/vf2.h
changeset 1142 2f479109a71d
parent 1141 a037254714b3
child 1143 f85ee41c84bc
equal deleted inserted replaced
0:4154321abb8e 1:92bdbb1ec7aa
    16  */
    16  */
    17 
    17 
    18 #ifndef LEMON_VF2_H
    18 #ifndef LEMON_VF2_H
    19 #define LEMON_VF2_H
    19 #define LEMON_VF2_H
    20 
    20 
       
    21 ///\ingroup graph_properties
       
    22 ///\file
       
    23 ///\brief VF2 algorithm \cite cordella2004sub.
       
    24 
    21 #include <lemon/core.h>
    25 #include <lemon/core.h>
    22 #include <lemon/concepts/graph.h>
    26 #include <lemon/concepts/graph.h>
    23 #include <lemon/dfs.h>
    27 #include <lemon/dfs.h>
    24 #include <lemon/bfs.h>
    28 #include <lemon/bfs.h>
    25 #include <test/test_tools.h>
    29 #include <test/test_tools.h>
    88         }
    92         }
    89       };
    93       };
    90     }
    94     }
    91   }
    95   }
    92 
    96 
    93   enum MappingType {
    97   ///Graph mapping types.
       
    98 
       
    99   ///\ingroup graph_isomorphism
       
   100   ///The \ref Vf2 "VF2" algorithm is capable of finding different kind of
       
   101   ///embeddings, this enum specifies its type.
       
   102   ///
       
   103   ///See \ref graph_isomorphism for a more detailed description.
       
   104   enum Vf2MappingType {
       
   105     /// Subgraph isomorphism
    94     SUBGRAPH = 0,
   106     SUBGRAPH = 0,
       
   107     /// Induced subgraph isomorphism
    95     INDUCED = 1,
   108     INDUCED = 1,
       
   109     /// Graph isomorphism
       
   110 
       
   111     /// If the two graph has the same number of nodes, than it is
       
   112     /// equivalent to \ref INDUCED, and if they also have the same
       
   113     /// number of edges, then it is also equivalent to \ref SUBGRAPH.
       
   114     ///
       
   115     /// However, using this setting is faster than the other two
       
   116     /// options.
    96     ISOMORPH = 2
   117     ISOMORPH = 2
    97   };
   118   };
    98 
   119 
    99   template<class G1, class G2, class I, class NEq = bits::vf2::AlwaysEq >
   120   ///%VF2 algorithm class.
       
   121 
       
   122   ///\ingroup graph_isomorphism This class provides an efficient
       
   123   ///implementation of the %VF2 algorithm \cite cordella2004sub
       
   124   ///for variants of the (Sub)graph Isomorphism problem.
       
   125   ///
       
   126   ///There is also a \ref vf2() "function-type interface" called \ref vf2()
       
   127   ///for the %VF2 algorithm, which is probably more convenient in most
       
   128   ///use-cases.
       
   129   ///
       
   130   ///\tparam G1 The type of the graph to be embedded.
       
   131   ///The default type is \ref ListDigraph.
       
   132   ///\tparam G2 The type of the graph g1 will be embedded into.
       
   133   ///The default type is \ref ListDigraph.
       
   134   ///\tparam M The type of the NodeMap storing the mapping.
       
   135   ///By default, it is G1::NodeMap<G2::Node>
       
   136   ///\tparam NEQ A bool-valued binary functor determinining whether a node is
       
   137   ///mappable to another. By default it is an always true operator.
       
   138   ///
       
   139   ///\sa vf2()
       
   140 #ifdef DOXYGEN
       
   141   template<class G1, class G2, class M, class NEQ >
       
   142 #else
       
   143   template<class G1=ListDigraph,
       
   144            class G2=ListDigraph,
       
   145            class M = typename G1::template NodeMap<G2::Node>,
       
   146            class NEQ = bits::vf2::AlwaysEq >
       
   147 #endif
   100   class Vf2
   148   class Vf2
   101   {
   149   {
   102     //Current depth in the DFS tree.
   150     //Current depth in the DFS tree.
   103     int _depth;
   151     int _depth;
   104     //Functor with bool operator()(G1::Node,G2::Node), which returns 1
   152     //Functor with bool operator()(G1::Node,G2::Node), which returns 1
   105     //if and only if the 2 nodes are equivalent.
   153     //if and only if the 2 nodes are equivalent.
   106     NEq _nEq;
   154     NEQ _nEq;
   107 
   155 
   108     typename G2::template NodeMap<int> _conn;
   156     typename G2::template NodeMap<int> _conn;
   109     //Current matching. We index it by the nodes of g1, and match[v] is
   157     //Current mapping. We index it by the nodes of g1, and match[v] is
   110     //a node of g2.
   158     //a node of g2.
   111     I &_match;
   159     M &_mapping;
   112     //order[i] is the node of g1, for which we find a pair if depth=i
   160     //order[i] is the node of g1, for which we find a pair if depth=i
   113     std::vector<typename G1::Node> order;
   161     std::vector<typename G1::Node> order;
   114     //currEdgeIts[i] is an edge iterator, witch is last used in the ith
   162     //currEdgeIts[i] is an edge iterator, witch is last used in the ith
   115     //depth to find a pair for order[i].
   163     //depth to find a pair for order[i].
   116     std::vector<typename G2::IncEdgeIt> currEdgeIts;
   164     std::vector<typename G2::IncEdgeIt> currEdgeIts;
   119     //The big graph.
   167     //The big graph.
   120     const G2 &_g2;
   168     const G2 &_g2;
   121     //lookup tables for cut the searchtree
   169     //lookup tables for cut the searchtree
   122     typename G1::template NodeMap<int> rNew1t,rInOut1t;
   170     typename G1::template NodeMap<int> rNew1t,rInOut1t;
   123 
   171 
   124     MappingType _mapping_type;
   172     Vf2MappingType _mapping_type;
   125 
   173 
   126     //cut the search tree
   174     //cut the search tree
   127     template<MappingType MT>
   175     template<Vf2MappingType MT>
   128     bool cut(const typename G1::Node n1,const typename G2::Node n2) const
   176     bool cut(const typename G1::Node n1,const typename G2::Node n2) const
   129     {
   177     {
   130       int rNew2=0,rInOut2=0;
   178       int rNew2=0,rInOut2=0;
   131       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2)
   179       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2)
   132         {
   180         {
   147         default:
   195         default:
   148           return false;
   196           return false;
   149         }
   197         }
   150     }
   198     }
   151 
   199 
   152     template<MappingType MT>
   200     template<Vf2MappingType MT>
   153     bool feas(const typename G1::Node n1,const typename G2::Node n2)
   201     bool feas(const typename G1::Node n1,const typename G2::Node n2)
   154     {
   202     {
   155       if(!_nEq(n1,n2))
   203       if(!_nEq(n1,n2))
   156         return 0;
   204         return 0;
   157 
   205 
   158       for(typename G1::IncEdgeIt e1(_g1,n1); e1!=INVALID; ++e1)
   206       for(typename G1::IncEdgeIt e1(_g1,n1); e1!=INVALID; ++e1)
   159         {
   207         {
   160           const typename G1::Node currNode=_g1.oppositeNode(n1,e1);
   208           const typename G1::Node currNode=_g1.oppositeNode(n1,e1);
   161           if(_match[currNode]!=INVALID)
   209           if(_mapping[currNode]!=INVALID)
   162             --_conn[_match[currNode]];
   210             --_conn[_mapping[currNode]];
   163         }
   211         }
   164       bool isIso=1;
   212       bool isIso=1;
   165       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2)
   213       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2)
   166         {
   214         {
   167           const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
   215           const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
   175         }
   223         }
   176 
   224 
   177       for(typename G1::IncEdgeIt e1(_g1,n1); e1!=INVALID; ++e1)
   225       for(typename G1::IncEdgeIt e1(_g1,n1); e1!=INVALID; ++e1)
   178         {
   226         {
   179           const typename G1::Node currNode=_g1.oppositeNode(n1,e1);
   227           const typename G1::Node currNode=_g1.oppositeNode(n1,e1);
   180           if(_match[currNode]!=INVALID&&_conn[_match[currNode]]!=-1)
   228           if(_mapping[currNode]!=INVALID&&_conn[_mapping[currNode]]!=-1)
   181             {
   229             {
   182               switch(MT)
   230               switch(MT)
   183                 {
   231                 {
   184                 case INDUCED:
   232                 case INDUCED:
   185                 case ISOMORPH:
   233                 case ISOMORPH:
   186                   isIso=0;
   234                   isIso=0;
   187                   break;
   235                   break;
   188                 case SUBGRAPH:
   236                 case SUBGRAPH:
   189                   if(_conn[_match[currNode]]<-1)
   237                   if(_conn[_mapping[currNode]]<-1)
   190                     isIso=0;
   238                     isIso=0;
   191                   break;
   239                   break;
   192                 }
   240                 }
   193               _conn[_match[currNode]]=-1;
   241               _conn[_mapping[currNode]]=-1;
   194             }
   242             }
   195         }
   243         }
   196       return isIso&&cut<MT>(n1,n2);
   244       return isIso&&cut<MT>(n1,n2);
   197     }
   245     }
   198 
   246 
   199     void addPair(const typename G1::Node n1,const typename G2::Node n2)
   247     void addPair(const typename G1::Node n1,const typename G2::Node n2)
   200     {
   248     {
   201       _conn[n2]=-1;
   249       _conn[n2]=-1;
   202       _match.set(n1,n2);
   250       _mapping.set(n1,n2);
   203       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2)
   251       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2)
   204         if(_conn[_g2.oppositeNode(n2,e2)]!=-1)
   252         if(_conn[_g2.oppositeNode(n2,e2)]!=-1)
   205           ++_conn[_g2.oppositeNode(n2,e2)];
   253           ++_conn[_g2.oppositeNode(n2,e2)];
   206     }
   254     }
   207 
   255 
   208     void subPair(const typename G1::Node n1,const typename G2::Node n2)
   256     void subPair(const typename G1::Node n1,const typename G2::Node n2)
   209     {
   257     {
   210       _conn[n2]=0;
   258       _conn[n2]=0;
   211       _match.set(n1,INVALID);
   259       _mapping.set(n1,INVALID);
   212       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2)
   260       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2)
   213         {
   261         {
   214           const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
   262           const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
   215           if(_conn[currNode]>0)
   263           if(_conn[currNode]>0)
   216             --_conn[currNode];
   264             --_conn[currNode];
   229       bits::vf2::BfsLeaveOrder<G1> v(_g1,order);
   277       bits::vf2::BfsLeaveOrder<G1> v(_g1,order);
   230       BfsVisit<G1,bits::vf2::BfsLeaveOrder<G1> >bfs(_g1, v);
   278       BfsVisit<G1,bits::vf2::BfsLeaveOrder<G1> >bfs(_g1, v);
   231       bfs.run();
   279       bfs.run();
   232     }
   280     }
   233 
   281 
   234   public:
   282     template<Vf2MappingType MT>
   235 
       
   236     template<MappingType MT>
       
   237     bool extMatch()
   283     bool extMatch()
   238     {
   284     {
   239       while(_depth>=0)
   285       while(_depth>=0)
   240         {
   286         {
   241           //there are not nodes in g1, which has not pair in g2.
   287           //there are not nodes in g1, which has not pair in g2.
   248           //the pair of order[_depth]
   294           //the pair of order[_depth]
   249           typename G2::Node currPNode;
   295           typename G2::Node currPNode;
   250           if(currEdgeIts[_depth]==INVALID)
   296           if(currEdgeIts[_depth]==INVALID)
   251             {
   297             {
   252               typename G1::IncEdgeIt fstMatchedE(_g1,order[_depth]);
   298               typename G1::IncEdgeIt fstMatchedE(_g1,order[_depth]);
   253               //if _match[order[_depth]]!=INVALID, we dont use
   299               //if _mapping[order[_depth]]!=INVALID, we dont use
   254               //fstMatchedE
   300               //fstMatchedE
   255               if(_match[order[_depth]]==INVALID)
   301               if(_mapping[order[_depth]]==INVALID)
   256                 for(; fstMatchedE!=INVALID &&
   302                 for(; fstMatchedE!=INVALID &&
   257                       _match[_g1.oppositeNode(order[_depth],
   303                       _mapping[_g1.oppositeNode(order[_depth],
   258                                               fstMatchedE)]==INVALID;
   304                                               fstMatchedE)]==INVALID;
   259                     ++fstMatchedE) ; //find fstMatchedE
   305                     ++fstMatchedE) ; //find fstMatchedE
   260               if(fstMatchedE==INVALID||_match[order[_depth]]!=INVALID)
   306               if(fstMatchedE==INVALID||_mapping[order[_depth]]!=INVALID)
   261                 {
   307                 {
   262                   //We did not find an covered neighbour, this means
   308                   //We did not find an covered neighbour, this means
   263                   //the graph is not connected(or _depth==0).  Every
   309                   //the graph is not connected(or _depth==0).  Every
   264                   //uncovered(and there are some other properties due
   310                   //uncovered(and there are some other properties due
   265                   //to the spec. problem types) node of g2 is
   311                   //to the spec. problem types) node of g2 is
   266                   //candidate.  We can read the iterator of the last
   312                   //candidate.  We can read the iterator of the last
   267                   //tryed node from the match if it is not the first
   313                   //tryed node from the match if it is not the first
   268                   //try(match[order[_depth]]!=INVALID)
   314                   //try(match[order[_depth]]!=INVALID)
   269                   typename G2::NodeIt n2(_g2);
   315                   typename G2::NodeIt n2(_g2);
   270                   //if its not the first try
   316                   //if its not the first try
   271                   if(_match[order[_depth]]!=INVALID)
   317                   if(_mapping[order[_depth]]!=INVALID)
   272                     {
   318                     {
   273                       n2=++typename G2::NodeIt(_g2,_match[order[_depth]]);
   319                       n2=++typename G2::NodeIt(_g2,_mapping[order[_depth]]);
   274                       subPair(order[_depth],_match[order[_depth]]);
   320                       subPair(order[_depth],_mapping[order[_depth]]);
   275                     }
   321                     }
   276                   for(; n2!=INVALID; ++n2)
   322                   for(; n2!=INVALID; ++n2)
   277                     if(MT!=SUBGRAPH&&_conn[n2]==0)
   323                     if(MT!=SUBGRAPH&&_conn[n2]==0)
   278                       {
   324                       {
   279                         if(feas<MT>(order[_depth],n2))
   325                         if(feas<MT>(order[_depth],n2))
   292                     --_depth;
   338                     --_depth;
   293                   continue;
   339                   continue;
   294                 }
   340                 }
   295               else
   341               else
   296                 {
   342                 {
   297                   currPNode=_match[_g1.oppositeNode(order[_depth],fstMatchedE)];
   343                   currPNode=_mapping[_g1.oppositeNode(order[_depth],
       
   344                                                       fstMatchedE)];
   298                   currEdgeIts[_depth]=typename G2::IncEdgeIt(_g2,currPNode);
   345                   currEdgeIts[_depth]=typename G2::IncEdgeIt(_g2,currPNode);
   299                 }
   346                 }
   300             }
   347             }
   301           else
   348           else
   302             {
   349             {
   303               currPNode=_g2.oppositeNode(_match[order[_depth]],
   350               currPNode=_g2.oppositeNode(_mapping[order[_depth]],
   304                                          currEdgeIts[_depth]);
   351                                          currEdgeIts[_depth]);
   305               subPair(order[_depth],_match[order[_depth]]);
   352               subPair(order[_depth],_mapping[order[_depth]]);
   306               ++currEdgeIts[_depth];
   353               ++currEdgeIts[_depth];
   307             }
   354             }
   308           for(; currEdgeIts[_depth]!=INVALID; ++currEdgeIts[_depth])
   355           for(; currEdgeIts[_depth]!=INVALID; ++currEdgeIts[_depth])
   309             {
   356             {
   310               const typename G2::Node currNode =
   357               const typename G2::Node currNode =
   343                 ++tmp[currNode];
   390                 ++tmp[currNode];
   344             }
   391             }
   345         }
   392         }
   346     }
   393     }
   347   public:
   394   public:
   348     Vf2(const G1 &g1, const G2 &g2,I &i, const NEq &nEq = NEq() ) :
   395     ///Constructor
   349       _nEq(nEq), _conn(g2,0), _match(i), order(countNodes(g1)),
   396 
       
   397     ///Constructor
       
   398 
       
   399     ///\param g1 The graph to be embedded into \e g2.
       
   400     ///\param g2 The graph \e g1 will be embedded into.
       
   401     ///\param m \ref concepts::ReadWriteMap "read-write" NodeMap
       
   402     ///storing the found mapping.
       
   403     ///\param neq A bool-valued binary functor determinining whether a node is
       
   404     ///mappable to another. By default it is an always true operator.
       
   405     Vf2(const G1 &g1, const G2 &g2,M &m, const NEQ &neq = NEQ() ) :
       
   406       _nEq(neq), _conn(g2,0), _mapping(m), order(countNodes(g1)),
   350       currEdgeIts(countNodes(g1),INVALID), _g1(g1), _g2(g2), rNew1t(g1,0),
   407       currEdgeIts(countNodes(g1),INVALID), _g1(g1), _g2(g2), rNew1t(g1,0),
   351       rInOut1t(g1,0), _mapping_type(SUBGRAPH)
   408       rInOut1t(g1,0), _mapping_type(SUBGRAPH)
   352     {
   409     {
   353       _depth=0;
   410       _depth=0;
   354       setOrder();
   411       setOrder();
   355       setRNew1tRInOut1t();
   412       setRNew1tRInOut1t();
   356     }
   413     }
   357 
   414 
   358     MappingType mappingType() const { return _mapping_type; }
   415     ///Returns the current mapping type
   359     void mappingType(MappingType m_type) { _mapping_type = m_type; }
   416 
   360 
   417     ///Returns the current mapping type
       
   418     ///
       
   419     Vf2MappingType mappingType() const { return _mapping_type; }
       
   420     ///Sets mapping type
       
   421 
       
   422     ///Sets mapping type.
       
   423     ///
       
   424     ///The mapping type is set to \ref SUBGRAPH by default.
       
   425     ///
       
   426     ///\sa See \ref for the possible values.
       
   427     void mappingType(Vf2MappingType m_type) { _mapping_type = m_type; }
       
   428 
       
   429     ///Find a mapping
       
   430 
       
   431     ///It finds a mapping between from g1 into g2 according to the mapping
       
   432     ///type set by \ref mappingType(Vf2MappingType) "mappingType()".
       
   433     ///
       
   434     ///By subsequent calls, it returns all possible mappings one-by-one.
       
   435     ///
       
   436     ///\retval true if a mapping is found.
       
   437     ///\retval false if there is no (more) mapping.
   361     bool find()
   438     bool find()
   362     {
   439     {
   363       switch(_mapping_type)
   440       switch(_mapping_type)
   364         {
   441         {
   365         case SUBGRAPH:
   442         case SUBGRAPH:
   382     typedef G2 Graph2;
   459     typedef G2 Graph2;
   383 
   460 
   384     const G1 &_g1;
   461     const G1 &_g1;
   385     const G2 &_g2;
   462     const G2 &_g2;
   386 
   463 
   387     MappingType _mapping_type;
   464     Vf2MappingType _mapping_type;
   388 
   465 
   389     typedef typename G1::template NodeMap<typename G2::Node> Mapping;
   466     typedef typename G1::template NodeMap<typename G2::Node> Mapping;
   390     bool _local_mapping;
   467     bool _local_mapping;
   391     void *_mapping;
   468     void *_mapping;
   392     void createMapping()
   469     void createMapping()
   399 
   476 
   400     Vf2WizardBase(const G1 &g1,const G2 &g2)
   477     Vf2WizardBase(const G1 &g1,const G2 &g2)
   401       : _g1(g1), _g2(g2), _mapping_type(SUBGRAPH), _local_mapping(true) {}
   478       : _g1(g1), _g2(g2), _mapping_type(SUBGRAPH), _local_mapping(true) {}
   402   };
   479   };
   403 
   480 
       
   481   /// Auxiliary class for the function-type interface of %VF2 algorithm.
       
   482 
       
   483   /// This auxiliary class implements the named parameters of
       
   484   /// \ref vf2() "function-type interface" of \ref Vf2 algorithm.
       
   485   ///
       
   486   /// \warning This class should only be used through the function \ref vf2().
       
   487   ///
       
   488   /// \tparam TR The traits class that defines various types used by the
       
   489   /// algorithm.
   404   template<class TR>
   490   template<class TR>
   405   class Vf2Wizard : public TR
   491   class Vf2Wizard : public TR
   406   {
   492   {
   407     typedef TR Base;
   493     typedef TR Base;
   408     typedef typename TR::Graph1 Graph1;
   494     typedef typename TR::Graph1 Graph1;
   416     using TR::_mapping_type;
   502     using TR::_mapping_type;
   417     using TR::_mapping;
   503     using TR::_mapping;
   418     using TR::_node_eq;
   504     using TR::_node_eq;
   419 
   505 
   420   public:
   506   public:
   421     ///Copy constructor
   507     ///Constructor
   422     Vf2Wizard(const Graph1 &g1,const Graph2 &g2) : Base(g1,g2) {}
   508     Vf2Wizard(const Graph1 &g1,const Graph2 &g2) : Base(g1,g2) {}
   423 
   509 
   424     ///Copy constructor
   510     ///Copy constructor
   425     Vf2Wizard(const Base &b) : Base(b) {}
   511     Vf2Wizard(const Base &b) : Base(b) {}
   426 
   512 
   455     ///\brief \ref named-templ-param "Named parameter" for setting
   541     ///\brief \ref named-templ-param "Named parameter" for setting
   456     ///the node equivalence relation.
   542     ///the node equivalence relation.
   457     ///
   543     ///
   458     ///\ref named-templ-param "Named parameter" function for setting
   544     ///\ref named-templ-param "Named parameter" function for setting
   459     ///the equivalence relation between the nodes.
   545     ///the equivalence relation between the nodes.
       
   546     ///
       
   547     ///\param node_eq A bool-valued binary functor determinining
       
   548     ///whether a node is mappable to another. By default it is an
       
   549     ///always true operator.
   460     template<class T>
   550     template<class T>
   461     Vf2Wizard< SetNodeEqBase<T> > nodeEq(const T &node_eq)
   551     Vf2Wizard< SetNodeEqBase<T> > nodeEq(const T &node_eq)
   462     {
   552     {
   463       return Vf2Wizard<SetNodeEqBase<T> >(SetNodeEqBase<T>(*this,node_eq));
   553       return Vf2Wizard<SetNodeEqBase<T> >(SetNodeEqBase<T>(*this,node_eq));
   464     }
   554     }
   466     ///\brief \ref named-templ-param "Named parameter" for setting
   556     ///\brief \ref named-templ-param "Named parameter" for setting
   467     ///the node labels.
   557     ///the node labels.
   468     ///
   558     ///
   469     ///\ref named-templ-param "Named parameter" function for setting
   559     ///\ref named-templ-param "Named parameter" function for setting
   470     ///the node labels defining equivalence relation between them.
   560     ///the node labels defining equivalence relation between them.
       
   561     ///
       
   562     ///\param m1 It is arbitrary \ref ReadMap "readable node map" of g1.
       
   563     ///\param m1 It is arbitrary \ref ReadMap "readable node map" of g2.
       
   564     ///
       
   565     ///The value type of these maps must be equal comparable.
   471     template<class M1, class M2>
   566     template<class M1, class M2>
   472     Vf2Wizard< SetNodeEqBase<bits::vf2::MapEq<M1,M2> > >
   567     Vf2Wizard< SetNodeEqBase<bits::vf2::MapEq<M1,M2> > >
   473     nodeLabels(const M1 &m1,const M2 &m2)
   568     nodeLabels(const M1 &m1,const M2 &m2)
   474     {
   569     {
   475       return nodeEq(bits::vf2::MapEq<M1,M2>(m1,m2));
   570       return nodeEq(bits::vf2::MapEq<M1,M2>(m1,m2));
   476     }
   571     }
   477 
   572 
   478     Vf2Wizard<Base> &mappingType(MappingType m_type)
   573     ///\brief \ref named-templ-param "Named parameter" for setting
       
   574     ///the mapping type.
       
   575     ///
       
   576     ///\ref named-templ-param "Named parameter" for setting
       
   577     ///the mapping type.
       
   578     ///
       
   579     ///The mapping type is set to \ref SUBGRAPH by default.
       
   580     ///
       
   581     ///\sa See \ref for the possible values.
       
   582     Vf2Wizard<Base> &mappingType(Vf2MappingType m_type)
   479     {
   583     {
   480       _mapping_type = m_type;
   584       _mapping_type = m_type;
   481       return *this;
   585       return *this;
   482     }
   586     }
   483 
   587 
       
   588     ///\brief \ref named-templ-param "Named parameter" for setting
       
   589     ///the mapping type to \ref INDUCED.
       
   590     ///
       
   591     ///\ref named-templ-param "Named parameter" for setting
       
   592     ///the mapping type to \ref INDUCED.
   484     Vf2Wizard<Base> &induced()
   593     Vf2Wizard<Base> &induced()
   485     {
   594     {
   486       _mapping_type = INDUCED;
   595       _mapping_type = INDUCED;
   487       return *this;
   596       return *this;
   488     }
   597     }
   489 
   598 
       
   599     ///\brief \ref named-templ-param "Named parameter" for setting
       
   600     ///the mapping type to \ref ISOMORPH.
       
   601     ///
       
   602     ///\ref named-templ-param "Named parameter" for setting
       
   603     ///the mapping type to \ref ISOMORPH.
   490     Vf2Wizard<Base> &iso()
   604     Vf2Wizard<Base> &iso()
   491     {
   605     {
   492       _mapping_type = ISOMORPH;
   606       _mapping_type = ISOMORPH;
   493       return *this;
   607       return *this;
   494     }
   608     }
   495 
   609 
       
   610     ///Runs VF2 algorithm.
       
   611 
       
   612     ///This method runs VF2 algorithm.
       
   613     ///
       
   614     ///\retval true if a mapping is found.
       
   615     ///\retval false if there is no (more) mapping.
   496     bool run()
   616     bool run()
   497     {
   617     {
   498       if(Base::_local_mapping)
   618       if(Base::_local_mapping)
   499         Base::createMapping();
   619         Base::createMapping();
   500 
   620 
   510 
   630 
   511       return ret;
   631       return ret;
   512     }
   632     }
   513   };
   633   };
   514 
   634 
       
   635   ///Function-type interface for VF2 algorithm.
       
   636 
       
   637   /// \ingroup graph_isomorphism
       
   638   ///Function-type interface for VF2 algorithm \cite cordella2004sub.
       
   639   ///
       
   640   ///This function has several \ref named-func-param "named parameters"
       
   641   ///declared as the members of class \ref Vf2Wizard.
       
   642   ///The following examples show how to use these parameters.
       
   643   ///\code
       
   644   ///  // Find an embedding of graph g into graph h
       
   645   ///  ListGraph::NodeMap<ListGraph::Node> m(g);
       
   646   ///  vf2(g,h).mapping(m).run();
       
   647   ///
       
   648   ///  // Check whether graphs g and h are isomorphic
       
   649   ///  bool is_iso = vf2(g,h).iso().run();
       
   650   ///\endcode
       
   651   ///\warning Don't forget to put the \ref Vf2Wizard::run() "run()"
       
   652   ///to the end of the expression.
       
   653   ///\sa Vf2Wizard
       
   654   ///\sa Vf2
   515   template<class G1, class G2>
   655   template<class G1, class G2>
   516   Vf2Wizard<Vf2WizardBase<G1,G2> > vf2(const G1 &g1, const G2 &g2)
   656   Vf2Wizard<Vf2WizardBase<G1,G2> > vf2(const G1 &g1, const G2 &g2)
   517   {
   657   {
   518     return Vf2Wizard<Vf2WizardBase<G1,G2> >(g1,g2);
   658     return Vf2Wizard<Vf2WizardBase<G1,G2> >(g1,g2);
   519   }
   659   }