Advertisement
Guest User

Untitled

a guest
Apr 24th, 2015
511
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.58 KB | None | 0 0
  1. #include <boost/graph/adjacency_list.hpp>
  2. #include <boost/graph/vf2_sub_graph_iso.hpp>
  3. #include <boost/algorithm/string/split.hpp>
  4. #include <boost/algorithm/string/classification.hpp>
  5.  
  6. #include <fstream>
  7. #include <iostream>
  8. #include <string>
  9. #include <vector>
  10. #include <algorithm>
  11. #include <ctime>
  12. #include <unordered_set>
  13.  
  14. //for mmap:
  15. #include <sys/mman.h>
  16. #include <sys/stat.h>
  17. #include <fcntl.h>
  18.  
  19. using namespace std;
  20. using namespace boost;
  21.  
  22.  
  23. //==========STRUCTURES==========
  24. // vertex
  25. struct VertexProperties {
  26.     int id;
  27.     int label;
  28.     VertexProperties(unsigned i = 0, unsigned l = 0) : id(i), label(l) {}
  29. };
  30.  
  31. // edge
  32. struct EdgeProperties {
  33.     unsigned id;
  34.     unsigned label;
  35.     EdgeProperties(unsigned i = 0, unsigned l = 0) : id(i), label(l) {}
  36. };
  37.  
  38. // Graph
  39. struct GraphProperties {
  40.     unsigned id;
  41.     unsigned label;
  42.     GraphProperties(unsigned i = 0, unsigned l = 0) : id(i), label(l) {}
  43. };
  44.  
  45. // adjency list
  46. typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, VertexProperties, EdgeProperties,
  47. GraphProperties> Graph;
  48.  
  49. // descriptors
  50.  
  51. typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
  52. typedef std::pair<boost::graph_traits<Graph>::edge_descriptor, bool> edge_t;
  53. // iterators
  54. typedef graph_traits<Graph>::vertex_iterator vertex_iter;
  55. typedef graph_traits<Graph>::edge_iterator edge_iter;
  56. typedef std::pair<edge_iter, edge_iter> edge_pair;
  57.  
  58.  
  59.  
  60. float seuil;
  61. vector<Graph> dataG;
  62.  
  63. //oprators over edges-------------------------------------------------------------------------------unorderdset
  64. string hashedg(edge_iter e,Graph g ){
  65.     vertex_t from = source(*e, g);
  66.     vertex_t to = target(*e, g);
  67.     edge_t edg = edge(from, to, g);
  68.     string key=std::to_string(g[from].id)+std::to_string(g[from].label)+std::to_string(g[edg.first].label)+std::to_string(g[to].id)+std::to_string(g[to].label); //the id from+ it's label + edge label+ the to id + it's label
  69.  
  70.     return key; // tableLength;
  71. }
  72.  
  73. struct hashedge{
  74.     size_t operator ()(const edge_iter e,Graph g )const{
  75.         std::hash<string> fnx;
  76.         return fnx(hashedg(e,g));
  77.     }
  78. };
  79. std::unordered_set<edge_iter,hashedge> edgehash;
  80.  
  81.  
  82.  
  83. //=================callback used fro subgraph_iso=================================================================
  84. struct my_callback {
  85.     template <typename CorrespondenceMap1To2, typename CorrespondenceMap2To1>
  86.     bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1 g) const {
  87.         return false;
  88.     }
  89. };
  90.  
  91. //==========handle_error==========
  92. void handle_error(const char *msg) {
  93.     perror(msg);
  94.     exit(255);
  95. }
  96.  
  97.  
  98. //============READ ALL THE FILE AND RETURN A STRING===================
  99. const char *readfromfile(const char *fname, size_t &length) {
  100.     int fd = open(fname, O_RDONLY);
  101.     if (fd == -1)
  102.         handle_error("open");
  103.  
  104.     // obtain file size
  105.     struct stat sb;
  106.     if (fstat(fd, &sb) == -1)
  107.         handle_error("fstat");
  108.  
  109.     length = sb.st_size;
  110.  
  111.     const char *addr = static_cast<const char *>(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0u));
  112.     if (addr == MAP_FAILED)
  113.         handle_error("mmap");
  114.  
  115.     // TODO close fd at some point in time, call munmap(...)
  116.     return addr;
  117. }
  118. //==========SPLIT THE STRING BY NEWLINE (\n) ==========
  119. vector<string> splitstringtolines(string const& str) {
  120.  
  121.     std::vector<string> split_vector;
  122.     split(split_vector, str, is_any_of("\n"));
  123.  
  124.     return split_vector;
  125. }
  126.  
  127. //============Get a string starting from pos============
  128. string getpos(int const& pos, string const& yy) {
  129.     size_t i = pos;
  130.     string str;
  131.     for (; ((yy[i] != ' ') && (i < yy.length())); i++) {str += yy[i];}
  132.     return str;
  133. }
  134. //==================read string vector and return graphs vector===================
  135. std::vector<Graph> creategraphs(std::vector<string> const& fichlines) {
  136.  
  137.     int compide = 0; // compteur de id edge
  138.     for (string yy : fichlines) {
  139.         switch (yy[0]) {
  140.             case 't': {
  141.                 string str2 = getpos(4, yy);
  142.                 unsigned gid = atoi(str2.c_str());
  143.                 dataG.emplace_back(GraphProperties(gid, gid));
  144.                 compide = 0;
  145.             } break;
  146.             case 'v': {
  147.                 assert(!dataG.empty()); // assert will terminate the program  if its argument turns out to be false
  148.                 // cout<<yy<<endl;
  149.                 int vId, vLabel;
  150.                 string vvv = getpos(2, yy);
  151.                 vId = atoi(vvv.c_str());
  152.                 string vvvv = getpos((int)vvv.length() + 3, yy);
  153.                 // cout<<vvvv<<endl;
  154.                 vLabel = atoi(vvvv.c_str());
  155.                 boost::add_vertex(VertexProperties(vId, vLabel), dataG.back());
  156.             }
  157.  
  158.                 break;
  159.  
  160.             case 'e': { // cout<<yy<<endl;
  161.                 assert(!dataG.empty()); // assert will terminate the program  if its argument turns out to be false
  162.  
  163.                 int fromId, toId, eLabel;
  164.                 string eee = getpos(2, yy);
  165.                 // cout<<eee<<endl;
  166.                 fromId = atoi(eee.c_str());
  167.                 string eee2 = getpos((int)eee.length() + 3, yy);
  168.                 // cout<<eee2<<endl;
  169.                 toId = atoi(eee2.c_str());
  170.                 int c = (int)eee.length() + (int)eee2.length() + 4;
  171.                 //    cout<<c<<endl;
  172.                 string eee3 = getpos(c, yy);
  173.                 //  cout<<eee3<<endl;
  174.                 eLabel = atoi(eee3.c_str());
  175.                 boost::add_edge(fromId, toId, EdgeProperties(compide, eLabel), dataG.back());
  176.                 compide++;
  177.             } break;
  178.         }
  179.     }
  180.  
  181.     return dataG;
  182. }
  183. //============test if the graph is empty========================================================
  184. bool emptygraph(Graph const& g) {
  185.     return ((num_edges(g)==0)&&(num_vertices(g)==0));//using only the number of edges match
  186. }
  187. //============test if the graph connectivity========================================================
  188. bool graphconnexe(Graph const& g) {
  189.     return (num_edges(g) >= (num_vertices(g)-1));
  190. }
  191. //====================print the graph information========================================================
  192. void printgraph(Graph const& gr) {
  193.     typedef std::pair<edge_iter, edge_iter> edge_pair;
  194.     std::cout <<"=================================="<<endl;
  195.     std::cout <<" contains " << num_vertices(gr) << " vertices, and " << num_edges(gr) << " edges " << std::endl;
  196.     if (graphconnexe(gr)) {
  197.  
  198.         // Vertex list
  199.         if (num_vertices(gr) != 0) {
  200.             std::cout << "  Vertex list: " << std::endl;
  201.             for (size_t i = 0; i < num_vertices(gr); ++i) // size_t vertice number in the graph
  202.             {
  203.                 std::cout << " ID: " << gr[i].id << ", Label: " << gr[i].label << std::endl;
  204.             }
  205.         }
  206.         // Edge list
  207.         if (num_edges(gr) != 0) {
  208.             std::cout << "  Edge list: " << std::endl;
  209.             edge_pair ep;
  210.             for (ep = edges(gr); ep.first != ep.second; ++ep.first) // ep edge number
  211.             {
  212.                 vertex_t from = source(*ep.first, gr);
  213.                 vertex_t to = target(*ep.first, gr);
  214.                 edge_t edg = edge(from, to, gr);
  215.                 std::cout << "   e(" << gr[from].id << "," << gr[to].id << ")   ID: " << gr[edg.first].id
  216.                 << " ,  Label: " << gr[edg.first].label << std::endl;
  217.             }
  218.         }
  219.         std::cout<<endl;
  220.     } else {
  221.         cout << "Please check this graph connectivity." << endl;
  222.     }
  223. }
  224.  
  225. //=================test if the given vertice exist in the graph========================= i have modified this
  226. bool verticeexist(Graph const& g, int const& vId, int const& vlabel) {
  227.  
  228.  
  229.     for (size_t i = 0; i < num_vertices(g); ++i) // size_t vertice number in the graph
  230.     {
  231.         if ((g[i].id == vId) && (g[i].label == vlabel))  return true;
  232.     }
  233.  
  234.     return false;
  235. }
  236. //========test if this id of the vertice exist in the graph====================================================
  237. bool idverticeexist(Graph const& g, int const& vId) {
  238.     if (num_edges(g) != 0) {
  239.         for (size_t i = 0; i < num_vertices(g); ++i) // size_t vertice number in the graph
  240.         {
  241.             if (g[i].id == vId) {
  242.                 return true;
  243.             }
  244.         }
  245.     }
  246.     return false;
  247. }
  248. //=======get vertice label label============================
  249.  
  250. int getvlabel(Graph const& M,int const& id){
  251.     int cpt;
  252.     for (size_t i = 0; i < num_vertices(M); ++i){
  253.         if (M[i].id == id) {
  254.             cpt=M[i].label;
  255.             return cpt;
  256.             //there is a problem if we can't find the id (to get the label) what should we return
  257.             //we call this function only when we are sure that the id exist by using idverticeexist() function
  258.  
  259.         }
  260.     }
  261.     return (num_vertices(M)+1);
  262. }
  263. //=============test if the given edge exist in the graph===========================i have modified this
  264. bool edgeexist(Graph const& g, int const& fromid, int const& toid, unsigned const& elabel) {
  265.  
  266.  
  267.     if (num_edges(g) != 0) {
  268.         edge_pair ep;
  269.         for (ep = edges(g); ep.first != ep.second; ++ep.first) // ep edge number
  270.         {
  271.             vertex_t from = source(*ep.first, g);
  272.             vertex_t to = target(*ep.first, g);
  273.             edge_t edg = edge(from, to, g);
  274.  
  275.             if ((g[from].id == fromid) && (g[to].id == toid) && (g[edg.first].label == elabel)) {
  276.                 return true;
  277.             }
  278.  
  279.         }
  280.     }
  281.  
  282.     return false;
  283. }
  284.  
  285. /*===============test if edges are equal============================= ??????
  286.  bool edgesareequal(Graph const& g1,edge_iter const& e1,Graph const& g2,edge_iter const& e2){
  287.  
  288.  vertex_t frome1 = source(*e1, g1);
  289.  vertex_t toe1 = target(*e1, g1);
  290.  edge_t edg1 = edge(frome1, toe1, g1);
  291.  int label1 =g1[edg1.first].label;
  292.  
  293.  vertex_t frome2 = source(*e2, g2);
  294.  vertex_t toe2 = target(*e2, g2);
  295.  edge_t edg2 = edge(frome2, toe2, g2);
  296.  int label2 =g2[edg2.first].label;
  297.  
  298.  
  299.  return((frome1==frome2)&&(toe1==toe2)&&(label1==label2));
  300.  }
  301.  */
  302.  
  303. //======================================================
  304. float countfrequency(Graph const& g1,std::vector<Graph> dataG){
  305.     int iso=0;
  306.     if(emptygraph(g1)){return 1;}
  307.     else{
  308.         for (Graph g2: dataG){
  309.             if(vf2_subgraph_iso(g1,g2,my_callback())){iso++;}
  310.         }
  311.     }
  312.     return (iso/dataG.size());
  313. }
  314. //======================================================!!!!!!!!
  315. bool frequent(Graph const& g1,std::vector<Graph> dataG){
  316.     if(emptygraph(g1)){return true;}
  317.     else{
  318.         return countfrequency(g1, dataG)*dataG.size()>=seuil;
  319.     }
  320.  
  321. }
  322. //==========test if the edge is connexe with the graph=============
  323. bool graphconnexewithedge(Graph g, int const& fromid, int const& toid) {
  324.     return (idverticeexist(g,fromid)|| idverticeexist(g,toid));
  325. }
  326. //=========aumentation of a subgraph g from the original graph M=================================
  327. void augmentation(Graph &M, Graph &g, int const& fromid, int const& toid, unsigned const& edgeid, unsigned const& elabel) {
  328.  
  329.  
  330.     if(!idverticeexist(g,fromid)){
  331.         int vlabel=getvlabel(M,fromid);
  332.         boost::add_vertex(VertexProperties(fromid, vlabel), g);
  333.     }
  334.  
  335.     if(!idverticeexist(g,toid)){
  336.         int vlabel=getvlabel(M,toid);
  337.         boost::add_vertex(VertexProperties(toid, vlabel), g);
  338.     }
  339.  
  340.     boost::add_edge(fromid, toid, EdgeProperties(edgeid, elabel), g);
  341.  
  342. }
  343.  
  344. //=========================================================== this is very complex, it must be modifed
  345. //edgesdiff result is a vector or un order set
  346. //i have modifed this
  347. std::vector<std::array<int, 3>>  edgesdiff(Graph const& g1,Graph const& g2){
  348.  
  349.  
  350.     std::array<int, 3> t;
  351.     std::vector<std::array<int, 3>> res;
  352.  
  353.     edge_pair ep;
  354.     for (ep = edges(g1); ep.first != ep.second; ++ep.first) // ep edge number
  355.     {
  356.         vertex_t from = source(*ep.first, g1);
  357.         t[0]=g1[from].id;
  358.         vertex_t to = target(*ep.first, g1);
  359.         t[1]=g1[to].id;
  360.         edge_t edg = edge(from, to, g1);
  361.         t[2]=g1[edg.first].label;
  362.  
  363.         if(!edgeexist(g2,t[0],t[1],t[2])){res.push_back(t);}
  364.  
  365.  
  366.     }
  367.  
  368.     return res;
  369. }
  370.  
  371. //====================================== for this we use a set of graphs
  372. std::unordered_set<Graph> genererLesInduictifs(Graph G, std::unordered_set<Graph> vec){
  373.     std::unordered_set<Graph> in;
  374.     Graph w;
  375.     std::vector<std::array<int, 3>> ef;
  376.  
  377.     for(auto v:vec){
  378.         ef=edgesdiff(G,v);
  379.         for(auto e:ef){
  380.             if(graphconnexewithedge(v,e[0],e[1])){
  381.                 //we must create w a new copy of v with a new @
  382.                 w=v;
  383.                 augmentation(G,w,e[0],e[1],num_edges(v)+1,e[2]);}
  384.             if(frequent(w,dataG)){in.insert(w);}
  385.         }
  386.  
  387.     }
  388.  
  389.  
  390.     return in;
  391. }
  392. //=======list==========
  393. std::unordered_set<Graph> list(Graph G){
  394.     std::unordered_set<Graph> gen0,in,gen,freqs;
  395.     Graph vide;
  396.     std::unordered_set<std::array<int, 3>> ef;
  397.  
  398.     ef=edgesdiff(G,vide);
  399.     gen0.insert(vide);
  400.     in=genererLesInduictifs(G,gen0);
  401.     while(in.size()!=0){
  402.         gen=in;
  403.         for(auto x:gen){
  404.             freqs.insert(x);
  405.         }
  406.         in=genererLesInduictifs(G,gen);
  407.     }
  408.  
  409.     return freqs;
  410. }
  411. //==============================M A I N   P R O G R A M =======================================
  412. int main() {
  413.     clock_t start = std::clock();
  414.     size_t length;
  415.     std::vector<Graph> dataG =creategraphs(splitstringtolines(readfromfile("10000.data", length)));
  416.     cout << "FILE Contains " << dataG.size() << " graphs."<<endl;
  417.  
  418.  
  419.  
  420.     cout<<"TIME: " << (std::clock() - start) / (double)CLOCKS_PER_SEC<< "s" << endl; // fin du programme.
  421.  
  422. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement