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

📄 graph_can_code.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. */#ifndef _GRAPH_CAN_CODE_H#define _GRAPH_CAN_CODE_Husing namespace std;#include <string>#include <sstream>#include <vector>#include <ext/hash_map>#include "generic_classes.h"time_tracker tt_iostream;template<typename V_T, typename E_T>struct five_tuple;template<typename V_T, typename E_T>ostream& operator<< (ostream&, const five_tuple<V_T, E_T>&);// NOTE: should the labels (_li, _lij, _lj) in thus struct be stored as // references (to avoid copying them) ?? Will that work ??/** * \brief Storing a five_tuple that represent a labeled edge of a graph. * * <dfs_id1, dfs_id2, vertex_label1, edge_label, vertex_label2> are the 5-tuple. * It is used as part of the canonical code of a graph. */template<typename V_T, typename E_T>struct five_tuple{  five_tuple() {}  five_tuple(const int& id1, const int& id2, const V_T& li, const E_T& lij, const V_T& lj): _i(id1), _j(id2), _li(li), _lj(lj), _lij(lij) {}  bool operator< (const five_tuple<V_T, E_T>& rhs) const {    // follows ordering given on pg 10 of gSpan TR    bool is_fwd=(_i<_j);    bool rhs_is_fwd=(rhs._i<rhs._j);    if(!is_fwd && rhs_is_fwd)      return true;    if(!is_fwd && !rhs_is_fwd && _j<rhs._j)      return true;    if(!is_fwd && !rhs_is_fwd && _j==rhs._j && _lij<rhs._lij)      return true;    if(is_fwd && rhs_is_fwd && _i>rhs._i)      return true;    if(is_fwd && rhs_is_fwd && _i==rhs._i && _li<rhs._li)      return true;    if(is_fwd && rhs_is_fwd && _i==rhs._i && _li==rhs._li && _lij<rhs._lij)      return true;    if(is_fwd && rhs_is_fwd && _i==rhs._i && _li==rhs._li && _lij==rhs._lij && _lj<rhs._lj)      return true;    return false;  }//end operator<  friend ostream& operator<< <>(ostream&, const five_tuple<V_T, E_T>&);  int _i;  int _j;  V_T _li;  V_T _lj;  E_T _lij;};//end struct five_tupletemplate<typename V_T, typename E_T>ostream& operator<< (ostream& ostr, const five_tuple<V_T, E_T>& tuple) {  ostr<<tuple._i<<" "<<tuple._j<<" "<<tuple._li<<" "<<tuple._lij<<" "<<tuple._lj;  return ostr;}template<typename PP, typename V_T, typename E_T, template <typename> class ALLOC >class canonical_code<GRAPH_PROP, V_T, E_T, ALLOC >;template<typename PP, typename V_T, typename E_T, template <typename> class ALLOC >ostream& operator<< (ostream&, const canonical_code<GRAPH_PROP, V_T, E_T, ALLOC >&);/** * \brief Graph canonical Code class by partial specialization of * generic canonical_code class. * * pattern_prop is set to undirected (graph property) */template<typename PP, typename V_T, typename E_T, template <typename> class ALLOC=std::allocator >class canonical_code<GRAPH_PROP, V_T, E_T, ALLOC >{ public:  typedef int STORAGE_TYPE;  typedef five_tuple<V_T, E_T> FIVE_TUPLE;  typedef FIVE_TUPLE INIT_TYPE;  typedef eqint COMPARISON_FUNC;  typedef vector<FIVE_TUPLE, ALLOC<FIVE_TUPLE> > TUPLES;  typedef typename TUPLES::const_iterator CONST_IT;  typedef typename TUPLES::iterator IT;  typedef canonical_code<GRAPH_PROP, V_T, E_T, ALLOC > CAN_CODE;  typedef HASHNS::hash_map<int, int, HASHNS::hash<int>, std::equal_to<int>, ALLOC<int> > VID_HMAP;  typedef typename VID_HMAP::const_iterator VM_CONST_IT;  typedef vector<int, ALLOC<int> > RMP_T;  canonical_code() : _can_code(id_generator++) {} // defunct default constructor  /** Parameterized constructor that inserts ft as first tuple into      DFS code */  canonical_code(const FIVE_TUPLE& ft, const int&gi, const int& gj) {    append(ft, gi, gj);  }  IT begin() { return _dfs_code.begin();}  CONST_IT begin() const { return _dfs_code.begin();}  IT end() { return _dfs_code.end();}  CONST_IT end() const { return _dfs_code.end();}  int size() const { return _dfs_code.size();}  void clear() {    _dfs_code.clear();    _cid_to_gid.clear();    _gid_to_cid.clear();    _rmp.clear();  }  const FIVE_TUPLE& operator[](const int& index) const { return _dfs_code[index];}  void init_rmp() {    if(!_rmp.empty())      _rmp.clear();    _rmp.push_back(0);    _rmp.push_back(1);  }  void update_rmp(const FIVE_TUPLE& tuple) {    if(_rmp.empty()) {      _rmp.push_back(tuple._i);      _rmp.push_back(tuple._j);      return;    }    // no changes to rmp if it's a back-edge    if(tuple._i>tuple._j)      return;    typename RMP_T::iterator rmp_it=_rmp.end()-1;    while(rmp_it>=_rmp.begin()) {      if(*rmp_it==tuple._i)        break;      rmp_it=_rmp.erase(rmp_it);      rmp_it--;    }    _rmp.push_back(tuple._j);  }//end update_rmp()  template<class PAT>  void init(const INIT_TYPE& tuple, PAT* pattern) {     tt_iostream.start();    clear();    _dfs_code.push_back(tuple);    ostringstream t_ss;    t_ss << tuple;    string t_str = t_ss.str();    char* p = new char[t_str.length()+1];    t_str.copy(p, string::npos);    p[t_str.length()] = 0;    HASHNS::hash_map<const char*, int, HASHNS::hash<const char*>, eqstr>::iterator itr = level_one_hash.find(p);     if(itr != level_one_hash.end()) {      _can_code = itr->second;       delete p;    } else {      level_one_hash.insert(make_pair(p, _can_code));    }    tt_iostream.stop();          pattern->update_rmpath(0);    pattern->update_rmpath(1);  }  void push_back(const FIVE_TUPLE& tuple) {    _dfs_code.push_back(tuple);    tt_iostream.start();    tt_iostream.stop();  }  void append(const FIVE_TUPLE& tuple) {     push_back(tuple);  }  void append(const FIVE_TUPLE& tuple, const int& gi, const int& gj) {     push_back(tuple);    _cid_to_gid.insert(make_pair(tuple._i, gi));    _cid_to_gid.insert(make_pair(tuple._j, gj));    _gid_to_cid.insert(make_pair(gi, tuple._i));    _gid_to_cid.insert(make_pair(gj, tuple._j));  }  void update_code() {    _can_code = id_generator++;  }  STORAGE_TYPE getCode() const {    return _can_code;  }  bool operator< (const CAN_CODE& rhs) const {    int i=0, j=0;    while(i<_dfs_code.size() && j<rhs._dfs_code.size()) {      if(rhs._dfs_code[j]<_dfs_code[i])        return false;      i++;      j++;    }          // both codes are equal till common length    return _dfs_code.size()>=rhs._dfs_code.size();  }  int cid(const int& gi) const {    VM_CONST_IT it=_gid_to_cid.find(gi);    if(it==_gid_to_cid.end()) {      return -1;    }    return it->second;  }  int gid(const int& ci) const {    VM_CONST_IT it=_cid_to_gid.find(ci);    if(it==_cid_to_gid.end()) {      return -1;    }    return it->second;  }  RMP_T& rmost_path() { return _rmp;}  void append_rmp(const int& id) {    _rmp.push_back(id);  }  friend ostream& operator<< <>(ostream&, const canonical_code<GRAPH_PROP, V_T, E_T, ALLOC>&); private:  STORAGE_TYPE _can_code;  TUPLES _dfs_code;    VID_HMAP _cid_to_gid;  VID_HMAP _gid_to_cid;  RMP_T _rmp;  static int id_generator;  static HASHNS::hash_map<const char*, int, HASHNS::hash<const char*>, eqstr> level_one_hash;};//end class canonical_code for graphtemplate<typename PP, typename V_T, typename E_T, template <typename> class ALLOC>ostream& operator<< (ostream& ostr, const canonical_code<GRAPH_PROP, V_T, E_T, ALLOC>& cc) {  typename canonical_code<GRAPH_PROP, V_T, E_T, ALLOC>::TUPLES::const_iterator it;  for(it=cc._dfs_code.begin(); it!=cc._dfs_code.end(); it++)    ostr<<*it<<endl;  return ostr;}template<class PP, typename v, typename e, template <typename> class ALLOC >int canonical_code<GRAPH_PROP, v, e, ALLOC>::id_generator = 1;template<class PP, typename v, typename e, template <typename> class ALLOC >HASHNS::hash_map<const char*, int, HASHNS::hash<const char*>, eqstr> canonical_code<GRAPH_PROP, v, e, ALLOC>::level_one_hash;#endif

⌨️ 快捷键说明

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