diff --git a/README.md b/README.md index 069c53c..26e0c3d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ HyperGraphLib [![Build Status](https://travis-ci.org/alex-87/HyperGraphLib.svg?branch=master)](https://travis-ci.org/alex-87/HyperGraphLib) ------------- +![hypergraph](http://alex-87.github.io/HyperGraphLib/images/hypergraph.png) How to compile HyperGraphLib ------------- diff --git a/src/algorithm/Isomorph.cpp b/src/algorithm/Isomorph.cpp new file mode 100644 index 0000000..858a9ba --- /dev/null +++ b/src/algorithm/Isomorph.cpp @@ -0,0 +1,87 @@ + +#include "include/Isomorph.hh" +#include "../model/include/Hypergraphe.hh" +#include "../model/include/HyperVertex.hh" +#include "../model/include/HyperEdge.hh" +#include + +Isomorph::Isomorph(const boost::shared_ptr& ptrHypergrapheAbstraitA, + const boost::shared_ptr& ptrHypergrapheAbstraitB) + : _ptrHypergrapheAbstraitA(ptrHypergrapheAbstraitA), + _ptrHypergrapheAbstraitB(ptrHypergrapheAbstraitB) { + +} + +void +Isomorph::runAlgorithme() { + + bool ret = false; + graph_t graphA( _ptrHypergrapheAbstraitA->getHyperEdgeList().size() ), + graphB( _ptrHypergrapheAbstraitB->getHyperEdgeList().size() ); + +#pragma omp parallel sections + { + +#pragma omp section + { + hypergraphTranspose(_ptrHypergrapheAbstraitA, graphA); + } + +#pragma omp section + { + hypergraphTranspose(_ptrHypergrapheAbstraitB, graphB); + } + + } + + std::vector::vertex_descriptor> f( _ptrHypergrapheAbstraitA->getHyperEdgeList().size() ); + + boost::property_map::type + v_index_map = get(boost::vertex_index, graphA); + + ret = boost::isomorphism( + graphA, + graphB, + boost::isomorphism_map( + boost::make_iterator_property_map(f.begin(), v_index_map, f[0]) + ) + ); + + _result.setBooleanResult( ret ); +} + +void +Isomorph::hypergraphTranspose(const boost::shared_ptr& hpg, graph_t& graphOut) { + + std::vector::vertex_descriptor> + v(hpg->getHyperEdgeList().size()); + + boost::property_map::type + v_index_map = get(boost::vertex_index, graphOut); + + boost::graph_traits::vertex_iterator i, end; + int id = 0; + for (boost::tie(i, end) = boost::vertices(graphOut); i != end; ++i, ++id) { + put(v_index_map, *i, id); + v[id] = *i; + } + + for(int u=0; ugetHyperEdgeList().size(); u++ ) { + for(int h=0; hgetHyperEdgeList().at(u)->getHyperVertexList().size(); h++) { + for(int q=0; qgetHyperEdgeList().at(u)->getHyperVertexList().at(h)->getHyperEdgeList().size(); q++) { + boost::add_edge(v[hpg->getHyperEdgeList().at(u)->getHyperVertexList().at(h)->getIdentifier()], + v[hpg->getHyperEdgeList().at(u)->getHyperVertexList().at(h)->getHyperEdgeList().at(q)->getIdentifier()], + graphOut ); + } + } + } +} + +RStructure +Isomorph::getResult() const { + return _result; +} + +Isomorph::~Isomorph() { +} + diff --git a/src/algorithm/include/Isomorph.hh b/src/algorithm/include/Isomorph.hh new file mode 100644 index 0000000..6fb11c8 --- /dev/null +++ b/src/algorithm/include/Isomorph.hh @@ -0,0 +1,46 @@ + +#ifndef ALGORITHM_INCLUDE_ISOMORPHISM_HH_ +#define ALGORITHM_INCLUDE_ISOMORPHISM_HH_ + +#include +#include +#include +#include + +#include "../../model/include/HypergrapheAbstrait.hh" +#include "../../model/include/AlgorithmeAbstrait.hh" + +class Isomorph : public AlgorithmeAbstrait { + +public: + + Isomorph(const boost::shared_ptr&, const boost::shared_ptr&); + + RStructure getResult() const; + + ~Isomorph(); + +protected: + + typedef boost::adjacency_list > + graph_t; + + void hypergraphTranspose(const boost::shared_ptr&, graph_t&); + + void runAlgorithme(); + +protected: + + boost::shared_ptr + _ptrHypergrapheAbstraitA; + + boost::shared_ptr + _ptrHypergrapheAbstraitB; + + RStructure _result; + +}; + + + +#endif diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 556757f..71157a8 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -35,6 +35,7 @@ #include "../algorithm/include/Linear.hh" #include "../algorithm/include/Connected.hh" #include "../algorithm/include/HyperGraphStat.hh" +#include "../algorithm/include/Isomorph.hh" #include "../io/include/WriterFile.hh" #include "../io/include/ReaderFile.hh" @@ -56,6 +57,7 @@ int main(int argc, char *argv[]) { ("simple", "Décide si l'hypergraphe est simple") ("helly", "Décide si un hypergraphe possède la propriété de Helly") ("connexe", "Décide si l'hypergraphe est connexe") + ("isomorph", boost::program_options::value(), "Décide si deux hypergraphes sont isomorphe") ("stat", "Retourne les statistiques de l'hypergraphe") ("path", "Retourne le chemins") ("source", boost::program_options::value(), "Source de la reherche de chemins") @@ -104,6 +106,35 @@ int main(int argc, char *argv[]) { ptrHpg = fReader.getHypergraphe(); } + // Isomorphism special parameters configuration + if( vm.count("isomorph") && vm.count("inputfile") ) { + + boost::shared_ptr ptrHpg2; + + std::ifstream ifs(vm["isomorph"].as(), std::ifstream::in); + + ReaderFile fReader; + fReader.readHypergraphe( ifs ); + ifs.close(); + + ptrHpg2 = fReader.getHypergraphe(); + + NewAlgorithm2(isomorphHpg, Isomorph, ptrHpg, ptrHpg2); + + MotorAlgorithm::setAlgorithme( isomorphHpg ); + MotorAlgorithm::runAlgorithme(); + + RStructure r( isomorphHpg->getResult() ); + + if( r.getBooleanResult() ) { + std::cout << "L'hypergraphe est isomorphe." << std::endl; + } else { + std::cout << "L'hypergraphe n'est pas isomorphe." << std::endl; + } + + return 0; + } + if( vm.count("random") ) { RandomHypergraphe rHyp; rHyp.generateHypergraphe(vm["random"].as(), vm["random"].as()); diff --git a/src/client/include/Client.hh b/src/client/include/Client.hh index 4e80679..c3b29ec 100644 --- a/src/client/include/Client.hh +++ b/src/client/include/Client.hh @@ -3,10 +3,11 @@ #define CLIENT_INCLUDE_CLIENT_HH_ #define VERSION_MAJOR 0 -#define VERSION_MINOR 16 -#define VERSION_BUILD 2 +#define VERSION_MINOR 17 +#define VERSION_BUILD 1 #define NewAlgorithm(a, b, c) boost::shared_ptr a( new b( c ) ); +#define NewAlgorithm2(a, b, c, d) boost::shared_ptr a( new b( c , d ) ); #endif /* CLIENT_INCLUDE_CLIENT_HH_ */ diff --git a/src/lib/LightTreeLib.hpp b/src/lib/LightTreeLib.hpp new file mode 100644 index 0000000..c1adbe3 --- /dev/null +++ b/src/lib/LightTreeLib.hpp @@ -0,0 +1,59 @@ +/* + * LightTreeLib - Small C++ Template library - Used in HypergraphLib + * + */ + +#ifndef LIGHTTREELIB_HPP_ +#define LIGHTTREELIB_HPP_ + +#include +#include + +template +class LightTree { + +public: + + LightTree(const T& t) : _t( t ) { + _cnt = 0; + } + + void + setElement(const T& t) { + _t = t; + } + + void + addNode(boost::shared_ptr >& lightTree) { + _mapNode[_cnt] = lightTree; + _cnt++; + } + + boost::shared_ptr >& + getNode(unsigned int nodeId) { + return _mapNode[nodeId]; + } + + unsigned int + getCardinal() const { + return _cnt; + } + + T& + getElement() { + return _t; + } + + ~LightTree() { + } + +private: + + T _t; + unsigned int _cnt; + std::map > > _mapNode; + +}; + + +#endif /* LIGHTTREELIB_HPP_ */