| @@ -0,0 +1,723 @@ | |||
| /**************************************************************************** | |||
| * * | |||
| * Copyright (C) 2019-2020 by Natacha Lambert, David B. Blumenthal and * | |||
| * Linlin Jia * | |||
| * * | |||
| * This file should be used by Python. * | |||
| * Please call the Python module if you want to use GedLib with this code.* | |||
| * * | |||
| * Otherwise, you can directly use GedLib for C++. * | |||
| * * | |||
| ***************************************************************************/ | |||
| /*! | |||
| * @file GedLibBind.ipp | |||
| * @brief Classe and function definitions to call easly GebLib in Python without Gedlib's types | |||
| */ | |||
| #ifndef GEDLIBBIND_IPP | |||
| #define GEDLIBBIND_IPP | |||
| //Include standard libraries + GedLib library | |||
| // #include <iostream> | |||
| // #include "GedLibBind.h" | |||
| // #include "../include/gedlib-master/src/env/ged_env.hpp" | |||
| //#include "../include/gedlib-master/median/src/median_graph_estimator.hpp" | |||
| using namespace std; | |||
| //Definition of types and templates used in this code for my human's memory :). | |||
| //ged::GEDEnv<UserNodeID, UserNodeLabel, UserEdgeLabel> env; | |||
| //template<class UserNodeID, class UserNodeLabel, class UserEdgeLabel> struct ExchangeGraph | |||
| //typedef std::map<std::string, std::string> GXLLabel; | |||
| //typedef std::string GXLNodeID; | |||
| namespace pyged { | |||
| //!< List of available edit cost functions readable by Python. | |||
| std::vector<std::string> editCostStringOptions = { | |||
| "CHEM_1", | |||
| "CHEM_2", | |||
| "CMU", | |||
| "GREC_1", | |||
| "GREC_2", | |||
| "LETTER", | |||
| "LETTER2", | |||
| "NON_SYMBOLIC", | |||
| "FINGERPRINT", | |||
| "PROTEIN", | |||
| "CONSTANT" | |||
| }; | |||
| //!< Map of available edit cost functions between enum type in C++ and string in Python | |||
| std::map<std::string, ged::Options::EditCosts> editCostOptions = { | |||
| {"CHEM_1", ged::Options::EditCosts::CHEM_1}, | |||
| {"CHEM_2", ged::Options::EditCosts::CHEM_2}, | |||
| {"CMU", ged::Options::EditCosts::CMU}, | |||
| {"GREC_1", ged::Options::EditCosts::GREC_1}, | |||
| {"GREC_2", ged::Options::EditCosts::GREC_2}, | |||
| {"LETTER", ged::Options::EditCosts::LETTER}, | |||
| {"LETTER2", ged::Options::EditCosts::LETTER2}, | |||
| {"NON_SYMBOLIC", ged::Options::EditCosts::NON_SYMBOLIC}, | |||
| {"FINGERPRINT", ged::Options::EditCosts::FINGERPRINT}, | |||
| {"PROTEIN", ged::Options::EditCosts::PROTEIN}, | |||
| {"CONSTANT", ged::Options::EditCosts::CONSTANT} | |||
| }; | |||
| //!< List of available computation methods readable by Python. | |||
| std::vector<std::string> methodStringOptions = { | |||
| "BRANCH", | |||
| "BRANCH_FAST", | |||
| "BRANCH_TIGHT", | |||
| "BRANCH_UNIFORM", | |||
| "BRANCH_COMPACT", | |||
| "PARTITION", | |||
| "HYBRID", | |||
| "RING", | |||
| "ANCHOR_AWARE_GED", | |||
| "WALKS", | |||
| "IPFP", | |||
| "BIPARTITE", | |||
| "SUBGRAPH", | |||
| "NODE", | |||
| "RING_ML", | |||
| "BIPARTITE_ML", | |||
| "REFINE", | |||
| "BP_BEAM", | |||
| "SIMULATED_ANNEALING", | |||
| "HED", | |||
| "STAR" | |||
| }; | |||
| //!< Map of available computation methods readables between enum type in C++ and string in Python | |||
| std::map<std::string, ged::Options::GEDMethod> methodOptions = { | |||
| {"BRANCH", ged::Options::GEDMethod::BRANCH}, | |||
| {"BRANCH_FAST", ged::Options::GEDMethod::BRANCH_FAST}, | |||
| {"BRANCH_TIGHT", ged::Options::GEDMethod::BRANCH_TIGHT}, | |||
| {"BRANCH_UNIFORM", ged::Options::GEDMethod::BRANCH_UNIFORM}, | |||
| {"BRANCH_COMPACT", ged::Options::GEDMethod::BRANCH_COMPACT}, | |||
| {"PARTITION", ged::Options::GEDMethod::PARTITION}, | |||
| {"HYBRID", ged::Options::GEDMethod::HYBRID}, | |||
| {"RING", ged::Options::GEDMethod::RING}, | |||
| {"ANCHOR_AWARE_GED", ged::Options::GEDMethod::ANCHOR_AWARE_GED}, | |||
| {"WALKS", ged::Options::GEDMethod::WALKS}, | |||
| {"IPFP", ged::Options::GEDMethod::IPFP}, | |||
| {"BIPARTITE", ged::Options::GEDMethod::BIPARTITE}, | |||
| {"SUBGRAPH", ged::Options::GEDMethod::SUBGRAPH}, | |||
| {"NODE", ged::Options::GEDMethod::NODE}, | |||
| {"RING_ML", ged::Options::GEDMethod::RING_ML}, | |||
| {"BIPARTITE_ML",ged::Options::GEDMethod::BIPARTITE_ML}, | |||
| {"REFINE",ged::Options::GEDMethod::REFINE}, | |||
| {"BP_BEAM", ged::Options::GEDMethod::BP_BEAM}, | |||
| {"SIMULATED_ANNEALING", ged::Options::GEDMethod::SIMULATED_ANNEALING}, | |||
| {"HED", ged::Options::GEDMethod::HED}, | |||
| {"STAR" , ged::Options::GEDMethod::STAR}, | |||
| }; | |||
| //!<List of available initilaization options readable by Python. | |||
| std::vector<std::string> initStringOptions = { | |||
| "LAZY_WITHOUT_SHUFFLED_COPIES", | |||
| "EAGER_WITHOUT_SHUFFLED_COPIES", | |||
| "LAZY_WITH_SHUFFLED_COPIES", | |||
| "EAGER_WITH_SHUFFLED_COPIES" | |||
| }; | |||
| //!< Map of available initilaization options readables between enum type in C++ and string in Python | |||
| std::map<std::string, ged::Options::InitType> initOptions = { | |||
| {"LAZY_WITHOUT_SHUFFLED_COPIES", ged::Options::InitType::LAZY_WITHOUT_SHUFFLED_COPIES}, | |||
| {"EAGER_WITHOUT_SHUFFLED_COPIES", ged::Options::InitType::EAGER_WITHOUT_SHUFFLED_COPIES}, | |||
| {"LAZY_WITH_SHUFFLED_COPIES", ged::Options::InitType::LAZY_WITH_SHUFFLED_COPIES}, | |||
| {"EAGER_WITH_SHUFFLED_COPIES", ged::Options::InitType::EAGER_WITH_SHUFFLED_COPIES} | |||
| }; | |||
| std::vector<std::string> getEditCostStringOptions() { | |||
| return editCostStringOptions; | |||
| } | |||
| std::vector<std::string> getMethodStringOptions() { | |||
| return methodStringOptions; | |||
| } | |||
| std::vector<std::string> getInitStringOptions() { | |||
| return initStringOptions; | |||
| } | |||
| static std::size_t getDummyNode() { | |||
| return ged::GEDGraph::dummy_node(); | |||
| } | |||
| /*! | |||
| * @brief Returns the enum EditCost which correspond to the string parameter | |||
| * @param editCost Select one of the predefined edit costs in the list. | |||
| * @return The edit cost function which correspond in the edit cost functions map. | |||
| */ | |||
| ged::Options::EditCosts translateEditCost(std::string editCost) { | |||
| for (std::size_t i = 0; i != editCostStringOptions.size(); i++) { | |||
| if (editCostStringOptions[i] == editCost) { | |||
| return editCostOptions[editCostStringOptions[i]]; | |||
| } | |||
| } | |||
| return ged::Options::EditCosts::CONSTANT; | |||
| } | |||
| /*! | |||
| * @brief Returns the enum IniType which correspond to the string parameter | |||
| * @param initOption Select initialization options. | |||
| * @return The init Type which correspond in the init options map. | |||
| */ | |||
| ged::Options::InitType translateInitOptions(std::string initOption) { | |||
| for (std::size_t i = 0; i != initStringOptions.size(); i++) { | |||
| if (initStringOptions[i] == initOption) { | |||
| return initOptions[initStringOptions[i]]; | |||
| } | |||
| } | |||
| return ged::Options::InitType::EAGER_WITHOUT_SHUFFLED_COPIES; | |||
| } | |||
| /*! | |||
| * @brief Returns the string correspond to the enum IniType. | |||
| * @param initOption Select initialization options. | |||
| * @return The string which correspond to the enum IniType @p initOption. | |||
| */ | |||
| std::string initOptionsToString(ged::Options::InitType initOption) { | |||
| for (std::size_t i = 0; i != initOptions.size(); i++) { | |||
| if (initOptions[initStringOptions[i]] == initOption) { | |||
| return initStringOptions[i]; | |||
| } | |||
| } | |||
| return "EAGER_WITHOUT_SHUFFLED_COPIES"; | |||
| } | |||
| /*! | |||
| * @brief Returns the enum Method which correspond to the string parameter | |||
| * @param method Select the method that is to be used. | |||
| * @return The computation method which correspond in the edit cost functions map. | |||
| */ | |||
| ged::Options::GEDMethod translateMethod(std::string method) { | |||
| for (std::size_t i = 0; i != methodStringOptions.size(); i++) { | |||
| if (methodStringOptions[i] == method) { | |||
| return methodOptions[methodStringOptions[i]]; | |||
| } | |||
| } | |||
| return ged::Options::GEDMethod::STAR; | |||
| } | |||
| /*! | |||
| * @brief Returns the vector of values which correspond to the pointer parameter. | |||
| * @param pointer The size_t pointer to convert. | |||
| * @return The vector which contains the pointer's values. | |||
| */ | |||
| std::vector<size_t> translatePointer(std::size_t* pointer, std::size_t dataSize ) { | |||
| std::vector<size_t> res; | |||
| for(std::size_t i = 0; i < dataSize; i++) { | |||
| res.push_back(pointer[i]); | |||
| } | |||
| return res; | |||
| } | |||
| /*! | |||
| * @brief Returns the vector of values which correspond to the pointer parameter. | |||
| * @param pointer The double pointer to convert. | |||
| * @return The vector which contains the pointer's values. | |||
| */ | |||
| std::vector<double> translatePointer(double* pointer, std::size_t dataSize ) { | |||
| std::vector<double> res; | |||
| for(std::size_t i = 0; i < dataSize; i++) { | |||
| res.push_back(pointer[i]); | |||
| } | |||
| return res; | |||
| } | |||
| /*! | |||
| * @brief Returns the vector of values which correspond to the pointer parameter. | |||
| * @param pointer The size_t pointer to convert. | |||
| * @return The vector which contains the pointer's values, with double type. | |||
| */ | |||
| std::vector<double> translateAndConvertPointer(std::size_t* pointer, std::size_t dataSize ) { | |||
| std::vector<double> res; | |||
| for(std::size_t i = 0; i < dataSize; i++) { | |||
| res.push_back((double)pointer[i]); | |||
| } | |||
| return res; | |||
| } | |||
| /*! | |||
| * @brief Returns the string which contains all element of a int list. | |||
| * @param vector The vector to translate. | |||
| * @return The string which contains all elements separated with a blank space. | |||
| */ | |||
| std::string toStringVectorInt(std::vector<int> vector) { | |||
| std::string res = ""; | |||
| for (std::size_t i = 0; i != vector.size(); i++) | |||
| { | |||
| res += std::to_string(vector[i]) + " "; | |||
| } | |||
| return res; | |||
| } | |||
| /*! | |||
| * @brief Returns the string which contains all element of a unsigned long int list. | |||
| * @param vector The vector to translate. | |||
| * @return The string which contains all elements separated with a blank space. | |||
| */ | |||
| std::string toStringVectorInt(std::vector<unsigned long int> vector) { | |||
| std::string res = ""; | |||
| for (std::size_t i = 0; i != vector.size(); i++) | |||
| { | |||
| res += std::to_string(vector[i]) + " "; | |||
| } | |||
| return res; | |||
| } | |||
| PyGEDEnv::PyGEDEnv () { | |||
| env_ = new ged::GEDEnv<ged::GXLNodeID, ged::GXLLabel, ged::GXLLabel>(); | |||
| this->initialized = false; | |||
| } | |||
| PyGEDEnv::~PyGEDEnv () { | |||
| if (env_ != NULL) { | |||
| delete env_; | |||
| env_ = NULL; | |||
| } | |||
| } | |||
| // bool initialized = false; //Initialization boolean (because Env has one but not accessible). | |||
| bool PyGEDEnv::isInitialized() { | |||
| return initialized; | |||
| } | |||
| void PyGEDEnv::restartEnv() { | |||
| if (env_ != NULL) { | |||
| delete env_; | |||
| env_ = NULL; | |||
| } | |||
| env_ = new ged::GEDEnv<ged::GXLNodeID, ged::GXLLabel, ged::GXLLabel>(); | |||
| initialized = false; | |||
| } | |||
| void PyGEDEnv::loadGXLGraph(const std::string & pathFolder, const std::string & pathXML, bool node_type, bool edge_type) { | |||
| std::vector<ged::GEDGraph::GraphID> tmp_graph_ids(env_->load_gxl_graph(pathFolder, pathXML, | |||
| (node_type ? ged::Options::GXLNodeEdgeType::LABELED : ged::Options::GXLNodeEdgeType::UNLABELED), | |||
| (edge_type ? ged::Options::GXLNodeEdgeType::LABELED : ged::Options::GXLNodeEdgeType::UNLABELED), | |||
| std::unordered_set<std::string>(), std::unordered_set<std::string>())); | |||
| } | |||
| std::pair<std::size_t,std::size_t> PyGEDEnv::getGraphIds() const { | |||
| return env_->graph_ids(); | |||
| } | |||
| std::vector<std::size_t> PyGEDEnv::getAllGraphIds() { | |||
| std::vector<std::size_t> listID; | |||
| for (std::size_t i = env_->graph_ids().first; i != env_->graph_ids().second; i++) { | |||
| listID.push_back(i); | |||
| } | |||
| return listID; | |||
| } | |||
| const std::string PyGEDEnv::getGraphClass(std::size_t id) const { | |||
| return env_->get_graph_class(id); | |||
| } | |||
| const std::string PyGEDEnv::getGraphName(std::size_t id) const { | |||
| return env_->get_graph_name(id); | |||
| } | |||
| std::size_t PyGEDEnv::addGraph(const std::string & graph_name, const std::string & graph_class) { | |||
| ged::GEDGraph::GraphID newId = env_->add_graph(graph_name, graph_class); | |||
| initialized = false; | |||
| return std::stoi(std::to_string(newId)); | |||
| } | |||
| void PyGEDEnv::addNode(std::size_t graphId, const std::string & nodeId, const std::map<std::string, std::string> & nodeLabel) { | |||
| env_->add_node(graphId, nodeId, nodeLabel); | |||
| initialized = false; | |||
| } | |||
| /*void addEdge(std::size_t graphId, ged::GXLNodeID tail, ged::GXLNodeID head, ged::GXLLabel edgeLabel) { | |||
| env_->add_edge(graphId, tail, head, edgeLabel); | |||
| }*/ | |||
| void PyGEDEnv::addEdge(std::size_t graphId, const std::string & tail, const std::string & head, const std::map<std::string, std::string> & edgeLabel, bool ignoreDuplicates) { | |||
| env_->add_edge(graphId, tail, head, edgeLabel, ignoreDuplicates); | |||
| initialized = false; | |||
| } | |||
| void PyGEDEnv::clearGraph(std::size_t graphId) { | |||
| env_->clear_graph(graphId); | |||
| initialized = false; | |||
| } | |||
| ged::ExchangeGraph<ged::GXLNodeID, ged::GXLLabel, ged::GXLLabel> PyGEDEnv::getGraph(std::size_t graphId) const { | |||
| return env_->get_graph(graphId); | |||
| } | |||
| std::size_t PyGEDEnv::getGraphInternalId(std::size_t graphId) { | |||
| return getGraph(graphId).id; | |||
| } | |||
| std::size_t PyGEDEnv::getGraphNumNodes(std::size_t graphId) { | |||
| return getGraph(graphId).num_nodes; | |||
| } | |||
| std::size_t PyGEDEnv::getGraphNumEdges(std::size_t graphId) { | |||
| return getGraph(graphId).num_edges; | |||
| } | |||
| std::vector<std::string> PyGEDEnv::getGraphOriginalNodeIds(std::size_t graphId) { | |||
| return getGraph(graphId).original_node_ids; | |||
| } | |||
| std::vector<std::map<std::string, std::string>> PyGEDEnv::getGraphNodeLabels(std::size_t graphId) { | |||
| return getGraph(graphId).node_labels; | |||
| } | |||
| std::map<std::pair<std::size_t, std::size_t>, std::map<std::string, std::string>> PyGEDEnv::getGraphEdges(std::size_t graphId) { | |||
| return getGraph(graphId).edge_labels; | |||
| } | |||
| std::vector<std::vector<std::size_t>> PyGEDEnv::getGraphAdjacenceMatrix(std::size_t graphId) { | |||
| return getGraph(graphId).adj_matrix; | |||
| } | |||
| void PyGEDEnv::setEditCost(std::string editCost, std::vector<double> editCostConstants) { | |||
| env_->set_edit_costs(translateEditCost(editCost), editCostConstants); | |||
| } | |||
| void PyGEDEnv::setPersonalEditCost(std::vector<double> editCostConstants) { | |||
| //env_->set_edit_costs(Your EditCost Class(editCostConstants)); | |||
| } | |||
| // void PyGEDEnv::initEnv() { | |||
| // env_->init(); | |||
| // initialized = true; | |||
| // } | |||
| void PyGEDEnv::initEnv(std::string initOption, bool print_to_stdout) { | |||
| env_->init(translateInitOptions(initOption), print_to_stdout); | |||
| initialized = true; | |||
| } | |||
| void PyGEDEnv::setMethod(std::string method, const std::string & options) { | |||
| env_->set_method(translateMethod(method), options); | |||
| } | |||
| void PyGEDEnv::initMethod() { | |||
| env_->init_method(); | |||
| } | |||
| double PyGEDEnv::getInitime() const { | |||
| return env_->get_init_time(); | |||
| } | |||
| void PyGEDEnv::runMethod(std::size_t g, std::size_t h) { | |||
| env_->run_method(g, h); | |||
| } | |||
| double PyGEDEnv::getUpperBound(std::size_t g, std::size_t h) const { | |||
| return env_->get_upper_bound(g, h); | |||
| } | |||
| double PyGEDEnv::getLowerBound(std::size_t g, std::size_t h) const { | |||
| return env_->get_lower_bound(g, h); | |||
| } | |||
| std::vector<long unsigned int> PyGEDEnv::getForwardMap(std::size_t g, std::size_t h) const { | |||
| return env_->get_node_map(g, h).get_forward_map(); | |||
| } | |||
| std::vector<long unsigned int> PyGEDEnv::getBackwardMap(std::size_t g, std::size_t h) const { | |||
| return env_->get_node_map(g, h).get_backward_map(); | |||
| } | |||
| std::size_t PyGEDEnv::getNodeImage(std::size_t g, std::size_t h, std::size_t nodeId) const { | |||
| return env_->get_node_map(g, h).image(nodeId); | |||
| } | |||
| std::size_t PyGEDEnv::getNodePreImage(std::size_t g, std::size_t h, std::size_t nodeId) const { | |||
| return env_->get_node_map(g, h).pre_image(nodeId); | |||
| } | |||
| double PyGEDEnv::getInducedCost(std::size_t g, std::size_t h) const { | |||
| return env_->get_node_map(g, h).induced_cost(); | |||
| } | |||
| std::vector<pair<std::size_t, std::size_t>> PyGEDEnv::getNodeMap(std::size_t g, std::size_t h) { | |||
| std::vector<pair<std::size_t, std::size_t>> res; | |||
| std::vector<ged::NodeMap::Assignment> relation; | |||
| env_->get_node_map(g, h).as_relation(relation); | |||
| for (const auto & assignment : relation) { | |||
| res.push_back(std::make_pair(assignment.first, assignment.second)); | |||
| } | |||
| return res; | |||
| } | |||
| std::vector<std::vector<int>> PyGEDEnv::getAssignmentMatrix(std::size_t g, std::size_t h) { | |||
| std::vector<std::vector<int>> res; | |||
| for(std::size_t i = 0; i != getForwardMap(g, h).size(); i++) { | |||
| std::vector<int> newLine; | |||
| bool have1 = false; | |||
| for(std::size_t j = 0; j != getBackwardMap(g, h).size(); j++) { | |||
| if (getNodeImage(g, h, i) == j) { | |||
| newLine.push_back(1); | |||
| have1 = true; | |||
| } | |||
| else{ | |||
| newLine.push_back(0); | |||
| } | |||
| } | |||
| if(have1) { | |||
| newLine.push_back(0); | |||
| } | |||
| else{ | |||
| newLine.push_back(1); | |||
| } | |||
| res.push_back(newLine); | |||
| } | |||
| std::vector<int> lastLine; | |||
| for (size_t k = 0; k != getBackwardMap(g,h).size(); k++) { | |||
| if (getBackwardMap(g,h)[k] == ged::GEDGraph::dummy_node()) { | |||
| lastLine.push_back(1); | |||
| } | |||
| else{ | |||
| lastLine.push_back(0); | |||
| } | |||
| } | |||
| res.push_back(lastLine); | |||
| return res; | |||
| } | |||
| std::vector<std::vector<unsigned long int>> PyGEDEnv::getAllMap(std::size_t g, std::size_t h) { | |||
| std::vector<std::vector<unsigned long int>> res; | |||
| res.push_back(getForwardMap(g, h)); | |||
| res.push_back(getBackwardMap(g,h)); | |||
| return res; | |||
| } | |||
| double PyGEDEnv::getRuntime(std::size_t g, std::size_t h) const { | |||
| return env_->get_runtime(g, h); | |||
| } | |||
| bool PyGEDEnv::quasimetricCosts() const { | |||
| return env_->quasimetric_costs(); | |||
| } | |||
| std::vector<std::vector<size_t>> PyGEDEnv::hungarianLSAP(std::vector<std::vector<std::size_t>> matrixCost) { | |||
| std::size_t nrows = matrixCost.size(); | |||
| std::size_t ncols = matrixCost[0].size(); | |||
| std::size_t *rho = new std::size_t[nrows], *varrho = new std::size_t[ncols]; | |||
| std::size_t *u = new std::size_t[nrows], *v = new std::size_t[ncols]; | |||
| std::size_t *C = new std::size_t[nrows*ncols]; | |||
| // std::size_t i = 0, j; | |||
| for (std::size_t i = 0; i < nrows; i++) { | |||
| for (std::size_t j = 0; j < ncols; j++) { | |||
| C[j*nrows+i] = matrixCost[i][j]; | |||
| } | |||
| } | |||
| lsape::hungarianLSAP<std::size_t>(C,nrows,ncols,rho,u,v,varrho); | |||
| std::vector<std::vector<size_t>> res; | |||
| res.push_back(translatePointer(rho, nrows)); | |||
| res.push_back(translatePointer(varrho, ncols)); | |||
| res.push_back(translatePointer(u, nrows)); | |||
| res.push_back(translatePointer(v, ncols)); | |||
| return res; | |||
| } | |||
| std::vector<std::vector<double>> PyGEDEnv::hungarianLSAPE(std::vector<std::vector<double>> matrixCost) { | |||
| std::size_t nrows = matrixCost.size(); | |||
| std::size_t ncols = matrixCost[0].size(); | |||
| std::size_t *rho = new std::size_t[nrows-1], *varrho = new std::size_t[ncols-1]; | |||
| double *u = new double[nrows], *v = new double[ncols]; | |||
| double *C = new double[nrows*ncols]; | |||
| for (std::size_t i = 0; i < nrows; i++) { | |||
| for (std::size_t j = 0; j < ncols; j++) { | |||
| C[j*nrows+i] = matrixCost[i][j]; | |||
| } | |||
| } | |||
| lsape::hungarianLSAPE<double,std::size_t>(C,nrows,ncols,rho,varrho,u,v); | |||
| std::vector<std::vector<double>> res; | |||
| res.push_back(translateAndConvertPointer(rho, nrows-1)); | |||
| res.push_back(translateAndConvertPointer(varrho, ncols-1)); | |||
| res.push_back(translatePointer(u, nrows)); | |||
| res.push_back(translatePointer(v, ncols)); | |||
| return res; | |||
| } | |||
| std::size_t PyGEDEnv::getNumNodeLabels() const { | |||
| return env_->num_node_labels(); | |||
| } | |||
| std::map<std::string, std::string> PyGEDEnv::getNodeLabel(std::size_t label_id) const { | |||
| return env_->get_node_label(label_id); | |||
| } | |||
| std::size_t PyGEDEnv::getNumEdgeLabels() const { | |||
| return env_->num_edge_labels(); | |||
| } | |||
| std::map<std::string, std::string> PyGEDEnv::getEdgeLabel(std::size_t label_id) const { | |||
| return env_->get_edge_label(label_id); | |||
| } | |||
| // std::size_t PyGEDEnv::getNumNodes(std::size_t graph_id) const { | |||
| // return env_->get_num_nodes(graph_id); | |||
| // } | |||
| double PyGEDEnv::getAvgNumNodes() const { | |||
| return env_->get_avg_num_nodes(); | |||
| } | |||
| double PyGEDEnv::getNodeRelCost(const std::map<std::string, std::string> & node_label_1, const std::map<std::string, std::string> & node_label_2) const { | |||
| return env_->node_rel_cost(node_label_1, node_label_2); | |||
| } | |||
| double PyGEDEnv::getNodeDelCost(const std::map<std::string, std::string> & node_label) const { | |||
| return env_->node_del_cost(node_label); | |||
| } | |||
| double PyGEDEnv::getNodeInsCost(const std::map<std::string, std::string> & node_label) const { | |||
| return env_->node_ins_cost(node_label); | |||
| } | |||
| std::map<std::string, std::string> PyGEDEnv::getMedianNodeLabel(const std::vector<std::map<std::string, std::string>> & node_labels) const { | |||
| return env_->median_node_label(node_labels); | |||
| } | |||
| double PyGEDEnv::getEdgeRelCost(const std::map<std::string, std::string> & edge_label_1, const std::map<std::string, std::string> & edge_label_2) const { | |||
| return env_->edge_rel_cost(edge_label_1, edge_label_2); | |||
| } | |||
| double PyGEDEnv::getEdgeDelCost(const std::map<std::string, std::string> & edge_label) const { | |||
| return env_->edge_del_cost(edge_label); | |||
| } | |||
| double PyGEDEnv::getEdgeInsCost(const std::map<std::string, std::string> & edge_label) const { | |||
| return env_->edge_ins_cost(edge_label); | |||
| } | |||
| std::map<std::string, std::string> PyGEDEnv::getMedianEdgeLabel(const std::vector<std::map<std::string, std::string>> & edge_labels) const { | |||
| return env_->median_edge_label(edge_labels); | |||
| } | |||
| std::string PyGEDEnv::getInitType() const { | |||
| return initOptionsToString(env_->get_init_type()); | |||
| } | |||
| double PyGEDEnv::computeInducedCost(std::size_t g_id, std::size_t h_id, std::vector<pair<std::size_t, std::size_t>> relation) const { | |||
| ged::NodeMap node_map = ged::NodeMap(env_->get_num_nodes(g_id), env_->get_num_nodes(h_id)); | |||
| for (const auto & assignment : relation) { | |||
| node_map.add_assignment(assignment.first, assignment.second); | |||
| // std::cout << assignment.first << assignment.second << endl; | |||
| } | |||
| const std::vector<ged::GEDGraph::NodeID> forward_map = node_map.get_forward_map(); | |||
| for (std::size_t i{0}; i < node_map.num_source_nodes(); i++) { | |||
| if (forward_map.at(i) == ged::GEDGraph::undefined_node()) { | |||
| node_map.add_assignment(i, ged::GEDGraph::dummy_node()); | |||
| } | |||
| } | |||
| const std::vector<ged::GEDGraph::NodeID> backward_map = node_map.get_backward_map(); | |||
| for (std::size_t i{0}; i < node_map.num_target_nodes(); i++) { | |||
| if (backward_map.at(i) == ged::GEDGraph::undefined_node()) { | |||
| node_map.add_assignment(ged::GEDGraph::dummy_node(), i); | |||
| } | |||
| } | |||
| // for (auto & map : node_map.get_forward_map()) { | |||
| // std::cout << map << ", "; | |||
| // } | |||
| // std::cout << endl; | |||
| // for (auto & map : node_map.get_backward_map()) { | |||
| // std::cout << map << ", "; | |||
| // } | |||
| env_->compute_induced_cost(g_id, h_id, node_map); | |||
| return node_map.induced_cost(); | |||
| } | |||
| // double PyGEDEnv::getNodeCost(std::size_t label1, std::size_t label2) const { | |||
| // return env_->ged_data_node_cost(label1, label2); | |||
| // } | |||
| /*void medianLetter(pathFolder, pathXML, editCost, method, options="", initOption = "EAGER_WITHOUT_SHUFFLED_COPIES") { | |||
| if(isInitialized()) { | |||
| restartEnv(); | |||
| } | |||
| setEditCost(editCost);*/ | |||
| /*std::string letter_class("A"); | |||
| if (argc > 1) { | |||
| letter_class = std::string(argv[1]); | |||
| }*/ | |||
| //std::string seed("0"); | |||
| /*if (argc > 2) { | |||
| seed = std::string(argv[2]); | |||
| }*/ | |||
| /*loadGXLGraph(pathFolder, pathXML); | |||
| std::vector<std::size_t> graph_ids = getAllGraphIds(); | |||
| std::size_t median_id = env_->add_graph("median", ""); | |||
| initEnv(initOption); | |||
| setMethod(method); | |||
| ged::MedianGraphEstimator<ged::GXLNodeID, ged::GXLLabel, ged::GXLLabel> median_estimator(&env, false); | |||
| median_estimator.set_options("--init-type RANDOM --randomness PSEUDO --seed " + seed); | |||
| median_estimator.run(graph_ids, median_id); | |||
| std::string gxl_file_name("../output/gen_median_Letter_HIGH_" + letter_class + ".gxl"); | |||
| env_->save_as_gxl_graph(median_id, gxl_file_name);*/ | |||
| /*std::string tikz_file_name("../output/gen_median_Letter_HIGH_" + letter_class + ".tex"); | |||
| save_letter_graph_as_tikz_file(env_->get_graph(median_id), tikz_file_name);*/ | |||
| //} | |||
| } | |||
| #endif /* SRC_GEDLIB_BIND_IPP */ | |||
| // namespace shapes { | |||
| // // Default constructor | |||
| // Rectangle::Rectangle () {} | |||
| // // Overloaded constructor | |||
| // Rectangle::Rectangle (int x0, int y0, int x1, int y1) { | |||
| // this->x0 = x0; | |||
| // this->y0 = y0; | |||
| // this->x1 = x1; | |||
| // this->y1 = y1; | |||
| // } | |||
| // // Destructor | |||
| // Rectangle::~Rectangle () {} | |||
| // // Return the area of the rectangle | |||
| // int Rectangle::getArea () { | |||
| // return (this->x1 - this->x0) * (this->y1 - this->y0); | |||
| // } | |||
| // // Get the size of the rectangle. | |||
| // // Put the size in the pointer args | |||
| // void Rectangle::getSize (int *width, int *height) { | |||
| // (*width) = x1 - x0; | |||
| // (*height) = y1 - y0; | |||
| // } | |||
| // // Move the rectangle by dx dy | |||
| // void Rectangle::move (int dx, int dy) { | |||
| // this->x0 += dx; | |||
| // this->y0 += dy; | |||
| // this->x1 += dx; | |||
| // this->y1 += dy; | |||
| // } | |||
| // } | |||