lemon/vf2.h
changeset 1407 76349d8212d3
parent 1405 3feba0ea1bda
child 1408 b9fad0f9f8ab
equal deleted inserted replaced
6:49ea1e75db3c 7:d18e31eef0ad
    51         bool operator()(typename M1::Key k1, typename M2::Key k2) const {
    51         bool operator()(typename M1::Key k1, typename M2::Key k2) const {
    52           return _m1[k1] == _m2[k2];
    52           return _m1[k1] == _m2[k2];
    53         }
    53         }
    54       };
    54       };
    55 
    55 
    56 
       
    57 
       
    58       template <class G>
    56       template <class G>
    59       class DfsLeaveOrder : public DfsVisitor<G> {
    57       class DfsLeaveOrder : public DfsVisitor<G> {
    60         const G &_g;
    58         const G &_g;
    61         std::vector<typename G::Node> &_order;
    59         std::vector<typename G::Node> &_order;
    62         int i;
    60         int i;
    91   ///implementation of the %VF2 algorithm \cite cordella2004sub
    89   ///implementation of the %VF2 algorithm \cite cordella2004sub
    92   ///for variants of the (Sub)graph Isomorphism problem.
    90   ///for variants of the (Sub)graph Isomorphism problem.
    93   ///
    91   ///
    94   ///There is also a \ref vf2() "function-type interface" called \ref vf2()
    92   ///There is also a \ref vf2() "function-type interface" called \ref vf2()
    95   ///for the %VF2 algorithm, which is probably more convenient in most
    93   ///for the %VF2 algorithm, which is probably more convenient in most
    96   ///use-cases.
    94   ///use cases.
    97   ///
    95   ///
    98   ///\tparam G1 The type of the graph to be embedded.
    96   ///\tparam G1 The type of the graph to be embedded.
    99   ///The default type is \ref ListDigraph.
    97   ///The default type is \ref ListDigraph.
   100   ///\tparam G2 The type of the graph g1 will be embedded into.
    98   ///\tparam G2 The type of the graph g1 will be embedded into.
   101   ///The default type is \ref ListDigraph.
    99   ///The default type is \ref ListDigraph.
   102   ///\tparam M The type of the NodeMap storing the mapping.
   100   ///\tparam M The type of the NodeMap storing the mapping.
   103   ///By default, it is G1::NodeMap<G2::Node>
   101   ///By default, it is G1::NodeMap<G2::Node>
   104   ///\tparam NEQ A bool-valued binary functor determinining whether a node is
   102   ///\tparam NEQ A bool-valued binary functor determinining whether a node is
   105   ///mappable to another. By default it is an always true operator.
   103   ///mappable to another. By default, it is an always-true operator.
   106   ///
   104   ///
   107   ///\sa vf2()
   105   ///\sa vf2()
   108 #ifdef DOXYGEN
   106 #ifdef DOXYGEN
   109   template<class G1, class G2, class M, class NEQ >
   107   template<class G1, class G2, class M, class NEQ >
   110 #else
   108 #else
   114            class NEQ = bits::vf2::AlwaysEq >
   112            class NEQ = bits::vf2::AlwaysEq >
   115 #endif
   113 #endif
   116   class Vf2 {
   114   class Vf2 {
   117     //Current depth in the DFS tree.
   115     //Current depth in the DFS tree.
   118     int _depth;
   116     int _depth;
       
   117 
   119     //Functor with bool operator()(G1::Node,G2::Node), which returns 1
   118     //Functor with bool operator()(G1::Node,G2::Node), which returns 1
   120     //ifff the two nodes are equivalent.
   119     //if and only if the two nodes are equivalent
   121     NEQ _nEq;
   120     NEQ _nEq;
   122 
   121 
       
   122     //_conn[v2] = number of covered neighbours of v2
   123     typename G2::template NodeMap<int> _conn;
   123     typename G2::template NodeMap<int> _conn;
   124     //Current mapping. We index it by the nodes of g1, and match[v] is
   124 
   125     //a node of g2.
   125     //The current mapping. _mapping[v1]=v2 iff v1 has been mapped to v2,
       
   126     //where v1 is a node of G1 and v2 is a node of G2
   126     M &_mapping;
   127     M &_mapping;
   127     //order[i] is the node of g1, for which we search a pair if depth=i
   128 
       
   129     //order[i] is the node of g1 for which a pair is searched if depth=i
   128     std::vector<typename G1::Node> order;
   130     std::vector<typename G1::Node> order;
   129     //currEdgeIts[i] is an edge iterator, witch is last used in the ith
   131 
   130     //depth to find a pair for order[i].
   132     //currEdgeIts[i] is the last used edge iterator in the i-th
       
   133     //depth to find a pair for node order[i]
   131     std::vector<typename G2::IncEdgeIt> currEdgeIts;
   134     std::vector<typename G2::IncEdgeIt> currEdgeIts;
   132     //The small graph.
   135  
       
   136     //The graph to be embedded
   133     const G1 &_g1;
   137     const G1 &_g1;
   134     //The large graph.
   138 
       
   139     //The graph into which g1 is to be embedded
   135     const G2 &_g2;
   140     const G2 &_g2;
       
   141 
   136     //lookup tables for cutting the searchtree
   142     //lookup tables for cutting the searchtree
   137     typename G1::template NodeMap<int> rNew1t,rInOut1t;
   143     typename G1::template NodeMap<int> rNew1t,rInOut1t;
   138 
   144 
   139     MappingType _mapping_type;
   145     MappingType _mapping_type;
   140 
   146 
   240     }
   246     }
   241 
   247 
   242     template<MappingType MT>
   248     template<MappingType MT>
   243     bool extMatch() {
   249     bool extMatch() {
   244       while(_depth>=0) {
   250       while(_depth>=0) {
   245         //there are not nodes in g1, which has not pair in g2.
       
   246         if(_depth==static_cast<int>(order.size())) {
   251         if(_depth==static_cast<int>(order.size())) {
       
   252           //all nodes of g1 are mapped to nodes of g2
   247           --_depth;
   253           --_depth;
   248           return true;
   254           return true;
   249         }
   255         }
   250         typename G1::Node& nodeOfDepth = order[_depth];
   256         typename G1::Node& nodeOfDepth = order[_depth];
   251         const typename G2::Node& pairOfNodeOfDepth = _mapping[nodeOfDepth];
   257         const typename G2::Node& pairOfNodeOfDepth = _mapping[nodeOfDepth];
   252         typename G2::IncEdgeIt &edgeItOfDepth = currEdgeIts[_depth];
   258         typename G2::IncEdgeIt &edgeItOfDepth = currEdgeIts[_depth];
   253         //the node of g2, which neighbours are the candidates for
   259         //the node of g2 whose neighbours are the candidates for
   254         //the pair of nodeOfDepth
   260         //the pair of nodeOfDepth
   255         typename G2::Node currPNode;
   261         typename G2::Node currPNode;
   256         if(edgeItOfDepth==INVALID) {
   262         if(edgeItOfDepth==INVALID) {
   257           typename G1::IncEdgeIt fstMatchedE(_g1,nodeOfDepth);
   263           typename G1::IncEdgeIt fstMatchedE(_g1,nodeOfDepth);
   258           //if pairOfNodeOfDepth!=INVALID, we dont use
   264           //if pairOfNodeOfDepth!=INVALID, we don't use fstMatchedE
   259           //fstMatchedE
   265           if(pairOfNodeOfDepth==INVALID) {
   260           if(pairOfNodeOfDepth==INVALID)
       
   261             for(; fstMatchedE!=INVALID &&
   266             for(; fstMatchedE!=INVALID &&
   262                   _mapping[_g1.oppositeNode(nodeOfDepth,
   267                   _mapping[_g1.oppositeNode(nodeOfDepth,
   263                                             fstMatchedE)]==INVALID;
   268                                             fstMatchedE)]==INVALID;
   264                 ++fstMatchedE) ; //find fstMatchedE
   269                 ++fstMatchedE) ; //find fstMatchedE
       
   270           }
   265           if(fstMatchedE==INVALID||pairOfNodeOfDepth!=INVALID) {
   271           if(fstMatchedE==INVALID||pairOfNodeOfDepth!=INVALID) {
   266             //We found no covered neighbours, this means
   272             //We found no covered neighbours, this means that
   267             //the graph is not connected(or _depth==0).  Each
   273             //the graph is not connected (or _depth==0). Each
   268             //uncovered(and there are some other properties due
   274             //uncovered (and there are some other properties due
   269             //to the spec. problem types) node of g2 is
   275             //to the spec. problem types) node of g2 is
   270             //candidate.  We can read the iterator of the last
   276             //candidate. We can read the iterator of the last
   271             //tried node from the match if it is not the first
   277             //tried node from the match if it is not the first
   272             //try(match[nodeOfDepth]!=INVALID)
   278             //try (match[nodeOfDepth]!=INVALID)
   273             typename G2::NodeIt n2(_g2);
   279             typename G2::NodeIt n2(_g2);
   274             //if it's not the first try
   280             //if it's not the first try
   275             if(pairOfNodeOfDepth!=INVALID) {
   281             if(pairOfNodeOfDepth!=INVALID) {
   276               n2=++typename G2::NodeIt(_g2,pairOfNodeOfDepth);
   282               n2=++typename G2::NodeIt(_g2,pairOfNodeOfDepth);
   277               subPair(nodeOfDepth,pairOfNodeOfDepth);
   283               subPair(nodeOfDepth,pairOfNodeOfDepth);
   315         edgeItOfDepth==INVALID?--_depth:++_depth;
   321         edgeItOfDepth==INVALID?--_depth:++_depth;
   316       }
   322       }
   317       return false;
   323       return false;
   318     }
   324     }
   319 
   325 
   320     //calc. the lookup table for cut the searchtree
   326     //calculate the lookup table for cutting the search tree
   321     void setRNew1tRInOut1t() {
   327     void setRNew1tRInOut1t() {
   322       typename G1::template NodeMap<int> tmp(_g1,0);
   328       typename G1::template NodeMap<int> tmp(_g1,0);
   323       for(unsigned int i=0; i<order.size(); ++i) {
   329       for(unsigned int i=0; i<order.size(); ++i) {
   324         const typename G1::Node& orderI = order[i];
   330         const typename G1::Node& orderI = order[i];
   325         tmp[orderI]=-1;
   331         tmp[orderI]=-1;
   349     ///\param neq A bool-valued binary functor determining whether a node is
   355     ///\param neq A bool-valued binary functor determining whether a node is
   350     ///mappable to another. By default it is an always true operator.
   356     ///mappable to another. By default it is an always true operator.
   351     Vf2(const G1 &g1, const G2 &g2, M &m, const NEQ &neq = NEQ() ) :
   357     Vf2(const G1 &g1, const G2 &g2, M &m, const NEQ &neq = NEQ() ) :
   352       _nEq(neq), _conn(g2,0), _mapping(m), order(countNodes(g1)),
   358       _nEq(neq), _conn(g2,0), _mapping(m), order(countNodes(g1)),
   353       currEdgeIts(countNodes(g1),INVALID), _g1(g1), _g2(g2), rNew1t(g1,0),
   359       currEdgeIts(countNodes(g1),INVALID), _g1(g1), _g2(g2), rNew1t(g1,0),
   354       rInOut1t(g1,0), _mapping_type(SUBGRAPH), _deallocMappingAfterUse(0) {
   360       rInOut1t(g1,0), _mapping_type(SUBGRAPH), _deallocMappingAfterUse(0)
       
   361     {
   355       _depth=0;
   362       _depth=0;
   356       setOrder();
   363       setOrder();
   357       setRNew1tRInOut1t();
   364       setRNew1tRInOut1t();
   358       for(typename G1::NodeIt n(g1);n!=INVALID;++n)
   365       for(typename G1::NodeIt n(g1);n!=INVALID;++n)
   359         m[n]=INVALID;
   366         m[n]=INVALID;
   438       : _g1(g1), _g2(g2), _mapping_type(SUBGRAPH), _local_mapping(true) { }
   445       : _g1(g1), _g2(g2), _mapping_type(SUBGRAPH), _local_mapping(true) { }
   439   };
   446   };
   440 
   447 
   441 
   448 
   442   /// Auxiliary class for the function-type interface of %VF2 algorithm.
   449   /// Auxiliary class for the function-type interface of %VF2 algorithm.
   443 
   450   ///
   444   /// This auxiliary class implements the named parameters of
   451   /// This auxiliary class implements the named parameters of
   445   /// \ref vf2() "function-type interface" of \ref Vf2 algorithm.
   452   /// \ref vf2() "function-type interface" of \ref Vf2 algorithm.
   446   ///
   453   ///
   447   /// \warning This class should only be used through the function \ref vf2().
   454   /// \warning This class is not to be used directly.
   448   ///
   455   ///
   449   /// \tparam TR The traits class that defines various types used by the
   456   /// \tparam TR The traits class that defines various types used by the
   450   /// algorithm.
   457   /// algorithm.
   451   template<class TR>
   458   template<class TR>
   452   class Vf2Wizard : public TR {
   459   class Vf2Wizard : public TR {
   463     using TR::_mapping;
   470     using TR::_mapping;
   464     using TR::_node_eq;
   471     using TR::_node_eq;
   465 
   472 
   466   public:
   473   public:
   467     ///Constructor
   474     ///Constructor
   468     Vf2Wizard(const Graph1 &g1,const Graph2 &g2) : Base(g1,g2) {
   475     Vf2Wizard(const Graph1 &g1,const Graph2 &g2) : Base(g1,g2) {}
   469     }
       
   470 
   476 
   471     ///Copy constructor
   477     ///Copy constructor
   472     Vf2Wizard(const Base &b) : Base(b) { }
   478     Vf2Wizard(const Base &b) : Base(b) {}
   473 
   479 
   474     ///Copy constructor
   480     ///Copy constructor
   475     Vf2Wizard(const Vf2Wizard &b) : Base(b) {}
   481     Vf2Wizard(const Vf2Wizard &b) : Base(b) {}
   476 
   482 
   477 
   483