lemon/vf2pp.h
changeset 1408 b9fad0f9f8ab
parent 1407 76349d8212d3
child 1409 c89884c1737b
equal deleted inserted replaced
1:211b83ad6ae7 2:2a949ca5a0d9
    26 #include <lemon/concepts/graph.h>
    26 #include <lemon/concepts/graph.h>
    27 #include <lemon/dfs.h>
    27 #include <lemon/dfs.h>
    28 #include <lemon/bfs.h>
    28 #include <lemon/bfs.h>
    29 #include <lemon/bits/vf2_internals.h>
    29 #include <lemon/bits/vf2_internals.h>
    30 
    30 
    31 
       
    32 #include <vector>
    31 #include <vector>
    33 #include <algorithm>
    32 #include <algorithm>
    34 #include <utility>
    33 #include <utility>
    35 
       
    36 
    34 
    37 namespace lemon {
    35 namespace lemon {
    38   namespace bits {
    36   namespace bits {
    39     namespace vf2pp {
    37     namespace vf2pp {
    40 
    38 
    99            class M = typename G1::template NodeMap<G2::Node>,
    97            class M = typename G1::template NodeMap<G2::Node>,
   100            class M1 = typename G1::template NodeMap<int>,
    98            class M1 = typename G1::template NodeMap<int>,
   101            class M2 = typename G2::template NodeMap<int> >
    99            class M2 = typename G2::template NodeMap<int> >
   102 #endif
   100 #endif
   103   class Vf2pp {
   101   class Vf2pp {
       
   102     //The graph to be embedded
       
   103     const G1 &_g1;
       
   104 
       
   105     //The graph into which g1 is to be embedded
       
   106     const G2 &_g2;
       
   107 
   104     //Current depth in the search tree.
   108     //Current depth in the search tree.
   105     int _depth;
   109     int _depth;
   106 
       
   107     //_conn[v2] = number of covered neighbours of v2
       
   108     typename G2::template NodeMap<int> _conn;
       
   109 
   110 
   110     //The current mapping. _mapping[v1]=v2 iff v1 has been mapped to v2,
   111     //The current mapping. _mapping[v1]=v2 iff v1 has been mapped to v2,
   111     //where v1 is a node of G1 and v2 is a node of G2
   112     //where v1 is a node of G1 and v2 is a node of G2
   112     M &_mapping;
   113     M &_mapping;
   113 
   114 
   114     //order[i] is a node of g1 for which a pair is searched if depth=i
   115     //_order[i] is a node of g1 for which a pair is searched if depth=i
   115     std::vector<typename G1::Node> order;
   116     std::vector<typename G1::Node> _order;
   116 
   117 
   117     //currEdgeIts[i] is the last used edge iterator in the i-th
   118     //_conn[v2] = number of covered neighbours of v2
   118     //depth to find a pair for node order[i]
   119     typename G2::template NodeMap<int> _conn;
   119     std::vector<typename G2::IncEdgeIt> currEdgeIts;
   120 
       
   121     //_currEdgeIts[i] is the last used edge iterator in the i-th
       
   122     //depth to find a pair for node _order[i]
       
   123     std::vector<typename G2::IncEdgeIt> _currEdgeIts;
   120  
   124  
   121     //The graph to be embedded
   125     //_rNewLabels1[v] is a pair of form
   122     const G1 &_g1;
       
   123 
       
   124     //The graph into which g1 is to be embedded
       
   125     const G2 &_g2;
       
   126 
       
   127     //rNewLabels1[v] is a pair of form
       
   128     //(label; num. of uncov. nodes with such label and no covered neighbours)
   126     //(label; num. of uncov. nodes with such label and no covered neighbours)
   129     typename G1::template NodeMap<std::vector<std::pair<int,int> > >
   127     typename G1::template NodeMap<std::vector<std::pair<int,int> > >
   130     rNewLabels1;
   128     _rNewLabels1;
   131 
   129 
   132     //rInOutLabels1[v] is the number of covered neighbours of v for each label
   130     //_rInOutLabels1[v] is the number of covered neighbours of v for each label
   133     //in form (label,number of such labels)
   131     //in form (label,number of such labels)
   134     typename G1::template NodeMap<std::vector<std::pair<int,int> > >
   132     typename G1::template NodeMap<std::vector<std::pair<int,int> > >
   135     rInOutLabels1;
   133     _rInOutLabels1;
   136 
   134 
   137     //_intLabels1[v]==i means that node v has label i in _g1
   135     //_intLabels1[v]==i means that node v has label i in _g1
   138     //(i is in {0,1,2,..,K-1}, where K is the number of diff. labels)
   136     //(i is in {0,1,2,..,K-1}, where K is the number of diff. labels)
   139     M1 &_intLabels1;
   137     M1 &_intLabels1;
   140 
   138 
   141     //_intLabels2[v]==i means that node v has label i in _g2
   139     //_intLabels2[v]==i means that node v has label i in _g2
   142     //(i is in {0,1,2,..,K-1}, where K is the number of diff. labels)
   140     //(i is in {0,1,2,..,K-1}, where K is the number of diff. labels)
   143     M2 &_intLabels2;
   141     M2 &_intLabels2;
   144 
   142 
   145     //largest label
   143     //largest label
   146     const int maxLabel;
   144     const int _maxLabel;
   147 
   145 
   148     //lookup tables for manipulating with label class cardinalities
   146     //lookup tables for manipulating with label class cardinalities
   149     //(after use they have to be reset to 0..0)
   147     //(after use they have to be reset to 0..0)
   150     std::vector<int> labelTmp1,labelTmp2;
   148     std::vector<int> _labelTmp1,_labelTmp2;
   151 
   149 
   152     MappingType _mapping_type;
   150     MappingType _mapping_type;
   153 
   151 
   154     //indicates whether the mapping or the labels must be deleted in the destructor
   152     //indicates whether the mapping or the labels must be deleted in the destructor
   155     bool _deallocMappingAfterUse,_deallocLabelsAfterUse;
   153     bool _deallocMappingAfterUse,_deallocLabelsAfterUse;
   159     template<MappingType MT>
   157     template<MappingType MT>
   160     bool cutByLabels(const typename G1::Node n1,const typename G2::Node n2) {
   158     bool cutByLabels(const typename G1::Node n1,const typename G2::Node n2) {
   161       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
   159       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
   162         const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
   160         const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
   163         if(_conn[currNode]>0)
   161         if(_conn[currNode]>0)
   164           --labelTmp1[_intLabels2[currNode]];
   162           --_labelTmp1[_intLabels2[currNode]];
   165         else if(MT!=SUBGRAPH&&_conn[currNode]==0)
   163         else if(MT!=SUBGRAPH&&_conn[currNode]==0)
   166           --labelTmp2[_intLabels2[currNode]];
   164           --_labelTmp2[_intLabels2[currNode]];
   167       }
   165       }
   168 
   166 
   169       bool ret=1;
   167       bool ret=1;
   170       if(ret) {
   168       if(ret) {
   171         for(unsigned int i = 0; i < rInOutLabels1[n1].size(); ++i)
   169         for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
   172           labelTmp1[rInOutLabels1[n1][i].first]+=rInOutLabels1[n1][i].second;
   170           _labelTmp1[_rInOutLabels1[n1][i].first]+=_rInOutLabels1[n1][i].second;
   173 
   171 
   174         if(MT!=SUBGRAPH)
   172         if(MT!=SUBGRAPH)
   175           for(unsigned int i = 0; i < rNewLabels1[n1].size(); ++i)
   173           for(unsigned int i = 0; i < _rNewLabels1[n1].size(); ++i)
   176             labelTmp2[rNewLabels1[n1][i].first]+=rNewLabels1[n1][i].second;
   174             _labelTmp2[_rNewLabels1[n1][i].first]+=_rNewLabels1[n1][i].second;
   177 
   175 
   178         switch(MT) {
   176         switch(MT) {
   179         case INDUCED:
   177         case INDUCED:
   180           for(unsigned int i = 0; i < rInOutLabels1[n1].size(); ++i)
   178           for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
   181             if(labelTmp1[rInOutLabels1[n1][i].first]>0) {
   179             if(_labelTmp1[_rInOutLabels1[n1][i].first]>0) {
   182               ret=0;
   180               ret=0;
   183               break;
   181               break;
   184             }
   182             }
   185           if(ret)
   183           if(ret)
   186             for(unsigned int i = 0; i < rNewLabels1[n1].size(); ++i)
   184             for(unsigned int i = 0; i < _rNewLabels1[n1].size(); ++i)
   187               if(labelTmp2[rNewLabels1[n1][i].first]>0) {
   185               if(_labelTmp2[_rNewLabels1[n1][i].first]>0) {
   188                 ret=0;
   186                 ret=0;
   189                 break;
   187                 break;
   190               }
   188               }
   191           break;
   189           break;
   192         case SUBGRAPH:
   190         case SUBGRAPH:
   193           for(unsigned int i = 0; i < rInOutLabels1[n1].size(); ++i)
   191           for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
   194             if(labelTmp1[rInOutLabels1[n1][i].first]>0) {
   192             if(_labelTmp1[_rInOutLabels1[n1][i].first]>0) {
   195               ret=0;
   193               ret=0;
   196               break;
   194               break;
   197             }
   195             }
   198           break;
   196           break;
   199         case ISOMORPH:
   197         case ISOMORPH:
   200           for(unsigned int i = 0; i < rInOutLabels1[n1].size(); ++i)
   198           for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
   201             if(labelTmp1[rInOutLabels1[n1][i].first]!=0) {
   199             if(_labelTmp1[_rInOutLabels1[n1][i].first]!=0) {
   202               ret=0;
   200               ret=0;
   203               break;
   201               break;
   204             }
   202             }
   205           if(ret)
   203           if(ret)
   206             for(unsigned int i = 0; i < rNewLabels1[n1].size(); ++i)
   204             for(unsigned int i = 0; i < _rNewLabels1[n1].size(); ++i)
   207               if(labelTmp2[rNewLabels1[n1][i].first]!=0) {
   205               if(_labelTmp2[_rNewLabels1[n1][i].first]!=0) {
   208                 ret=0;
   206                 ret=0;
   209                 break;
   207                 break;
   210               }
   208               }
   211           break;
   209           break;
   212         default:
   210         default:
   213           return false;
   211           return false;
   214         }
   212         }
   215         for(unsigned int i = 0; i < rInOutLabels1[n1].size(); ++i)
   213         for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
   216           labelTmp1[rInOutLabels1[n1][i].first]=0;
   214           _labelTmp1[_rInOutLabels1[n1][i].first]=0;
   217 
   215 
   218         if(MT!=SUBGRAPH)
   216         if(MT!=SUBGRAPH)
   219           for(unsigned int i = 0; i < rNewLabels1[n1].size(); ++i)
   217           for(unsigned int i = 0; i < _rNewLabels1[n1].size(); ++i)
   220             labelTmp2[rNewLabels1[n1][i].first]=0;
   218             _labelTmp2[_rNewLabels1[n1][i].first]=0;
   221       }
   219       }
   222 
   220 
   223       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
   221       for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
   224         const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
   222         const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
   225         labelTmp1[_intLabels2[currNode]]=0;
   223         _labelTmp1[_intLabels2[currNode]]=0;
   226         if(MT!=SUBGRAPH&&_conn[currNode]==0)
   224         if(MT!=SUBGRAPH&&_conn[currNode]==0)
   227           labelTmp2[_intLabels2[currNode]]=0;
   225           _labelTmp2[_intLabels2[currNode]]=0;
   228       }
   226       }
   229 
   227 
   230       return ret;
   228       return ret;
   231     }
   229     }
   232 
   230 
   308     }
   306     }
   309 
   307 
   310     void processBFSLevel(typename G1::Node source,unsigned int& orderIndex,
   308     void processBFSLevel(typename G1::Node source,unsigned int& orderIndex,
   311                          typename G1::template NodeMap<int>& dm1,
   309                          typename G1::template NodeMap<int>& dm1,
   312                          typename G1::template NodeMap<bool>& added) {
   310                          typename G1::template NodeMap<bool>& added) {
   313       order[orderIndex]=source;
   311       _order[orderIndex]=source;
   314       added[source]=1;
   312       added[source]=1;
   315 
   313 
   316       unsigned int endPosOfLevel=orderIndex,
   314       unsigned int endPosOfLevel=orderIndex,
   317         startPosOfLevel=orderIndex,
   315         startPosOfLevel=orderIndex,
   318         lastAdded=orderIndex;
   316         lastAdded=orderIndex;
   319 
   317 
   320       typename G1::template NodeMap<int> currConn(_g1,0);
   318       typename G1::template NodeMap<int> currConn(_g1,0);
   321 
   319 
   322       while(orderIndex<=lastAdded){
   320       while(orderIndex<=lastAdded){
   323         typename G1::Node currNode = order[orderIndex];
   321         typename G1::Node currNode = _order[orderIndex];
   324         for(typename G1::IncEdgeIt e(_g1,currNode); e!=INVALID; ++e) {
   322         for(typename G1::IncEdgeIt e(_g1,currNode); e!=INVALID; ++e) {
   325           typename G1::Node n = _g1.oppositeNode(currNode,e);
   323           typename G1::Node n = _g1.oppositeNode(currNode,e);
   326           if(!added[n]) {
   324           if(!added[n]) {
   327             order[++lastAdded]=n;
   325             _order[++lastAdded]=n;
   328             added[n]=1;
   326             added[n]=1;
   329           }
   327           }
   330         }
   328         }
   331         if(orderIndex>endPosOfLevel){
   329         if(orderIndex>endPosOfLevel){
   332           for(unsigned int j = startPosOfLevel; j <= endPosOfLevel; ++j) {
   330           for(unsigned int j = startPosOfLevel; j <= endPosOfLevel; ++j) {
   333             int minInd=j;
   331             int minInd=j;
   334             for(unsigned int i = j+1; i <= endPosOfLevel; ++i)
   332             for(unsigned int i = j+1; i <= endPosOfLevel; ++i)
   335               if(currConn[order[i]]>currConn[order[minInd]]||
   333               if(currConn[_order[i]]>currConn[_order[minInd]]||
   336                  (currConn[order[i]]==currConn[order[minInd]]&&
   334                  (currConn[_order[i]]==currConn[_order[minInd]]&&
   337                   (dm1[order[i]]>dm1[order[minInd]]||
   335                   (dm1[_order[i]]>dm1[_order[minInd]]||
   338                    (dm1[order[i]]==dm1[order[minInd]]&&
   336                    (dm1[_order[i]]==dm1[_order[minInd]]&&
   339                     labelTmp1[_intLabels1[order[minInd]]]>
   337                     _labelTmp1[_intLabels1[_order[minInd]]]>
   340                     labelTmp1[_intLabels1[order[i]]]))))
   338                     _labelTmp1[_intLabels1[_order[i]]]))))
   341                 minInd=i;
   339                 minInd=i;
   342 
   340 
   343             --labelTmp1[_intLabels1[order[minInd]]];
   341             --_labelTmp1[_intLabels1[_order[minInd]]];
   344             for(typename G1::IncEdgeIt e(_g1,order[minInd]); e!=INVALID; ++e)
   342             for(typename G1::IncEdgeIt e(_g1,_order[minInd]); e!=INVALID; ++e)
   345               ++currConn[_g1.oppositeNode(order[minInd],e)];
   343               ++currConn[_g1.oppositeNode(_order[minInd],e)];
   346             std::swap(order[j],order[minInd]);
   344             std::swap(_order[j],_order[minInd]);
   347           }
   345           }
   348           startPosOfLevel=endPosOfLevel+1;
   346           startPosOfLevel=endPosOfLevel+1;
   349           endPosOfLevel=lastAdded;
   347           endPosOfLevel=lastAdded;
   350         }
   348         }
   351         ++orderIndex;
   349         ++orderIndex;
   354 
   352 
   355 
   353 
   356     //we will find pairs for the nodes of g1 in this order
   354     //we will find pairs for the nodes of g1 in this order
   357     void setOrder(){
   355     void setOrder(){
   358       for(typename G2::NodeIt n2(_g2); n2!=INVALID; ++n2)
   356       for(typename G2::NodeIt n2(_g2); n2!=INVALID; ++n2)
   359         ++labelTmp1[_intLabels2[n2]];
   357         ++_labelTmp1[_intLabels2[n2]];
   360 
   358 
   361       typename G1::template NodeMap<int> dm1(_g1,0);
   359       typename G1::template NodeMap<int> dm1(_g1,0);
   362       for(typename G1::EdgeIt e(_g1); e!=INVALID; ++e) {
   360       for(typename G1::EdgeIt e(_g1); e!=INVALID; ++e) {
   363         ++dm1[_g1.u(e)];
   361         ++dm1[_g1.u(e)];
   364         ++dm1[_g1.v(e)];
   362         ++dm1[_g1.v(e)];
   370       for(typename G1::NodeIt n(_g1); n!=INVALID;) {
   368       for(typename G1::NodeIt n(_g1); n!=INVALID;) {
   371         if(!added[n]){
   369         if(!added[n]){
   372           typename G1::Node minNode = n;
   370           typename G1::Node minNode = n;
   373           for(typename G1::NodeIt n1(_g1,minNode); n1!=INVALID; ++n1)
   371           for(typename G1::NodeIt n1(_g1,minNode); n1!=INVALID; ++n1)
   374             if(!added[n1] &&
   372             if(!added[n1] &&
   375                (labelTmp1[_intLabels1[minNode]]>
   373                (_labelTmp1[_intLabels1[minNode]]>
   376                 labelTmp1[_intLabels1[n1]]||(dm1[minNode]<dm1[n1]&&
   374                 _labelTmp1[_intLabels1[n1]]||(dm1[minNode]<dm1[n1]&&
   377                                              labelTmp1[_intLabels1[minNode]]==
   375                                              _labelTmp1[_intLabels1[minNode]]==
   378                                              labelTmp1[_intLabels1[n1]])))
   376                                              _labelTmp1[_intLabels1[n1]])))
   379               minNode=n1;
   377               minNode=n1;
   380           processBFSLevel(minNode,orderIndex,dm1,added);
   378           processBFSLevel(minNode,orderIndex,dm1,added);
   381         }
   379         }
   382         else
   380         else
   383           ++n;
   381           ++n;
   384       }
   382       }
   385       for(unsigned int i = 0; i < labelTmp1.size(); ++i)
   383       for(unsigned int i = 0; i < _labelTmp1.size(); ++i)
   386         labelTmp1[i]=0;
   384         _labelTmp1[i]=0;
   387     }
   385     }
   388 
   386 
   389 
   387 
   390     template<MappingType MT>
   388     template<MappingType MT>
   391     bool extMatch(){
   389     bool extMatch(){
   392       while(_depth>=0) {
   390       while(_depth>=0) {
   393         if(_depth==static_cast<int>(order.size())) {
   391         if(_depth==static_cast<int>(_order.size())) {
   394           //all nodes of g1 are mapped to nodes of g2
   392           //all nodes of g1 are mapped to nodes of g2
   395           --_depth;
   393           --_depth;
   396           return true;
   394           return true;
   397         }
   395         }
   398         typename G1::Node& nodeOfDepth = order[_depth];
   396         typename G1::Node& nodeOfDepth = _order[_depth];
   399         const typename G2::Node& pairOfNodeOfDepth = _mapping[nodeOfDepth];
   397         const typename G2::Node& pairOfNodeOfDepth = _mapping[nodeOfDepth];
   400         typename G2::IncEdgeIt &edgeItOfDepth = currEdgeIts[_depth];
   398         typename G2::IncEdgeIt &edgeItOfDepth = _currEdgeIts[_depth];
   401         //the node of g2 whose neighbours are the candidates for
   399         //the node of g2 whose neighbours are the candidates for
   402         //the pair of order[_depth]
   400         //the pair of _order[_depth]
   403         typename G2::Node currPNode;
   401         typename G2::Node currPNode;
   404         if(edgeItOfDepth==INVALID){
   402         if(edgeItOfDepth==INVALID){
   405           typename G1::IncEdgeIt fstMatchedE(_g1,nodeOfDepth);
   403           typename G1::IncEdgeIt fstMatchedE(_g1,nodeOfDepth);
   406           //if _mapping[order[_depth]]!=INVALID, we don't need fstMatchedE
   404           //if _mapping[_order[_depth]]!=INVALID, we don't need fstMatchedE
   407           if(pairOfNodeOfDepth==INVALID) {
   405           if(pairOfNodeOfDepth==INVALID) {
   408             for(; fstMatchedE!=INVALID &&
   406             for(; fstMatchedE!=INVALID &&
   409                   _mapping[_g1.oppositeNode(nodeOfDepth,
   407                   _mapping[_g1.oppositeNode(nodeOfDepth,
   410                                             fstMatchedE)]==INVALID;
   408                                             fstMatchedE)]==INVALID;
   411                 ++fstMatchedE); //find fstMatchedE, it could be preprocessed
   409                 ++fstMatchedE); //find fstMatchedE, it could be preprocessed
   466     }
   464     }
   467 
   465 
   468     //calculate the lookup table for cutting the search tree
   466     //calculate the lookup table for cutting the search tree
   469     void setRNew1tRInOut1t(){
   467     void setRNew1tRInOut1t(){
   470       typename G1::template NodeMap<int> tmp(_g1,0);
   468       typename G1::template NodeMap<int> tmp(_g1,0);
   471       for(unsigned int i=0; i<order.size(); ++i) {
   469       for(unsigned int i=0; i<_order.size(); ++i) {
   472         tmp[order[i]]=-1;
   470         tmp[_order[i]]=-1;
   473         for(typename G1::IncEdgeIt e1(_g1,order[i]); e1!=INVALID; ++e1) {
   471         for(typename G1::IncEdgeIt e1(_g1,_order[i]); e1!=INVALID; ++e1) {
   474           const typename G1::Node currNode=_g1.oppositeNode(order[i],e1);
   472           const typename G1::Node currNode=_g1.oppositeNode(_order[i],e1);
   475           if(tmp[currNode]>0)
   473           if(tmp[currNode]>0)
   476             ++labelTmp1[_intLabels1[currNode]];
   474             ++_labelTmp1[_intLabels1[currNode]];
   477           else if(tmp[currNode]==0)
   475           else if(tmp[currNode]==0)
   478             ++labelTmp2[_intLabels1[currNode]];
   476             ++_labelTmp2[_intLabels1[currNode]];
   479         }
   477         }
   480         //labelTmp1[i]=number of neightbours with label i in set rInOut
   478         //_labelTmp1[i]=number of neightbours with label i in set rInOut
   481         //labelTmp2[i]=number of neightbours with label i in set rNew
   479         //_labelTmp2[i]=number of neightbours with label i in set rNew
   482         for(typename G1::IncEdgeIt e1(_g1,order[i]); e1!=INVALID; ++e1) {
   480         for(typename G1::IncEdgeIt e1(_g1,_order[i]); e1!=INVALID; ++e1) {
   483           const int& currIntLabel = _intLabels1[_g1.oppositeNode(order[i],e1)];
   481           const int& currIntLabel = _intLabels1[_g1.oppositeNode(_order[i],e1)];
   484           if(labelTmp1[currIntLabel]>0) {
   482           if(_labelTmp1[currIntLabel]>0) {
   485             rInOutLabels1[order[i]]
   483             _rInOutLabels1[_order[i]]
   486               .push_back(std::make_pair(currIntLabel,
   484               .push_back(std::make_pair(currIntLabel,
   487                                         labelTmp1[currIntLabel]));
   485                                         _labelTmp1[currIntLabel]));
   488             labelTmp1[currIntLabel]=0;
   486             _labelTmp1[currIntLabel]=0;
   489           }
   487           }
   490           else if(labelTmp2[currIntLabel]>0) {
   488           else if(_labelTmp2[currIntLabel]>0) {
   491             rNewLabels1[order[i]].
   489             _rNewLabels1[_order[i]].
   492               push_back(std::make_pair(currIntLabel,labelTmp2[currIntLabel]));
   490               push_back(std::make_pair(currIntLabel,_labelTmp2[currIntLabel]));
   493             labelTmp2[currIntLabel]=0;
   491             _labelTmp2[currIntLabel]=0;
   494           }
   492           }
   495         }
   493         }
   496 
   494 
   497         for(typename G1::IncEdgeIt e1(_g1,order[i]); e1!=INVALID; ++e1) {
   495         for(typename G1::IncEdgeIt e1(_g1,_order[i]); e1!=INVALID; ++e1) {
   498           int& tmpCurrNode=tmp[_g1.oppositeNode(order[i],e1)];
   496           int& tmpCurrNode=tmp[_g1.oppositeNode(_order[i],e1)];
   499           if(tmpCurrNode!=-1)
   497           if(tmpCurrNode!=-1)
   500             ++tmpCurrNode;
   498             ++tmpCurrNode;
   501         }
   499         }
   502       }
   500       }
   503     }
   501     }
   530     ///different labels.
   528     ///different labels.
   531     ///\param intLabel1 The NodeMap storing the integer node labels of G2.
   529     ///\param intLabel1 The NodeMap storing the integer node labels of G2.
   532     ///The labels must be the numbers {0,1,2,..,K-1}, where K is the number of
   530     ///The labels must be the numbers {0,1,2,..,K-1}, where K is the number of
   533     ///different labels.
   531     ///different labels.
   534     Vf2pp(const G1 &g1, const G2 &g2,M &m, M1 &intLabels1, M2 &intLabels2) :
   532     Vf2pp(const G1 &g1, const G2 &g2,M &m, M1 &intLabels1, M2 &intLabels2) :
   535       _depth(0), _conn(g2,0), _mapping(m), order(countNodes(g1),INVALID),
   533       _g1(g1), _g2(g2), _depth(0), _mapping(m), _order(countNodes(g1),INVALID),
   536       currEdgeIts(countNodes(g1),INVALID), _g1(g1), _g2(g2), rNewLabels1(_g1),
   534       _conn(g2,0), _currEdgeIts(countNodes(g1),INVALID), _rNewLabels1(_g1),
   537       rInOutLabels1(_g1), _intLabels1(intLabels1) ,_intLabels2(intLabels2),
   535       _rInOutLabels1(_g1), _intLabels1(intLabels1) ,_intLabels2(intLabels2),
   538       maxLabel(getMaxLabel()), labelTmp1(maxLabel+1),labelTmp2(maxLabel+1),
   536       _maxLabel(getMaxLabel()), _labelTmp1(_maxLabel+1),_labelTmp2(_maxLabel+1),
   539       _mapping_type(SUBGRAPH), _deallocMappingAfterUse(0),
   537       _mapping_type(SUBGRAPH), _deallocMappingAfterUse(0),
   540       _deallocLabelsAfterUse(0)
   538       _deallocLabelsAfterUse(0)
   541     {
   539     {
   542       setOrder();
   540       setOrder();
   543       setRNew1tRInOut1t();
   541       setRNew1tRInOut1t();