⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree_iso_check.h

📁 这是一个用于数据挖掘的常用算法的模板库(数据挖掘的C++模板库for UNIX)
💻 H
字号:
/* *  Copyright (C) 2005 M.J. Zaki <zaki@cs.rpi.edu> Rensselaer Polytechnic Institute *  Written by parimi@cs.rpi.edu *  Updated by chaojv@cs.rpi.edu, alhasan@cs.rpi.edu, salems@cs.rpi.edu * *  This program is free software; you can redistribute it and/or *  modify it under the terms of the GNU General Public License *  as published by the Free Software Foundation; either version 2 *  of the License, or (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License along *  with this program; if not, write to the Free Software Foundation, Inc., *  59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */// isomorphism cheking for trees#ifndef _TREE_ISO_CHECK_H_#define _TREE_ISO_CHECK_H_#include <stack>#include <utility>#include "typedefs.h"template<class PP, class MP, class ST, template<class, typename, typename, template <typename> class > class CC,         template<typename> class ALLOC>class pattern;class directed;class acyclic;class indegree_lte_one;class ordered;template<class prop, class next_property>class proplist;using namespace std;/** Updates the right most path of candidate for last vertex added */template<class PP, class MP, class ST, template<typename, typename, typename, template <typename> class > class CC,         template <typename> class ALLOC >void update_rmost_path(pattern<TREE_PROP, MP, ST, CC, ALLOC>*const& cand_pat) {  typedef pattern<TREE_PROP, MP, ST, CC, ALLOC> PATTERN;  int new_vid=cand_pat->rmost_vid(); // vertex added to generate this candidate  typename PATTERN::RMP_T& rmost_path=cand_pat->_rmost_path;  int pvid=(cand_pat->in_edges(new_vid)).first->first; // parent of new_vid    // pop off vids tills you hit pvid, or root of tree  typename PATTERN::RMP_T::iterator it=rmost_path.end()-1;  if(rmost_path.end()!=rmost_path.begin())    while(it!=rmost_path.begin()) {      if(*it==pvid)        break;      it=rmost_path.erase(it);      it--;              // update canonical code      cand_pat->_canonical_code.backtrack();    }    rmost_path.push_back(new_vid);    // update canonical code    cand_pat->_canonical_code.insert_vertex(cand_pat->label(new_vid));}//end update_rmost_path()/** Returns true if first iterator is within one unit of second one*/template<typename IT>int eit_diff_one(IT it1, IT it2) {  if(it1==it2)    return true;  it1++;  if(it1==it2)    return true;    return false;}/** Returns an IT that is two units before second one */template<typename IT>IT last_eits(IT it1, IT it2) {  IT prev=it1;  it1++;  it1++;    while(it1++!=it2)    prev++;    return prev;}/** Returns if given candidate is isomorphic;     correspondingly sets the bool flag in cand_pat as well */template<class PP, class MP, class ST, template<typename, typename, typename, template <typename> class > class CC,         template <typename> class ALLOC>bool check_isomorphism(pattern<TREE_PROP, MP, ST, CC, ALLOC>*const& cand_pat) {    typedef pattern<TREE_PROP, MP, ST, CC, ALLOC> PATTERN;    typename PATTERN::RMP_T::const_iterator it;  typename PATTERN::CONST_EIT_PAIR eit_pair;    update_rmost_path(cand_pat);  it=cand_pat->_rmost_path.end();  if(cand_pat->_rmost_path.size())    it--;    while(it>=cand_pat->_rmost_path.begin()) {    // get last 2 edges of *it    eit_pair=cand_pat->out_edges(*it);    bool max_one_child=false;            if(eit_pair.first!=eit_pair.second)      eit_pair.second--;    else      max_one_child=true;        if(eit_pair.first==eit_pair.second)      max_one_child=true;    else      eit_pair.second--;        if(!max_one_child && !check_subtree_order(eit_pair.second, cand_pat)) {      // last 2 subtrees of this vid were not ordered canonically      cand_pat->_is_canonical=false;      return false;    }    it--;  }    // execution reaches this point only if isomorphism check was passed  cand_pat->_is_canonical=true;  return true;  }//end check_isomorphsim()/** Receives an iterator to first of two subtrees to be checked, and the graph;    Returns true if first-subtree <= second-subtree */template<typename EIT, typename PATTERN>bool check_subtree_order(EIT& edge_it, const PATTERN*const& cand_pat) {  /* This function in effect imposes the <= ordering defined on pg 1007 of      SLEUTH */    // x and y are names for the two respective nodes being compared  int vid_x=edge_it->first;  edge_it++;  int vid_y=edge_it->first;  typename PATTERN::CONST_EIT_PAIR edges;  typedef pair<int, int> st_pair;  stack<st_pair> stack_x;  stack<st_pair> stack_y;  stack_x.push(make_pair(vid_x, 0));  stack_y.push(make_pair(vid_y, 0));  while(!stack_x.empty() && !stack_y.empty()) {        const st_pair& node_x=stack_x.top();    stack_x.pop();    const st_pair& node_y=stack_y.top();    stack_y.pop();        /// check if two nodes are at same dfs level ///    if(node_x.second<node_y.second) {      // y is deeper      return false;    }        if(node_x.second>node_y.second) {      // x is deeper      return true;    }        /// now check labels ///     if(cand_pat->label(node_x.first) < cand_pat->label(node_y.first)) {      return true;    }    if(cand_pat->label(node_x.first) > cand_pat->label(node_y.first)) {      return false;    }          // push edges of x in reverse order    edges=cand_pat->out_edges(node_x.first);    if(edges.second!=edges.first) {      edges.second--;      while(edges.second!=edges.first) {        stack_x.push(make_pair(edges.second->first, node_x.second+1));        edges.second--;      }      stack_x.push(make_pair(edges.second->first, node_x.second+1));    }        // push edges of y in reverse order    edges=cand_pat->out_edges(node_y.first);    if(edges.second!=edges.first) {      edges.second--;      while(edges.second!=edges.first) {        stack_y.push(make_pair(edges.second->first, node_y.second+1));        edges.second--;      }      stack_y.push(make_pair(edges.second->first, node_y.second+1));    }      }//end while stacks not empty  if(!stack_x.empty()) {    // x is deeper    return true;  }  if(!stack_y.empty()) {    // y is deeper          return false;  }    // both stacks were empty i.e. equal subtrees  return true;  }//end check_subtree_order()/**  specialized isomorphism for ordered trees */template<class PP, class MP, class ST, template<typename, typename, typename, template <typename> class > class CC,         template <typename> class ALLOC >bool check_isomorphism(pattern<ORD_TREE_PROP, MP, ST, CC, ALLOC>*const& cand_pat) {  update_rmost_path(cand_pat);  cand_pat->_is_canonical=true;  return true;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -