You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

GedLibBind.ipp 24 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. /****************************************************************************
  2. * *
  3. * Copyright (C) 2019-2020 by Natacha Lambert, David B. Blumenthal and *
  4. * Linlin Jia *
  5. * *
  6. * This file should be used by Python. *
  7. * Please call the Python module if you want to use GedLib with this code.*
  8. * *
  9. * Otherwise, you can directly use GedLib for C++. *
  10. * *
  11. ***************************************************************************/
  12. /*!
  13. * @file GedLibBind.ipp
  14. * @brief Classe and function definitions to call easly GebLib in Python without Gedlib's types
  15. */
  16. #ifndef GEDLIBBIND_IPP
  17. #define GEDLIBBIND_IPP
  18. //Include standard libraries + GedLib library
  19. // #include <iostream>
  20. // #include "GedLibBind.h"
  21. // #include "../include/gedlib-master/src/env/ged_env.hpp"
  22. //#include "../include/gedlib-master/median/src/median_graph_estimator.hpp"
  23. using namespace std;
  24. //Definition of types and templates used in this code for my human's memory :).
  25. //ged::GEDEnv<UserNodeID, UserNodeLabel, UserEdgeLabel> env;
  26. //template<class UserNodeID, class UserNodeLabel, class UserEdgeLabel> struct ExchangeGraph
  27. //typedef std::map<std::string, std::string> GXLLabel;
  28. //typedef std::string GXLNodeID;
  29. namespace pyged {
  30. //!< List of available edit cost functions readable by Python.
  31. std::vector<std::string> editCostStringOptions = {
  32. "CHEM_1",
  33. "CHEM_2",
  34. "CMU",
  35. "GREC_1",
  36. "GREC_2",
  37. "LETTER",
  38. "LETTER2",
  39. "NON_SYMBOLIC",
  40. "FINGERPRINT",
  41. "PROTEIN",
  42. "CONSTANT"
  43. };
  44. //!< Map of available edit cost functions between enum type in C++ and string in Python
  45. std::map<std::string, ged::Options::EditCosts> editCostOptions = {
  46. {"CHEM_1", ged::Options::EditCosts::CHEM_1},
  47. {"CHEM_2", ged::Options::EditCosts::CHEM_2},
  48. {"CMU", ged::Options::EditCosts::CMU},
  49. {"GREC_1", ged::Options::EditCosts::GREC_1},
  50. {"GREC_2", ged::Options::EditCosts::GREC_2},
  51. {"LETTER", ged::Options::EditCosts::LETTER},
  52. {"LETTER2", ged::Options::EditCosts::LETTER2},
  53. {"NON_SYMBOLIC", ged::Options::EditCosts::NON_SYMBOLIC},
  54. {"FINGERPRINT", ged::Options::EditCosts::FINGERPRINT},
  55. {"PROTEIN", ged::Options::EditCosts::PROTEIN},
  56. {"CONSTANT", ged::Options::EditCosts::CONSTANT}
  57. };
  58. //!< List of available computation methods readable by Python.
  59. std::vector<std::string> methodStringOptions = {
  60. "BRANCH",
  61. "BRANCH_FAST",
  62. "BRANCH_TIGHT",
  63. "BRANCH_UNIFORM",
  64. "BRANCH_COMPACT",
  65. "PARTITION",
  66. "HYBRID",
  67. "RING",
  68. "ANCHOR_AWARE_GED",
  69. "WALKS",
  70. "IPFP",
  71. "BIPARTITE",
  72. "SUBGRAPH",
  73. "NODE",
  74. "RING_ML",
  75. "BIPARTITE_ML",
  76. "REFINE",
  77. "BP_BEAM",
  78. "SIMULATED_ANNEALING",
  79. "HED",
  80. "STAR"
  81. };
  82. //!< Map of available computation methods readables between enum type in C++ and string in Python
  83. std::map<std::string, ged::Options::GEDMethod> methodOptions = {
  84. {"BRANCH", ged::Options::GEDMethod::BRANCH},
  85. {"BRANCH_FAST", ged::Options::GEDMethod::BRANCH_FAST},
  86. {"BRANCH_TIGHT", ged::Options::GEDMethod::BRANCH_TIGHT},
  87. {"BRANCH_UNIFORM", ged::Options::GEDMethod::BRANCH_UNIFORM},
  88. {"BRANCH_COMPACT", ged::Options::GEDMethod::BRANCH_COMPACT},
  89. {"PARTITION", ged::Options::GEDMethod::PARTITION},
  90. {"HYBRID", ged::Options::GEDMethod::HYBRID},
  91. {"RING", ged::Options::GEDMethod::RING},
  92. {"ANCHOR_AWARE_GED", ged::Options::GEDMethod::ANCHOR_AWARE_GED},
  93. {"WALKS", ged::Options::GEDMethod::WALKS},
  94. {"IPFP", ged::Options::GEDMethod::IPFP},
  95. {"BIPARTITE", ged::Options::GEDMethod::BIPARTITE},
  96. {"SUBGRAPH", ged::Options::GEDMethod::SUBGRAPH},
  97. {"NODE", ged::Options::GEDMethod::NODE},
  98. {"RING_ML", ged::Options::GEDMethod::RING_ML},
  99. {"BIPARTITE_ML",ged::Options::GEDMethod::BIPARTITE_ML},
  100. {"REFINE",ged::Options::GEDMethod::REFINE},
  101. {"BP_BEAM", ged::Options::GEDMethod::BP_BEAM},
  102. {"SIMULATED_ANNEALING", ged::Options::GEDMethod::SIMULATED_ANNEALING},
  103. {"HED", ged::Options::GEDMethod::HED},
  104. {"STAR" , ged::Options::GEDMethod::STAR},
  105. };
  106. //!<List of available initilaization options readable by Python.
  107. std::vector<std::string> initStringOptions = {
  108. "LAZY_WITHOUT_SHUFFLED_COPIES",
  109. "EAGER_WITHOUT_SHUFFLED_COPIES",
  110. "LAZY_WITH_SHUFFLED_COPIES",
  111. "EAGER_WITH_SHUFFLED_COPIES"
  112. };
  113. //!< Map of available initilaization options readables between enum type in C++ and string in Python
  114. std::map<std::string, ged::Options::InitType> initOptions = {
  115. {"LAZY_WITHOUT_SHUFFLED_COPIES", ged::Options::InitType::LAZY_WITHOUT_SHUFFLED_COPIES},
  116. {"EAGER_WITHOUT_SHUFFLED_COPIES", ged::Options::InitType::EAGER_WITHOUT_SHUFFLED_COPIES},
  117. {"LAZY_WITH_SHUFFLED_COPIES", ged::Options::InitType::LAZY_WITH_SHUFFLED_COPIES},
  118. {"EAGER_WITH_SHUFFLED_COPIES", ged::Options::InitType::EAGER_WITH_SHUFFLED_COPIES}
  119. };
  120. std::vector<std::string> getEditCostStringOptions() {
  121. return editCostStringOptions;
  122. }
  123. std::vector<std::string> getMethodStringOptions() {
  124. return methodStringOptions;
  125. }
  126. std::vector<std::string> getInitStringOptions() {
  127. return initStringOptions;
  128. }
  129. static std::size_t getDummyNode() {
  130. return ged::GEDGraph::dummy_node();
  131. }
  132. /*!
  133. * @brief Returns the enum EditCost which correspond to the string parameter
  134. * @param editCost Select one of the predefined edit costs in the list.
  135. * @return The edit cost function which correspond in the edit cost functions map.
  136. */
  137. ged::Options::EditCosts translateEditCost(std::string editCost) {
  138. for (std::size_t i = 0; i != editCostStringOptions.size(); i++) {
  139. if (editCostStringOptions[i] == editCost) {
  140. return editCostOptions[editCostStringOptions[i]];
  141. }
  142. }
  143. return ged::Options::EditCosts::CONSTANT;
  144. }
  145. /*!
  146. * @brief Returns the enum IniType which correspond to the string parameter
  147. * @param initOption Select initialization options.
  148. * @return The init Type which correspond in the init options map.
  149. */
  150. ged::Options::InitType translateInitOptions(std::string initOption) {
  151. for (std::size_t i = 0; i != initStringOptions.size(); i++) {
  152. if (initStringOptions[i] == initOption) {
  153. return initOptions[initStringOptions[i]];
  154. }
  155. }
  156. return ged::Options::InitType::EAGER_WITHOUT_SHUFFLED_COPIES;
  157. }
  158. /*!
  159. * @brief Returns the string correspond to the enum IniType.
  160. * @param initOption Select initialization options.
  161. * @return The string which correspond to the enum IniType @p initOption.
  162. */
  163. std::string initOptionsToString(ged::Options::InitType initOption) {
  164. for (std::size_t i = 0; i != initOptions.size(); i++) {
  165. if (initOptions[initStringOptions[i]] == initOption) {
  166. return initStringOptions[i];
  167. }
  168. }
  169. return "EAGER_WITHOUT_SHUFFLED_COPIES";
  170. }
  171. /*!
  172. * @brief Returns the enum Method which correspond to the string parameter
  173. * @param method Select the method that is to be used.
  174. * @return The computation method which correspond in the edit cost functions map.
  175. */
  176. ged::Options::GEDMethod translateMethod(std::string method) {
  177. for (std::size_t i = 0; i != methodStringOptions.size(); i++) {
  178. if (methodStringOptions[i] == method) {
  179. return methodOptions[methodStringOptions[i]];
  180. }
  181. }
  182. return ged::Options::GEDMethod::STAR;
  183. }
  184. /*!
  185. * @brief Returns the vector of values which correspond to the pointer parameter.
  186. * @param pointer The size_t pointer to convert.
  187. * @return The vector which contains the pointer's values.
  188. */
  189. std::vector<size_t> translatePointer(std::size_t* pointer, std::size_t dataSize ) {
  190. std::vector<size_t> res;
  191. for(std::size_t i = 0; i < dataSize; i++) {
  192. res.push_back(pointer[i]);
  193. }
  194. return res;
  195. }
  196. /*!
  197. * @brief Returns the vector of values which correspond to the pointer parameter.
  198. * @param pointer The double pointer to convert.
  199. * @return The vector which contains the pointer's values.
  200. */
  201. std::vector<double> translatePointer(double* pointer, std::size_t dataSize ) {
  202. std::vector<double> res;
  203. for(std::size_t i = 0; i < dataSize; i++) {
  204. res.push_back(pointer[i]);
  205. }
  206. return res;
  207. }
  208. /*!
  209. * @brief Returns the vector of values which correspond to the pointer parameter.
  210. * @param pointer The size_t pointer to convert.
  211. * @return The vector which contains the pointer's values, with double type.
  212. */
  213. std::vector<double> translateAndConvertPointer(std::size_t* pointer, std::size_t dataSize ) {
  214. std::vector<double> res;
  215. for(std::size_t i = 0; i < dataSize; i++) {
  216. res.push_back((double)pointer[i]);
  217. }
  218. return res;
  219. }
  220. /*!
  221. * @brief Returns the string which contains all element of a int list.
  222. * @param vector The vector to translate.
  223. * @return The string which contains all elements separated with a blank space.
  224. */
  225. std::string toStringVectorInt(std::vector<int> vector) {
  226. std::string res = "";
  227. for (std::size_t i = 0; i != vector.size(); i++)
  228. {
  229. res += std::to_string(vector[i]) + " ";
  230. }
  231. return res;
  232. }
  233. /*!
  234. * @brief Returns the string which contains all element of a unsigned long int list.
  235. * @param vector The vector to translate.
  236. * @return The string which contains all elements separated with a blank space.
  237. */
  238. std::string toStringVectorInt(std::vector<unsigned long int> vector) {
  239. std::string res = "";
  240. for (std::size_t i = 0; i != vector.size(); i++)
  241. {
  242. res += std::to_string(vector[i]) + " ";
  243. }
  244. return res;
  245. }
  246. PyGEDEnv::PyGEDEnv () {
  247. env_ = new ged::GEDEnv<ged::GXLNodeID, ged::GXLLabel, ged::GXLLabel>();
  248. this->initialized = false;
  249. }
  250. PyGEDEnv::~PyGEDEnv () {
  251. if (env_ != NULL) {
  252. delete env_;
  253. env_ = NULL;
  254. }
  255. }
  256. // bool initialized = false; //Initialization boolean (because Env has one but not accessible).
  257. bool PyGEDEnv::isInitialized() {
  258. return initialized;
  259. }
  260. void PyGEDEnv::restartEnv() {
  261. if (env_ != NULL) {
  262. delete env_;
  263. env_ = NULL;
  264. }
  265. env_ = new ged::GEDEnv<ged::GXLNodeID, ged::GXLLabel, ged::GXLLabel>();
  266. initialized = false;
  267. }
  268. void PyGEDEnv::loadGXLGraph(const std::string & pathFolder, const std::string & pathXML, bool node_type, bool edge_type) {
  269. std::vector<ged::GEDGraph::GraphID> tmp_graph_ids(env_->load_gxl_graph(pathFolder, pathXML,
  270. (node_type ? ged::Options::GXLNodeEdgeType::LABELED : ged::Options::GXLNodeEdgeType::UNLABELED),
  271. (edge_type ? ged::Options::GXLNodeEdgeType::LABELED : ged::Options::GXLNodeEdgeType::UNLABELED),
  272. std::unordered_set<std::string>(), std::unordered_set<std::string>()));
  273. }
  274. std::pair<std::size_t,std::size_t> PyGEDEnv::getGraphIds() const {
  275. return env_->graph_ids();
  276. }
  277. std::vector<std::size_t> PyGEDEnv::getAllGraphIds() {
  278. std::vector<std::size_t> listID;
  279. for (std::size_t i = env_->graph_ids().first; i != env_->graph_ids().second; i++) {
  280. listID.push_back(i);
  281. }
  282. return listID;
  283. }
  284. const std::string PyGEDEnv::getGraphClass(std::size_t id) const {
  285. return env_->get_graph_class(id);
  286. }
  287. const std::string PyGEDEnv::getGraphName(std::size_t id) const {
  288. return env_->get_graph_name(id);
  289. }
  290. std::size_t PyGEDEnv::addGraph(const std::string & graph_name, const std::string & graph_class) {
  291. ged::GEDGraph::GraphID newId = env_->add_graph(graph_name, graph_class);
  292. initialized = false;
  293. return std::stoi(std::to_string(newId));
  294. }
  295. void PyGEDEnv::addNode(std::size_t graphId, const std::string & nodeId, const std::map<std::string, std::string> & nodeLabel) {
  296. env_->add_node(graphId, nodeId, nodeLabel);
  297. initialized = false;
  298. }
  299. /*void addEdge(std::size_t graphId, ged::GXLNodeID tail, ged::GXLNodeID head, ged::GXLLabel edgeLabel) {
  300. env_->add_edge(graphId, tail, head, edgeLabel);
  301. }*/
  302. 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) {
  303. env_->add_edge(graphId, tail, head, edgeLabel, ignoreDuplicates);
  304. initialized = false;
  305. }
  306. void PyGEDEnv::clearGraph(std::size_t graphId) {
  307. env_->clear_graph(graphId);
  308. initialized = false;
  309. }
  310. ged::ExchangeGraph<ged::GXLNodeID, ged::GXLLabel, ged::GXLLabel> PyGEDEnv::getGraph(std::size_t graphId) const {
  311. return env_->get_graph(graphId);
  312. }
  313. std::size_t PyGEDEnv::getGraphInternalId(std::size_t graphId) {
  314. return getGraph(graphId).id;
  315. }
  316. std::size_t PyGEDEnv::getGraphNumNodes(std::size_t graphId) {
  317. return getGraph(graphId).num_nodes;
  318. }
  319. std::size_t PyGEDEnv::getGraphNumEdges(std::size_t graphId) {
  320. return getGraph(graphId).num_edges;
  321. }
  322. std::vector<std::string> PyGEDEnv::getGraphOriginalNodeIds(std::size_t graphId) {
  323. return getGraph(graphId).original_node_ids;
  324. }
  325. std::vector<std::map<std::string, std::string>> PyGEDEnv::getGraphNodeLabels(std::size_t graphId) {
  326. return getGraph(graphId).node_labels;
  327. }
  328. std::map<std::pair<std::size_t, std::size_t>, std::map<std::string, std::string>> PyGEDEnv::getGraphEdges(std::size_t graphId) {
  329. return getGraph(graphId).edge_labels;
  330. }
  331. std::vector<std::vector<std::size_t>> PyGEDEnv::getGraphAdjacenceMatrix(std::size_t graphId) {
  332. return getGraph(graphId).adj_matrix;
  333. }
  334. void PyGEDEnv::setEditCost(std::string editCost, std::vector<double> editCostConstants) {
  335. env_->set_edit_costs(translateEditCost(editCost), editCostConstants);
  336. }
  337. void PyGEDEnv::setPersonalEditCost(std::vector<double> editCostConstants) {
  338. //env_->set_edit_costs(Your EditCost Class(editCostConstants));
  339. }
  340. // void PyGEDEnv::initEnv() {
  341. // env_->init();
  342. // initialized = true;
  343. // }
  344. void PyGEDEnv::initEnv(std::string initOption, bool print_to_stdout) {
  345. env_->init(translateInitOptions(initOption), print_to_stdout);
  346. initialized = true;
  347. }
  348. void PyGEDEnv::setMethod(std::string method, const std::string & options) {
  349. env_->set_method(translateMethod(method), options);
  350. }
  351. void PyGEDEnv::initMethod() {
  352. env_->init_method();
  353. }
  354. double PyGEDEnv::getInitime() const {
  355. return env_->get_init_time();
  356. }
  357. void PyGEDEnv::runMethod(std::size_t g, std::size_t h) {
  358. env_->run_method(g, h);
  359. }
  360. double PyGEDEnv::getUpperBound(std::size_t g, std::size_t h) const {
  361. return env_->get_upper_bound(g, h);
  362. }
  363. double PyGEDEnv::getLowerBound(std::size_t g, std::size_t h) const {
  364. return env_->get_lower_bound(g, h);
  365. }
  366. std::vector<long unsigned int> PyGEDEnv::getForwardMap(std::size_t g, std::size_t h) const {
  367. return env_->get_node_map(g, h).get_forward_map();
  368. }
  369. std::vector<long unsigned int> PyGEDEnv::getBackwardMap(std::size_t g, std::size_t h) const {
  370. return env_->get_node_map(g, h).get_backward_map();
  371. }
  372. std::size_t PyGEDEnv::getNodeImage(std::size_t g, std::size_t h, std::size_t nodeId) const {
  373. return env_->get_node_map(g, h).image(nodeId);
  374. }
  375. std::size_t PyGEDEnv::getNodePreImage(std::size_t g, std::size_t h, std::size_t nodeId) const {
  376. return env_->get_node_map(g, h).pre_image(nodeId);
  377. }
  378. double PyGEDEnv::getInducedCost(std::size_t g, std::size_t h) const {
  379. return env_->get_node_map(g, h).induced_cost();
  380. }
  381. std::vector<pair<std::size_t, std::size_t>> PyGEDEnv::getNodeMap(std::size_t g, std::size_t h) {
  382. std::vector<pair<std::size_t, std::size_t>> res;
  383. std::vector<ged::NodeMap::Assignment> relation;
  384. env_->get_node_map(g, h).as_relation(relation);
  385. for (const auto & assignment : relation) {
  386. res.push_back(std::make_pair(assignment.first, assignment.second));
  387. }
  388. return res;
  389. }
  390. std::vector<std::vector<int>> PyGEDEnv::getAssignmentMatrix(std::size_t g, std::size_t h) {
  391. std::vector<std::vector<int>> res;
  392. for(std::size_t i = 0; i != getForwardMap(g, h).size(); i++) {
  393. std::vector<int> newLine;
  394. bool have1 = false;
  395. for(std::size_t j = 0; j != getBackwardMap(g, h).size(); j++) {
  396. if (getNodeImage(g, h, i) == j) {
  397. newLine.push_back(1);
  398. have1 = true;
  399. }
  400. else{
  401. newLine.push_back(0);
  402. }
  403. }
  404. if(have1) {
  405. newLine.push_back(0);
  406. }
  407. else{
  408. newLine.push_back(1);
  409. }
  410. res.push_back(newLine);
  411. }
  412. std::vector<int> lastLine;
  413. for (size_t k = 0; k != getBackwardMap(g,h).size(); k++) {
  414. if (getBackwardMap(g,h)[k] == ged::GEDGraph::dummy_node()) {
  415. lastLine.push_back(1);
  416. }
  417. else{
  418. lastLine.push_back(0);
  419. }
  420. }
  421. res.push_back(lastLine);
  422. return res;
  423. }
  424. std::vector<std::vector<unsigned long int>> PyGEDEnv::getAllMap(std::size_t g, std::size_t h) {
  425. std::vector<std::vector<unsigned long int>> res;
  426. res.push_back(getForwardMap(g, h));
  427. res.push_back(getBackwardMap(g,h));
  428. return res;
  429. }
  430. double PyGEDEnv::getRuntime(std::size_t g, std::size_t h) const {
  431. return env_->get_runtime(g, h);
  432. }
  433. bool PyGEDEnv::quasimetricCosts() const {
  434. return env_->quasimetric_costs();
  435. }
  436. std::vector<std::vector<size_t>> PyGEDEnv::hungarianLSAP(std::vector<std::vector<std::size_t>> matrixCost) {
  437. std::size_t nrows = matrixCost.size();
  438. std::size_t ncols = matrixCost[0].size();
  439. std::size_t *rho = new std::size_t[nrows], *varrho = new std::size_t[ncols];
  440. std::size_t *u = new std::size_t[nrows], *v = new std::size_t[ncols];
  441. std::size_t *C = new std::size_t[nrows*ncols];
  442. // std::size_t i = 0, j;
  443. for (std::size_t i = 0; i < nrows; i++) {
  444. for (std::size_t j = 0; j < ncols; j++) {
  445. C[j*nrows+i] = matrixCost[i][j];
  446. }
  447. }
  448. lsape::hungarianLSAP<std::size_t>(C,nrows,ncols,rho,u,v,varrho);
  449. std::vector<std::vector<size_t>> res;
  450. res.push_back(translatePointer(rho, nrows));
  451. res.push_back(translatePointer(varrho, ncols));
  452. res.push_back(translatePointer(u, nrows));
  453. res.push_back(translatePointer(v, ncols));
  454. return res;
  455. }
  456. std::vector<std::vector<double>> PyGEDEnv::hungarianLSAPE(std::vector<std::vector<double>> matrixCost) {
  457. std::size_t nrows = matrixCost.size();
  458. std::size_t ncols = matrixCost[0].size();
  459. std::size_t *rho = new std::size_t[nrows-1], *varrho = new std::size_t[ncols-1];
  460. double *u = new double[nrows], *v = new double[ncols];
  461. double *C = new double[nrows*ncols];
  462. for (std::size_t i = 0; i < nrows; i++) {
  463. for (std::size_t j = 0; j < ncols; j++) {
  464. C[j*nrows+i] = matrixCost[i][j];
  465. }
  466. }
  467. lsape::hungarianLSAPE<double,std::size_t>(C,nrows,ncols,rho,varrho,u,v);
  468. std::vector<std::vector<double>> res;
  469. res.push_back(translateAndConvertPointer(rho, nrows-1));
  470. res.push_back(translateAndConvertPointer(varrho, ncols-1));
  471. res.push_back(translatePointer(u, nrows));
  472. res.push_back(translatePointer(v, ncols));
  473. return res;
  474. }
  475. std::size_t PyGEDEnv::getNumNodeLabels() const {
  476. return env_->num_node_labels();
  477. }
  478. std::map<std::string, std::string> PyGEDEnv::getNodeLabel(std::size_t label_id) const {
  479. return env_->get_node_label(label_id);
  480. }
  481. std::size_t PyGEDEnv::getNumEdgeLabels() const {
  482. return env_->num_edge_labels();
  483. }
  484. std::map<std::string, std::string> PyGEDEnv::getEdgeLabel(std::size_t label_id) const {
  485. return env_->get_edge_label(label_id);
  486. }
  487. // std::size_t PyGEDEnv::getNumNodes(std::size_t graph_id) const {
  488. // return env_->get_num_nodes(graph_id);
  489. // }
  490. double PyGEDEnv::getAvgNumNodes() const {
  491. return env_->get_avg_num_nodes();
  492. }
  493. double PyGEDEnv::getNodeRelCost(const std::map<std::string, std::string> & node_label_1, const std::map<std::string, std::string> & node_label_2) const {
  494. return env_->node_rel_cost(node_label_1, node_label_2);
  495. }
  496. double PyGEDEnv::getNodeDelCost(const std::map<std::string, std::string> & node_label) const {
  497. return env_->node_del_cost(node_label);
  498. }
  499. double PyGEDEnv::getNodeInsCost(const std::map<std::string, std::string> & node_label) const {
  500. return env_->node_ins_cost(node_label);
  501. }
  502. std::map<std::string, std::string> PyGEDEnv::getMedianNodeLabel(const std::vector<std::map<std::string, std::string>> & node_labels) const {
  503. return env_->median_node_label(node_labels);
  504. }
  505. double PyGEDEnv::getEdgeRelCost(const std::map<std::string, std::string> & edge_label_1, const std::map<std::string, std::string> & edge_label_2) const {
  506. return env_->edge_rel_cost(edge_label_1, edge_label_2);
  507. }
  508. double PyGEDEnv::getEdgeDelCost(const std::map<std::string, std::string> & edge_label) const {
  509. return env_->edge_del_cost(edge_label);
  510. }
  511. double PyGEDEnv::getEdgeInsCost(const std::map<std::string, std::string> & edge_label) const {
  512. return env_->edge_ins_cost(edge_label);
  513. }
  514. std::map<std::string, std::string> PyGEDEnv::getMedianEdgeLabel(const std::vector<std::map<std::string, std::string>> & edge_labels) const {
  515. return env_->median_edge_label(edge_labels);
  516. }
  517. std::string PyGEDEnv::getInitType() const {
  518. return initOptionsToString(env_->get_init_type());
  519. }
  520. double PyGEDEnv::computeInducedCost(std::size_t g_id, std::size_t h_id, std::vector<pair<std::size_t, std::size_t>> relation) const {
  521. ged::NodeMap node_map = ged::NodeMap(env_->get_num_nodes(g_id), env_->get_num_nodes(h_id));
  522. for (const auto & assignment : relation) {
  523. node_map.add_assignment(assignment.first, assignment.second);
  524. // std::cout << assignment.first << assignment.second << endl;
  525. }
  526. const std::vector<ged::GEDGraph::NodeID> forward_map = node_map.get_forward_map();
  527. for (std::size_t i{0}; i < node_map.num_source_nodes(); i++) {
  528. if (forward_map.at(i) == ged::GEDGraph::undefined_node()) {
  529. node_map.add_assignment(i, ged::GEDGraph::dummy_node());
  530. }
  531. }
  532. const std::vector<ged::GEDGraph::NodeID> backward_map = node_map.get_backward_map();
  533. for (std::size_t i{0}; i < node_map.num_target_nodes(); i++) {
  534. if (backward_map.at(i) == ged::GEDGraph::undefined_node()) {
  535. node_map.add_assignment(ged::GEDGraph::dummy_node(), i);
  536. }
  537. }
  538. // for (auto & map : node_map.get_forward_map()) {
  539. // std::cout << map << ", ";
  540. // }
  541. // std::cout << endl;
  542. // for (auto & map : node_map.get_backward_map()) {
  543. // std::cout << map << ", ";
  544. // }
  545. env_->compute_induced_cost(g_id, h_id, node_map);
  546. return node_map.induced_cost();
  547. }
  548. // double PyGEDEnv::getNodeCost(std::size_t label1, std::size_t label2) const {
  549. // return env_->ged_data_node_cost(label1, label2);
  550. // }
  551. /*void medianLetter(pathFolder, pathXML, editCost, method, options="", initOption = "EAGER_WITHOUT_SHUFFLED_COPIES") {
  552. if(isInitialized()) {
  553. restartEnv();
  554. }
  555. setEditCost(editCost);*/
  556. /*std::string letter_class("A");
  557. if (argc > 1) {
  558. letter_class = std::string(argv[1]);
  559. }*/
  560. //std::string seed("0");
  561. /*if (argc > 2) {
  562. seed = std::string(argv[2]);
  563. }*/
  564. /*loadGXLGraph(pathFolder, pathXML);
  565. std::vector<std::size_t> graph_ids = getAllGraphIds();
  566. std::size_t median_id = env_->add_graph("median", "");
  567. initEnv(initOption);
  568. setMethod(method);
  569. ged::MedianGraphEstimator<ged::GXLNodeID, ged::GXLLabel, ged::GXLLabel> median_estimator(&env, false);
  570. median_estimator.set_options("--init-type RANDOM --randomness PSEUDO --seed " + seed);
  571. median_estimator.run(graph_ids, median_id);
  572. std::string gxl_file_name("../output/gen_median_Letter_HIGH_" + letter_class + ".gxl");
  573. env_->save_as_gxl_graph(median_id, gxl_file_name);*/
  574. /*std::string tikz_file_name("../output/gen_median_Letter_HIGH_" + letter_class + ".tex");
  575. save_letter_graph_as_tikz_file(env_->get_graph(median_id), tikz_file_name);*/
  576. //}
  577. }
  578. #endif /* SRC_GEDLIB_BIND_IPP */
  579. // namespace shapes {
  580. // // Default constructor
  581. // Rectangle::Rectangle () {}
  582. // // Overloaded constructor
  583. // Rectangle::Rectangle (int x0, int y0, int x1, int y1) {
  584. // this->x0 = x0;
  585. // this->y0 = y0;
  586. // this->x1 = x1;
  587. // this->y1 = y1;
  588. // }
  589. // // Destructor
  590. // Rectangle::~Rectangle () {}
  591. // // Return the area of the rectangle
  592. // int Rectangle::getArea () {
  593. // return (this->x1 - this->x0) * (this->y1 - this->y0);
  594. // }
  595. // // Get the size of the rectangle.
  596. // // Put the size in the pointer args
  597. // void Rectangle::getSize (int *width, int *height) {
  598. // (*width) = x1 - x0;
  599. // (*height) = y1 - y0;
  600. // }
  601. // // Move the rectangle by dx dy
  602. // void Rectangle::move (int dx, int dy) {
  603. // this->x0 += dx;
  604. // this->y0 += dy;
  605. // this->x1 += dx;
  606. // this->y1 += dy;
  607. // }
  608. // }

A Python package for graph kernels, graph edit distances and graph pre-image problem.