GEDLIB  1.0
ged_data.ipp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * Copyright (C) 2018 by David B. Blumenthal *
4  * *
5  * This file is part of GEDLIB. *
6  * *
7  * GEDLIB is free software: you can redistribute it and/or modify it *
8  * under the terms of the GNU Lesser General Public License as published *
9  * by the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * GEDLIB is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU Lesser General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU Lesser General Public *
18  * License along with GEDLIB. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 
27 #ifndef SRC_ENV_GED_DATA_IPP_
28 #define SRC_ENV_GED_DATA_IPP_
29 
30 namespace ged {
31 
32 template<class UserNodeLabel, class UserEdgeLabel>
33 GEDData<UserNodeLabel, UserEdgeLabel>::
34 GEDData() :
35 graphs_(),
36 graph_names_(),
37 graph_classes_(),
38 num_graphs_without_shuffled_copies_{0},
39 strings_to_internal_node_ids_(),
40 internal_node_ids_to_strings_(),
41 edit_costs_{nullptr},
42 node_costs_(),
43 edge_costs_(),
44 node_labels_(),
45 edge_labels_(),
47 delete_edit_costs_{true},
48 max_num_nodes_{0},
49 max_num_edges_{0} {}
50 
51 template<class UserNodeLabel, class UserEdgeLabel>
54  if (delete_edit_costs_) {
55  delete edit_costs_;
56  }
57 }
58 
59 template<class UserNodeLabel, class UserEdgeLabel>
60 void
62 set_edit_costs_(Options::EditCosts edit_costs, const std::vector<double> & edit_cost_constants) {
63  if (delete_edit_costs_) {
64  delete edit_costs_;
65  }
66  switch (edit_costs) {
68  if (edit_cost_constants.size() == 6) {
69  edit_costs_ = new Constant<UserNodeLabel, UserEdgeLabel>(edit_cost_constants.at(0), edit_cost_constants.at(1), edit_cost_constants.at(2), edit_cost_constants.at(3), edit_cost_constants.at(4), edit_cost_constants.at(5));
70  }
71  else if (edit_cost_constants.size() == 0) {
72  edit_costs_ = new Constant<UserNodeLabel, UserEdgeLabel>();
73  }
74  else {
75  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::CONSTANT. Expected: 6 or 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
76  }
77  break;
78  default:
79  throw Error("Selected edit costs unavailable for template parameters UserNodeLabel = " + std::string(typeid(UserNodeLabel).name()) + " and UserEdgeLabel = " + std::string(typeid(UserEdgeLabel).name()) + ".");
80  }
81  delete_edit_costs_ = true;
82 }
83 
84 template<>
85 void
87 set_edit_costs_(Options::EditCosts edit_costs, const std::vector<double> & edit_cost_constants) {
88  if (delete_edit_costs_) {
89  delete edit_costs_;
90  }
91  switch (edit_costs) {
93  if (edit_cost_constants.size() == 4) {
94  edit_costs_ = new CHEM1<GXLLabel, GXLLabel>(edit_cost_constants.at(0), edit_cost_constants.at(1), edit_cost_constants.at(2), edit_cost_constants.at(3));
95  }
96  else if (edit_cost_constants.size() == 0) {
97  edit_costs_ = new CHEM1<GXLLabel, GXLLabel>();
98  }
99  else {
100  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::CHEM_1. Expected: 4 or 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
101  }
102  break;
104  if (edit_cost_constants.size() == 3) {
105  edit_costs_ = new CHEM2<GXLLabel, GXLLabel>(edit_cost_constants.at(0), edit_cost_constants.at(1), edit_cost_constants.at(2));
106  }
107  else if (edit_cost_constants.size() == 0) {
108  edit_costs_ = new CHEM2<GXLLabel, GXLLabel>();
109  }
110  else {
111  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::CHEM_2. Expected: 3 or 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
112  }
113  break;
115  if (edit_cost_constants.size() == 0) {
116  edit_costs_ = new GREC1<GXLLabel, GXLLabel>();
117  }
118  else {
119  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::GREC_1. Expected: 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
120  }
121  break;
123  if (edit_cost_constants.size() == 3) {
124  edit_costs_ = new GREC2<GXLLabel, GXLLabel>(edit_cost_constants.at(0), edit_cost_constants.at(1), edit_cost_constants.at(2));
125  }
126  else if (edit_cost_constants.size() == 0) {
127  edit_costs_ = new GREC2<GXLLabel, GXLLabel>();
128  }
129  else {
130  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::GREC_2. Expected: 3 or 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
131  }
132  break;
134  if (edit_cost_constants.size() == 3) {
135  edit_costs_ = new Protein<GXLLabel, GXLLabel>(edit_cost_constants.at(0), edit_cost_constants.at(1), edit_cost_constants.at(2));
136  }
137  else if (edit_cost_constants.size() == 0) {
138  edit_costs_ = new Protein<GXLLabel, GXLLabel>();
139  }
140  else {
141  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::PROTEIN. Expected: 3 or 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
142  }
143  break;
145  if (edit_cost_constants.size() == 3) {
146  edit_costs_ = new Fingerprint<GXLLabel, GXLLabel>(edit_cost_constants.at(0), edit_cost_constants.at(1), edit_cost_constants.at(2));
147  }
148  else if (edit_cost_constants.size() == 0) {
149  edit_costs_ = new Fingerprint<GXLLabel, GXLLabel>();
150  }
151  else {
152  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::FINGERPRINT. Expected: 3 or 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
153  }
154  break;
156  if (edit_cost_constants.size() == 3) {
157  edit_costs_ = new Letter<GXLLabel, GXLLabel>(edit_cost_constants.at(0), edit_cost_constants.at(1), edit_cost_constants.at(2));
158  }
159  else if (edit_cost_constants.size() == 0) {
160  edit_costs_ = new Letter<GXLLabel, GXLLabel>();
161  }
162  else {
163  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::LETTER. Expected: 3 or 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
164  }
165  break;
167  if (edit_cost_constants.size() == 2) {
168  edit_costs_ = new CMU<GXLLabel, GXLLabel>(edit_cost_constants.at(0), edit_cost_constants.at(2));
169  }
170  else if (edit_cost_constants.size() == 0) {
171  edit_costs_ = new CMU<GXLLabel, GXLLabel>();
172  }
173  else {
174  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::CMU. Expected: 2 or 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
175  }
176  break;
178  if (edit_cost_constants.size() == 6) {
179  edit_costs_ = new Constant<GXLLabel, GXLLabel>(edit_cost_constants.at(0), edit_cost_constants.at(1), edit_cost_constants.at(2), edit_cost_constants.at(3), edit_cost_constants.at(4), edit_cost_constants.at(5));
180  }
181  else if (edit_cost_constants.size() == 0) {
182  edit_costs_ = new Constant<GXLLabel, GXLLabel>();
183  }
184  else {
185  throw Error("Wrong number of constants for selected edit costs ged::Options::EditCosts::CONSTANT. Expected: 6 or 0; actual: " + std::to_string(edit_cost_constants.size()) + ".");
186  }
187  break;
188  }
189  delete_edit_costs_ = true;
190 }
191 
192 template<class UserNodeLabel, class UserEdgeLabel>
193 void
196  if (delete_edit_costs_) {
197  delete edit_costs_;
198  }
199  edit_costs_ = edit_costs;
200  delete_edit_costs_ = false;
201 }
202 
203 template<class UserNodeLabel, class UserEdgeLabel>
204 LabelID
206 node_label_to_id_(const UserNodeLabel & node_label) {
207  LabelID id {0};
208  for (auto itr = node_labels_.begin(); itr != node_labels_.end(); itr++) {
209  if (*itr == node_label) return (id + 1);
210  id++;
211  }
212  node_labels_.push_back(node_label);
213  return (id + 1);
214 }
215 
216 template<class UserNodeLabel, class UserEdgeLabel>
217 UserNodeLabel
219 id_to_node_label(LabelID label_id) const {
220  if ((label_id > node_labels_.size()) or (label_id == 0)) {
221  throw Error("Invalid node label ID " + std::to_string(label_id) + ".");
222  }
223  return node_labels_.at(label_id - 1);
224 }
225 
226 template<class UserNodeLabel, class UserEdgeLabel>
227 LabelID
229 edge_label_to_id_(const UserEdgeLabel & edge_label) {
230  LabelID id {0};
231  for (auto itr = edge_labels_.begin(); itr != edge_labels_.end(); itr++) {
232  if (*itr == edge_label) return (id + 1);
233  id++;
234  }
235  edge_labels_.push_back(edge_label);
236  return (id + 1);
237 }
238 
239 template<class UserNodeLabel, class UserEdgeLabel>
240 UserEdgeLabel
242 id_to_edge_label(LabelID label_id) const {
243  if ((label_id > edge_labels_.size()) or (label_id == 0)) {
244  throw Error("Invalid edge label ID " + std::to_string(label_id) + ".");
245  }
246  return edge_labels_.at(label_id - 1);
247 }
248 
249 template<class UserNodeLabel, class UserEdgeLabel>
250 bool
252 eager_init_() const {
254 }
255 
256 template<class UserNodeLabel, class UserEdgeLabel>
257 void
260 
261  // Update node cost matrix if new node labels have been added to the environment.
262  std::size_t size_old_node_costs = node_costs_.num_rows();
263  if (size_old_node_costs < node_labels_.size() + 1) {
264  DMatrix old_node_costs(node_costs_);
265  node_costs_.resize(node_labels_.size() + 1, node_labels_.size() + 1);
266  for (LabelID l_id_lhs = 0; l_id_lhs < node_labels_.size() + 1; l_id_lhs++) {
267  for (LabelID l_id_rhs = 0; l_id_rhs < node_labels_.size() + 1; l_id_rhs++) {
268  if (l_id_lhs < size_old_node_costs and l_id_rhs < size_old_node_costs) {
269  node_costs_(l_id_lhs, l_id_rhs) = old_node_costs(l_id_lhs, l_id_rhs);
270  }
271  else if (l_id_lhs == l_id_rhs) {
272  node_costs_(l_id_lhs, l_id_rhs) = 0.0;
273  }
274  else if (l_id_lhs == dummy_label()) {
275  node_costs_(l_id_lhs, l_id_rhs) = edit_costs_->node_ins_cost_fun(node_labels_.at(l_id_rhs - 1));
276  }
277  else if (l_id_rhs == dummy_label()) {
278  node_costs_(l_id_lhs, l_id_rhs) = edit_costs_->node_del_cost_fun(node_labels_.at(l_id_lhs - 1));
279  }
280  else {
281  node_costs_(l_id_lhs, l_id_rhs) = edit_costs_->node_rel_cost_fun(node_labels_.at(l_id_lhs - 1), node_labels_.at(l_id_rhs - 1));
282  }
283  }
284  }
285  }
286 
287  // Update edge cost matrix if new edge labels have been added to the environment.
288  std::size_t size_old_edge_costs = edge_costs_.num_rows();
289  if (size_old_edge_costs < edge_labels_.size() + 1) {
290  DMatrix old_edge_costs(edge_costs_);
291  edge_costs_.resize(edge_labels_.size() + 1, edge_labels_.size() + 1);
292  for (LabelID l_id_lhs = 0; l_id_lhs < edge_labels_.size() + 1; l_id_lhs++) {
293  for (LabelID l_id_rhs = 0; l_id_rhs < edge_labels_.size() + 1; l_id_rhs++) {
294  if (l_id_lhs < size_old_edge_costs and l_id_rhs < size_old_edge_costs) {
295  edge_costs_(l_id_lhs, l_id_rhs) = old_edge_costs(l_id_lhs, l_id_rhs);
296  }
297  else if (l_id_lhs == l_id_rhs) {
298  edge_costs_(l_id_lhs, l_id_rhs) = 0.0;
299  }
300  else if (l_id_lhs == dummy_label()) {
301  edge_costs_(l_id_lhs, l_id_rhs) = edit_costs_->edge_ins_cost_fun(edge_labels_.at(l_id_rhs - 1));
302  }
303  else if (l_id_rhs == dummy_label()) {
304  edge_costs_(l_id_lhs, l_id_rhs) = edit_costs_->edge_del_cost_fun(edge_labels_.at(l_id_lhs - 1));
305  }
306  else {
307  edge_costs_(l_id_lhs, l_id_rhs) = edit_costs_->edge_rel_cost_fun(edge_labels_.at(l_id_lhs - 1), edge_labels_.at(l_id_rhs - 1));
308  }
309  }
310  }
311  }
312 
313 }
314 
315 template<class UserNodeLabel, class UserEdgeLabel>
316 std::size_t
318 num_graphs() const {
319  return graphs_.size();
320 }
321 
322 template<class UserNodeLabel, class UserEdgeLabel>
323 const GEDGraph &
325 graph(GEDGraph::GraphID graph_id) const {
326  return graphs_.at(graph_id);
327 }
328 
329 template<class UserNodeLabel, class UserEdgeLabel>
332 string_to_node_id_(GEDGraph::GraphID graph_id, const std::string & string) const {
333  if (string == "DUMMY") {
334  return GEDGraph::dummy_node();
335  }
336  return strings_to_internal_node_ids_.at(graph_id).at(string);
337 }
338 
339 template<class UserNodeLabel, class UserEdgeLabel>
340 std::string
342 node_id_to_string_(GEDGraph::GraphID graph_id, GEDGraph::NodeID node_id) const {
343  if (node_id == GEDGraph::dummy_node()) {
344  return "DUMMY";
345  }
346  return internal_node_ids_to_strings_.at(graph_id).at(node_id);
347 }
348 
349 template<class UserNodeLabel, class UserEdgeLabel>
350 bool
354 }
355 
356 template<class UserNodeLabel, class UserEdgeLabel>
357 std::size_t
360  return num_graphs_without_shuffled_copies_;
361 }
362 
363 template<class UserNodeLabel, class UserEdgeLabel>
368  throw Error("No shuffled copy available.");
369  }
370  if (graph_id >= num_graphs_without_shuffled_copies()) {
371  return (graph_id - num_graphs_without_shuffled_copies());
372  }
373  return (graph_id + num_graphs_without_shuffled_copies());
374 }
375 
376 template<class UserNodeLabel, class UserEdgeLabel>
377 bool
380  return (graph_id >= num_graphs_without_shuffled_copies());
381 }
382 
383 template<class UserNodeLabel, class UserEdgeLabel>
384 std::vector<GEDGraph>::const_iterator
386 begin() const {
387  return graphs_.cbegin();
388 }
389 
390 template<class UserNodeLabel, class UserEdgeLabel>
391 std::vector<GEDGraph>::const_iterator
393 end() const {
394  return graphs_.cend();
395 }
396 
397 template<class UserNodeLabel, class UserEdgeLabel>
398 std::size_t
401  return node_costs_.num_rows();
402 }
403 
404 template<class UserNodeLabel, class UserEdgeLabel>
405 std::size_t
408  return edge_costs_.num_rows();
409 }
410 
411 template<class UserNodeLabel, class UserEdgeLabel>
412 std::size_t
414 max_num_nodes() const {
415  return max_num_nodes_;
416 }
417 
418 template<class UserNodeLabel, class UserEdgeLabel>
419 std::size_t
421 max_num_edges() const {
422  return max_num_edges_;
423 }
424 
425 template<class UserNodeLabel, class UserEdgeLabel>
426 double
428 edge_cost(LabelID label1, LabelID label2) const {
429  if (eager_init_()) {
430  return edge_costs_(label1, label2);
431  }
432  if (label1 == label2) {
433  return 0.0;
434  }
435  if (label1 == dummy_label()) {
436  return edit_costs_->edge_ins_cost_fun(edge_labels_.at(label2 - 1));
437  }
438  if (label2 == dummy_label()) {
439  return edit_costs_->edge_del_cost_fun(edge_labels_.at(label1 - 1));
440  }
441  return edit_costs_->edge_rel_cost_fun(edge_labels_.at(label1 - 1), edge_labels_.at(label2 - 1));
442 }
443 
444 template<class UserNodeLabel, class UserEdgeLabel>
445 void
447 vectorize_edge_label(LabelID edge_label, std::vector<double> & vector_representation) const {
448  edit_costs_->vectorize_edge_label(edge_labels_.at(edge_label - 1), vector_representation);
449 }
450 
451 template<class UserNodeLabel, class UserEdgeLabel>
452 double
454 node_cost(LabelID label1, LabelID label2) const {
455  if (eager_init_()) {
456  return node_costs_(label1, label2);
457  }
458  if (label1 == label2) {
459  return 0.0;
460  }
461  if (label1 == dummy_label()) {
462  return edit_costs_->node_ins_cost_fun(node_labels_.at(label2 - 1));
463  }
464  if (label2 == dummy_label()) {
465  return edit_costs_->node_del_cost_fun(node_labels_.at(label1 - 1));
466  }
467  return edit_costs_->node_rel_cost_fun(node_labels_.at(label1 - 1), node_labels_.at(label2 - 1));
468 }
469 
470 template<class UserNodeLabel, class UserEdgeLabel>
471 void
473 vectorize_node_label(LabelID node_label, std::vector<double> & vector_representation) const {
474  edit_costs_->vectorize_node_label(node_labels_.at(node_label - 1), vector_representation);
475 }
476 
477 template<class UserNodeLabel, class UserEdgeLabel>
478 void
480 save_node_map(const std::string & filename, GEDGraph::NodeID g_id, GEDGraph::NodeID h_id, const NodeMap & node_map, bool append) const {
481  std::ofstream ofs;
482  if (append) {
483  ofs.open(filename, std::ofstream::out | std::ofstream::app);
484  }
485  else {
486  ofs.open(filename, std::ofstream::out);
487  }
488  ofs << graph_names_.at(g_id) << " " << graph_names_.at(h_id);
489  std::vector<NodeMap::Assignment> relation;
490  node_map.as_relation(relation);
491  for (const auto & assignment : relation) {
492  ofs << " " << node_id_to_string_(g_id, assignment.first) << "," << node_id_to_string_(h_id, assignment.second);
493  }
494  ofs << "\n";
495  ofs.close();
496 }
497 
498 template<class UserNodeLabel, class UserEdgeLabel>
499 void
501 load_node_map(const std::string & filename, GEDGraph::NodeID g_id, GEDGraph::NodeID h_id, NodeMap & node_map) const {
502  std::string prefix(graph_names_.at(g_id) + " " + graph_names_.at(h_id) + " ");
503  std::ifstream ifs(filename);
504  if (not ifs.good()) {
505  throw Error("Loading node map from file " + filename + " failed. File cannot be opened.");
506  }
507  std::string line;
508  bool contains_node_map{false};
509  while(std::getline(ifs, line)) {
510  auto res = std::mismatch(prefix.begin(), prefix.end(), line.begin());
511  if (res.first == prefix.end()) {
512  contains_node_map = true;
513  line = line.substr(prefix.size());
514  break;
515  }
516  }
517  ifs.close();
518  if (not contains_node_map) {
519  throw Error("Loading node map from file " + filename + " failed. File does not contain a node map between the graphs " + graph_names_.at(g_id) + " and " + graph_names_.at(h_id) + ".");
520  }
521  std::istringstream line_stream(line);
522  std::string assignment;
523  std::string node_in_g;
524  std::string node_in_h;
525  while (std::getline(line_stream, assignment, ' ')) {
526  std::istringstream assignment_stream(assignment);
527  if (not std::getline(assignment_stream, node_in_g, ',')) {
528  throw Error("Loading node map from file " + filename + " failed. File has the wrong format. Expected format of lines: \"<graph name 1> <graph name 2> [<original node ID 1>,<original node ID 2>] [...]\"");
529  }
530  if (not std::getline(assignment_stream, node_in_h, ',')) {
531  throw Error("Loading node map from file " + filename + " failed. File has the wrong format. Expected format of lines: \"<graph name 1> <graph name 2> [<original node ID 1>,<original node ID 2>] [...]\"");
532  }
533  node_map.add_assignment(string_to_node_id_(g_id, node_in_g), string_to_node_id_(h_id, node_in_h));
534  }
535 }
536 
537 template<class UserNodeLabel, class UserEdgeLabel>
538 void
540 compute_induced_cost(const GEDGraph & g, const GEDGraph & h, NodeMap & node_map) const {
541  double cost{0.0};
542 
543  // collect node costs
544  for (auto node = g.nodes().first; node != g.nodes().second; node++) {
545  cost += node_cost(g.get_node_label(*node), h.get_node_label(node_map.image(*node)));
546  }
547  for (auto node = h.nodes().first; node != h.nodes().second; node++) {
548  GEDGraph::NodeID pre_image{node_map.pre_image(*node)};
549  if (pre_image == GEDGraph::dummy_node()) {
550  cost += node_cost(g.get_node_label(pre_image), h.get_node_label(*node));
551  }
552  }
553 
554  // collect edge costs
555  for (auto ij = g.edges().first; ij != g.edges().second; ij++) {
556  cost += edge_cost(g.get_edge_label(*ij), h.get_edge_label(node_map.image(g.tail(*ij)), node_map.image(g.head(*ij))));
557  }
558  for (auto kl = h.edges().first; kl != h.edges().second; kl++) {
559  if (not g.is_edge(node_map.pre_image(h.tail(*kl)), node_map.pre_image(h.head(*kl)))) {
560  cost += edge_cost(dummy_label(), h.get_edge_label(*kl));
561  }
562  }
563 
564  node_map.set_induced_cost(cost);
565 }
566 
567 template<class UserNodeLabel, class UserEdgeLabel>
568 double
570 swap_cost(const GEDGraph & g, const GEDGraph & h, const NodeMap::Assignment & assignment_1, const NodeMap::Assignment & assignment_2, NodeMap & node_map) const {
571 
572  // Get the nodes involved in the swap: {(i,k), (j,l)} -> {(i,l), (j,k)}.
573  GEDGraph::NodeID i{assignment_1.first};
574  GEDGraph::NodeID k{assignment_1.second};
575  GEDGraph::NodeID j{assignment_2.first};
576  GEDGraph::NodeID l{assignment_2.second};
577 
578  // Collect edges that are incident with i or j in g.
579  std::vector<GEDGraph::EdgeID> incident_edges_i_j;
580  if (i != GEDGraph::dummy_node()) {
581  for (auto edge = g.incident_edges(i).first; edge != g.incident_edges(i).second; edge++) {
582  if (g.head(*edge) != j) {
583  incident_edges_i_j.push_back(*edge);
584  }
585  }
586  }
587  if (j != GEDGraph::dummy_node()) {
588  for (auto edge = g.incident_edges(j).first; edge != g.incident_edges(j).second; edge++) {
589  if (g.head(*edge) != i) {
590  incident_edges_i_j.push_back(*edge);
591  }
592  }
593  }
594 
595  // Collect edges that are incident with k or l in h.
596  std::vector<GEDGraph::EdgeID> incident_edges_k_l;
597  if (k != GEDGraph::dummy_node()) {
598  for (auto edge = h.incident_edges(k).first; edge != h.incident_edges(k).second; edge++) {
599  if (h.head(*edge) != l) {
600  incident_edges_k_l.push_back(*edge);
601  }
602  }
603  }
604  if (l != GEDGraph::dummy_node()) {
605  for (auto edge = h.incident_edges(l).first; edge != h.incident_edges(l).second; edge++) {
606  if (h.head(*edge) != k) {
607  incident_edges_k_l.push_back(*edge);
608  }
609  }
610  }
611 
612  // Compute swap cost.
613  double delta{0.0};
614 
615  // Compute node cost delta.
616  delta -= node_cost(g.get_node_label(i), h.get_node_label(k));
617  delta -= node_cost(g.get_node_label(j), h.get_node_label(l));
618  delta += node_cost(g.get_node_label(i), h.get_node_label(l));
619  delta += node_cost(g.get_node_label(j), h.get_node_label(k));
620 
621  // Compute negative part of edge cost delta.
622  for (const auto & edge : incident_edges_i_j) {
623  delta -= edge_cost(g.get_edge_label(edge), h.get_edge_label(node_map.image(g.tail(edge)), node_map.image(g.head(edge))));
624  }
625  for (const auto & edge : incident_edges_k_l) {
626  if (not g.is_edge(node_map.pre_image(h.tail(edge)), node_map.pre_image(h.head(edge)))) {
627  delta -= edge_cost(dummy_label(), h.get_edge_label(edge));
628  }
629  }
630 
631  // Carry out the swap.
632  node_map.add_assignment(i, l);
633  node_map.add_assignment(j, k);
634 
635  // Compute positive part of edge cost delta.
636  for (const auto & edge : incident_edges_i_j) {
637  delta += edge_cost(g.get_edge_label(edge), h.get_edge_label(node_map.image(g.tail(edge)), node_map.image(g.head(edge))));
638  }
639  for (const auto & edge : incident_edges_k_l) {
640  if (not g.is_edge(node_map.pre_image(h.tail(edge)), node_map.pre_image(h.head(edge)))) {
641  delta += edge_cost(dummy_label(), h.get_edge_label(edge));
642  }
643  }
644 
645  // Undo the swap.
646  node_map.add_assignment(i, k);
647  node_map.add_assignment(j, l);
648 
649  // Return the overall swap cost.
650  return delta;
651 }
652 
653 template<class UserNodeLabel, class UserEdgeLabel>
654 void
656 swap_assignments(const NodeMap::Assignment & assignment_1, const NodeMap::Assignment & assignment_2, double swap_cost, NodeMap & node_map) const {
657 
658  // Carry out the swap.
659  node_map.add_assignment(assignment_1.first, assignment_2.second);
660  node_map.add_assignment(assignment_2.first, assignment_1.second);
661 
662  // Update the induced cost of the node map.
663  node_map.set_induced_cost(node_map.induced_cost() + swap_cost);
664 }
665 
666 template<class UserNodeLabel, class UserEdgeLabel>
667 bool
670  for (std::size_t label_1{1}; label_1 < num_node_labels(); label_1++) {
671  for (std::size_t label_2{1}; label_2 < num_node_labels(); label_2++) {
672  if (node_cost(label_1, label_2) > node_cost(label_1, ged::dummy_label()) + node_cost(ged::dummy_label(), label_2)) {
673  return false;
674  }
675  }
676  }
677  for (std::size_t label_1{1}; label_1 < num_edge_labels(); label_1++) {
678  for (std::size_t label_2{1}; label_2 < num_edge_labels(); label_2++) {
679  if (edge_cost(label_1, label_2) > edge_cost(label_1, ged::dummy_label()) + edge_cost(ged::dummy_label(), label_2)) {
680  return false;
681  }
682  }
683  }
684  return true;
685 }
686 
687 template<class UserNodeLabel, class UserEdgeLabel>
688 bool
690 quasimetric_costs(const GEDGraph & g, const GEDGraph & h) const {
691  std::vector<LabelID> node_labels_g;
692  for (auto node = g.nodes().first; node != g.nodes().second; node++) {
693  node_labels_g.push_back(g.get_node_label(*node));
694  }
695  std::vector<LabelID> node_labels_h;
696  for (auto node = h.nodes().first; node != h.nodes().second; node++) {
697  node_labels_h.push_back(h.get_node_label(*node));
698  }
699  std::vector<LabelID> edge_labels_g;
700  for (auto edge = g.edges().first; edge != g.edges().second; edge++) {
701  edge_labels_g.push_back(g.get_edge_label(*edge));
702  }
703  std::vector<LabelID> edge_labels_h;
704  for (auto edge = h.edges().first; edge != h.edges().second; edge++) {
705  edge_labels_h.push_back(h.get_edge_label(*edge));
706  }
707  for (auto label_1 : node_labels_g) {
708  for (auto label_2 : node_labels_h) {
709  if (node_cost(label_1, label_2) > node_cost(label_1, ged::dummy_label()) + node_cost(ged::dummy_label(), label_2)) {
710  return false;
711  }
712  }
713  }
714  for (auto label_1 : edge_labels_g) {
715  for (auto label_2 : edge_labels_h) {
716  if (edge_cost(label_1, label_2) > edge_cost(label_1, ged::dummy_label()) + edge_cost(ged::dummy_label(), label_2)) {
717  return false;
718  }
719  }
720  }
721  return true;
722 }
723 
724 template<class UserNodeLabel, class UserEdgeLabel>
725 double
728  if (eager_init_()) {
729  return node_costs_.max();
730  }
731  double max_cost{std::numeric_limits<double>::min()};
732  for (LabelID label_1{0}; label_1 < num_node_labels(); label_1++) {
733  for (LabelID label_2{0}; label_2 < num_node_labels(); label_2++) {
734  max_cost = std::max(max_cost, node_cost(label_1, label_2));
735  }
736  }
737  return max_cost;
738 }
739 
740 template<class UserNodeLabel, class UserEdgeLabel>
741 double
744  double max_cost{std::numeric_limits<double>::min()};
745  for (auto node = graph.nodes().first; node != graph.nodes().second; node++) {
746  max_cost = std::max(max_cost, node_cost(graph.get_node_label(*node), dummy_label()));
747  }
748  return max_cost;
749 }
750 
751 template<class UserNodeLabel, class UserEdgeLabel>
752 double
755  double min_cost{std::numeric_limits<double>::max()};
756  for (auto node = graph.nodes().first; node != graph.nodes().second; node++) {
757  min_cost = std::min(min_cost, node_cost(graph.get_node_label(*node), dummy_label()));
758  }
759  return min_cost;
760 }
761 
762 template<class UserNodeLabel, class UserEdgeLabel>
763 double
766  if (graph.num_nodes() == 0) {
767  return 0.0;
768  }
769  double mean_cost{0.0};
770  for (auto node = graph.nodes().first; node != graph.nodes().second; node++) {
771  mean_cost += node_cost(graph.get_node_label(*node), dummy_label());
772  }
773  return mean_cost / static_cast<double>(graph.num_nodes());
774 }
775 
776 template<class UserNodeLabel, class UserEdgeLabel>
777 double
780  double max_cost{std::numeric_limits<double>::min()};
781  for (auto node = graph.nodes().first; node != graph.nodes().second; node++) {
782  max_cost = std::max(max_cost, node_cost(dummy_label(), graph.get_node_label(*node)));
783  }
784  return max_cost;
785 }
786 
787 template<class UserNodeLabel, class UserEdgeLabel>
788 double
791  double min_cost{std::numeric_limits<double>::max()};
792  for (auto node = graph.nodes().first; node != graph.nodes().second; node++) {
793  min_cost = std::min(min_cost, node_cost(dummy_label(), graph.get_node_label(*node)));
794  }
795  return min_cost;
796 }
797 
798 template<class UserNodeLabel, class UserEdgeLabel>
799 double
802  if (graph.num_nodes() == 0) {
803  return 0.0;
804  }
805  double mean_cost{0.0};
806  for (auto node = graph.nodes().first; node != graph.nodes().second; node++) {
807  mean_cost += node_cost(dummy_label(), graph.get_node_label(*node));
808  }
809  return mean_cost / static_cast<double>(graph.num_nodes());
810 }
811 
812 template<class UserNodeLabel, class UserEdgeLabel>
813 double
815 max_node_subs_cost(const GEDGraph & g, const GEDGraph & h) const {
816  double max_cost{std::numeric_limits<double>::min()};
817  for (auto node_g = g.nodes().first; node_g != g.nodes().second; node_g++) {
818  for (auto node_h = h.nodes().first; node_h != h.nodes().second; node_h++) {
819  max_cost = std::max(max_cost, node_cost(g.get_node_label(*node_g), h.get_node_label(*node_h)));
820  }
821  }
822  return max_cost;
823 }
824 
825 template<class UserNodeLabel, class UserEdgeLabel>
826 double
828 min_node_subs_cost(const GEDGraph & g, const GEDGraph & h) const {
829  double min_cost{std::numeric_limits<double>::max()};
830  for (auto node_g = g.nodes().first; node_g != g.nodes().second; node_g++) {
831  for (auto node_h = h.nodes().first; node_h != h.nodes().second; node_h++) {
832  if (g.get_node_label(*node_g) != h.get_node_label(*node_h)) {
833  min_cost = std::min(min_cost, node_cost(g.get_node_label(*node_g), h.get_node_label(*node_h)));
834  }
835  }
836  }
837  return min_cost;
838 }
839 
840 template<class UserNodeLabel, class UserEdgeLabel>
841 double
843 mean_node_subs_cost(const GEDGraph & g, const GEDGraph & h) const {
844  if (g.num_nodes() * h.num_nodes() == 0) {
845  return 0.0;
846  }
847  double mean_cost{0.0};
848  for (auto node_g = g.nodes().first; node_g != g.nodes().second; node_g++) {
849  for (auto node_h = h.nodes().first; node_h != h.nodes().second; node_h++) {
850  mean_cost += node_cost(g.get_node_label(*node_g), h.get_node_label(*node_h));
851  }
852  }
853  return mean_cost / static_cast<double>(g.num_nodes() * h.num_nodes());
854 }
855 
856 template<class UserNodeLabel, class UserEdgeLabel>
857 double
859 max_edge_subs_cost(const GEDGraph & g, const GEDGraph & h) const {
860  double max_cost{std::numeric_limits<double>::min()};
861  for (auto egde_g = g.edges().first; egde_g != g.edges().second; egde_g++) {
862  for (auto edge_h = h.edges().first; edge_h != h.edges().second; edge_h++) {
863  max_cost = std::max(max_cost, edge_cost(g.get_edge_label(*egde_g), h.get_edge_label(*edge_h)));
864  }
865  }
866  return max_cost;
867 }
868 
869 template<class UserNodeLabel, class UserEdgeLabel>
870 double
872 min_edge_subs_cost(const GEDGraph & g, const GEDGraph & h) const {
873  double min_cost{std::numeric_limits<double>::max()};
874  for (auto egde_g = g.edges().first; egde_g != g.edges().second; egde_g++) {
875  for (auto edge_h = h.edges().first; edge_h != h.edges().second; edge_h++) {
876  if (g.get_edge_label(*egde_g) != h.get_edge_label(*edge_h)) {
877  min_cost = std::min(min_cost, edge_cost(g.get_edge_label(*egde_g), h.get_edge_label(*edge_h)));
878  }
879  }
880  }
881  return min_cost;
882 }
883 
884 template<class UserNodeLabel, class UserEdgeLabel>
885 double
887 mean_edge_subs_cost(const GEDGraph & g, const GEDGraph & h) const {
888  if (g.num_edges() * h.num_edges() == 0) {
889  return 0.0;
890  }
891  double mean_cost{0.0};
892  for (auto edge_g = g.edges().first; edge_g != g.edges().second; edge_g++) {
893  for (auto edge_h = h.edges().first; edge_h != h.edges().second; edge_h++) {
894  mean_cost += edge_cost(g.get_edge_label(*edge_g), h.get_edge_label(*edge_h));
895  }
896  }
897  return mean_cost / static_cast<double>(g.num_edges() * h.num_edges());
898 }
899 
900 template<class UserNodeLabel, class UserEdgeLabel>
901 double
904  if (eager_init_()) {
905  return edge_costs_.max();
906  }
907  double max_cost{std::numeric_limits<double>::min()};
908  for (LabelID label_1{0}; label_1 < num_edge_labels(); label_1++) {
909  for (LabelID label_2{0}; label_2 < num_edge_labels(); label_2++) {
910  max_cost = std::max(max_cost, edge_cost(label_1, label_2));
911  }
912  }
913  return max_cost;
914 }
915 
916 template<class UserNodeLabel, class UserEdgeLabel>
917 double
920  double max_cost{std::numeric_limits<double>::min()};
921  for (auto edge = graph.edges().first; edge != graph.edges().second; edge++) {
922  max_cost = std::max(max_cost, edge_cost(graph.get_edge_label(*edge), dummy_label()));
923  }
924  return max_cost;
925 }
926 
927 template<class UserNodeLabel, class UserEdgeLabel>
928 double
931  if (graph.num_edges() == 0) {
932  return 0.0;
933  }
934  double mean_cost{0.0};
935  for (auto edge = graph.edges().first; edge != graph.edges().second; edge++) {
936  mean_cost += edge_cost(graph.get_edge_label(*edge), dummy_label());
937  }
938  return mean_cost / static_cast<double>(graph.num_edges());
939 }
940 
941 template<class UserNodeLabel, class UserEdgeLabel>
942 double
945  double min_cost{std::numeric_limits<double>::max()};
946  for (auto edge = graph.edges().first; edge != graph.edges().second; edge++) {
947  min_cost = std::min(min_cost, edge_cost(graph.get_edge_label(*edge), dummy_label()));
948  }
949  return min_cost;
950 }
951 
952 template<class UserNodeLabel, class UserEdgeLabel>
953 double
956  double max_cost{std::numeric_limits<double>::min()};
957  for (auto edge = graph.edges().first; edge != graph.edges().second; edge++) {
958  max_cost = std::max(max_cost, edge_cost(dummy_label(), graph.get_edge_label(*edge)));
959  }
960  return max_cost;
961 }
962 
963 template<class UserNodeLabel, class UserEdgeLabel>
964 double
967  double min_cost{std::numeric_limits<double>::max()};
968  for (auto edge = graph.edges().first; edge != graph.edges().second; edge++) {
969  min_cost = std::min(min_cost, edge_cost(dummy_label(), graph.get_edge_label(*edge)));
970  }
971  return min_cost;
972 }
973 
974 template<class UserNodeLabel, class UserEdgeLabel>
975 double
978  if (graph.num_edges() == 0) {
979  return 0.0;
980  }
981  double mean_cost{0.0};
982  for (auto edge = graph.edges().first; edge != graph.edges().second; edge++) {
983  mean_cost += edge_cost(dummy_label(), graph.get_edge_label(*edge));
984  }
985  return mean_cost / static_cast<double>(graph.num_edges());
986 }
987 
988 template<class UserNodeLabel, class UserEdgeLabel>
989 double
991 max_edit_cost(const GEDGraph & g, const GEDGraph & h) const {
992  double max_cost{max_edge_del_cost(g)};
993  max_cost = std::max(max_cost, max_edge_ins_cost(h));
994  max_cost = std::max(max_cost, max_edge_subs_cost(g, h));
995  max_cost = std::max(max_cost, max_node_del_cost(g));
996  max_cost = std::max(max_cost, max_node_ins_cost(h));
997  max_cost = std::max(max_cost, max_node_subs_cost(g, h));
998  return max_cost;
999 }
1000 
1001 template<class UserNodeLabel, class UserEdgeLabel>
1002 double
1004 min_edit_cost(const GEDGraph & g, const GEDGraph & h) const {
1005  double min_cost{min_edge_del_cost(g)};
1006  min_cost = std::min(min_cost, min_edge_ins_cost(h));
1007  min_cost = std::min(min_cost, min_edge_subs_cost(g, h));
1008  min_cost = std::min(min_cost, min_node_del_cost(g));
1009  min_cost = std::min(min_cost, min_node_ins_cost(h));
1010  min_cost = std::min(min_cost, min_node_subs_cost(g, h));
1011  return min_cost;
1012 }
1013 
1014 template<class UserNodeLabel, class UserEdgeLabel>
1015 double
1017 max_node_edit_cost(const GEDGraph & g, const GEDGraph & h) const {
1018  double max_cost{max_node_del_cost(g)};
1019  max_cost = std::max(max_cost, max_node_ins_cost(h));
1020  max_cost = std::max(max_cost, max_node_subs_cost(g, h));
1021  return max_cost;
1022 }
1023 
1024 template<class UserNodeLabel, class UserEdgeLabel>
1025 double
1027 min_node_edit_cost(const GEDGraph & g, const GEDGraph & h) const {
1028  double min_cost{min_node_del_cost(g)};
1029  min_cost = std::min(min_cost, min_node_ins_cost(h));
1030  min_cost = std::min(min_cost, min_node_subs_cost(g, h));
1031  return min_cost;
1032 }
1033 
1034 template<class UserNodeLabel, class UserEdgeLabel>
1035 double
1037 max_edge_edit_cost(const GEDGraph & g, const GEDGraph & h) const {
1038  double max_cost{max_edge_del_cost(g)};
1039  max_cost = std::max(max_cost, max_edge_ins_cost(h));
1040  max_cost = std::max(max_cost, max_edge_subs_cost(g, h));
1041  return max_cost;
1042 }
1043 
1044 template<class UserNodeLabel, class UserEdgeLabel>
1045 double
1047 min_edge_edit_cost(const GEDGraph & g, const GEDGraph & h) const {
1048  double min_cost{min_edge_del_cost(g)};
1049  min_cost = std::min(min_cost, min_edge_ins_cost(h));
1050  min_cost = std::min(min_cost, min_edge_subs_cost(g, h));
1051  return min_cost;
1052 }
1053 
1054 }
1055 
1056 #endif /* SRC_ENV_GED_DATA_IPP_ */
std::size_t max_num_nodes() const
Returns maximal number of nodes.
Definition: ged_data.ipp:414
double min_node_subs_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the minimal cost of substituting a node contained in a graph by a node contained in another g...
Definition: ged_data.ipp:828
std::size_t num_nodes() const
Returns the number of nodes.
Definition: ged_graph.ipp:211
~GEDData()
Destructor.
Definition: ged_data.ipp:53
Contains the standardized input data along with basic functionality.
Definition: ged_data.hpp:55
void compute_induced_cost(const GEDGraph &g, const GEDGraph &h, NodeMap &node_map) const
Computes the edit cost between two graphs induced by a node map.
Definition: ged_data.ipp:540
ScalarT max() const
Returns the maximal coefficient.
Definition: matrix.ipp:163
double edge_cost(LabelID label1, LabelID label2) const
Returns edge relabeling, insertion, or deletion cost.
Definition: ged_data.ipp:428
Edit cost functions for the dataset GREC.
Definition: grec_2.hpp:55
Edit cost functions for chemical graphs such as the ones contained in the datasets Mutagenicity...
Definition: chem_1.hpp:51
void as_relation(std::vector< Assignment > &relation) const
Constructs the representation as relation.
Definition: node_map.ipp:164
Selects ged::Fingerprint.
A class for node maps.
Definition: node_map.hpp:43
double node_cost(LabelID label1, LabelID label2) const
Returns node relabeling, insertion, or deletion cost.
Definition: ged_data.ipp:454
void resize(std::size_t num_rows, std::size_t num_cols)
Resizes the matrix.
Definition: matrix.ipp:92
double max_node_ins_cost(const GEDGraph &graph) const
Returns the maximal cost of inserting a node contained in a graph.
Definition: ged_data.ipp:779
std::vector< GEDGraph >::size_type GraphID
Type of internally used graph IDs.
Definition: ged_graph.hpp:112
std::size_t max_num_edges() const
Returns maximal number of nodes.
Definition: ged_data.ipp:421
NodeID head(EdgeID edge) const
Returns the head of an edge.
Definition: ged_graph.ipp:199
Lazy initialization, shuffled graph copies are constructed.
void swap_assignments(const NodeMap::Assignment &assignment_1, const NodeMap::Assignment &assignment_2, double swap_cost, NodeMap &node_map) const
Swaps two assignments in a node map.
Definition: ged_data.ipp:656
bool is_edge(NodeID tail, NodeID head) const
Checks if an edge exists.
Definition: ged_graph.ipp:262
const GEDGraph & graph(GEDGraph::GraphID graph_id) const
Provides access to a graph.
Definition: ged_data.ipp:325
void vectorize_edge_label(LabelID edge_label, std::vector< double > &vector_representation) const
Computes an edge label&#39;s representation as a real-valued vector.
Definition: ged_data.ipp:447
double mean_node_ins_cost(const GEDGraph &graph) const
Returns the mean cost of inserting a node contained in a graph.
Definition: ged_data.ipp:801
GEDGraph::NodeID pre_image(GEDGraph::NodeID node) const
Returns pre-image of a node.
Definition: node_map.ipp:137
double min_edit_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the minimal edit cost between two graphs.
Definition: ged_data.ipp:1004
double mean_node_subs_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the mean cost of substituting a node contained in a graph by a node contained in another grap...
Definition: ged_data.ipp:843
Edit cost functions for chemical graphs such as the ones contained in the datasets Mutagenicity...
Definition: chem_2.hpp:54
double min_node_del_cost(const GEDGraph &graph) const
Returns the minimal cost of deleting a node contained in a graph.
Definition: ged_data.ipp:754
double min_edge_edit_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the minimal edge edit cost between two graphs.
Definition: ged_data.ipp:1047
double min_edge_subs_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the minimal cost of substituting a edge contained in a graph by a edge contained in another g...
Definition: ged_data.ipp:872
std::size_t num_edge_labels() const
Returns the number of edge labels.
Definition: ged_data.ipp:407
Selects ged::Protein.
bool is_shuffled_graph_copy(GEDGraph::GraphID graph_id) const
Checks if a graph is a shuffled copy of another graph.
Definition: ged_data.ipp:379
double max_node_del_cost(const GEDGraph &graph) const
Returns the maximal cost of deleting a node contained in a graph.
Definition: ged_data.ipp:743
double induced_cost() const
Returns the induced cost.
Definition: node_map.ipp:210
std::size_t LabelID
Internally used type of node and edge labels.
double mean_edge_del_cost(const GEDGraph &graph) const
Returns the mean cost of deleting a edge contained in a graph.
Definition: ged_data.ipp:930
Selects ged::Constant.
double max_edit_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the maximal edit cost between two graphs.
Definition: ged_data.ipp:991
NodeID tail(EdgeID edge) const
Returns the tail of an edge.
Definition: ged_graph.ipp:178
Selects ged::Letter.
LabelID get_node_label(NodeID node) const
Returns the label of a given node.
Definition: ged_graph.ipp:126
std::size_t num_edges() const
Returns the number of edges.
Definition: ged_graph.ipp:223
Runtime error class.
Definition: error.hpp:37
std::vector< GEDGraph >::const_iterator end() const
Provides access to the graphs contained in the instance.
Definition: ged_data.ipp:393
static NodeID dummy_node()
Returns a dummy node.
Definition: ged_graph.ipp:56
double max_node_edit_cost() const
Returns the maximal node edit cost between any two graphs contained in the instance.
Definition: ged_data.ipp:727
bool shuffled_graph_copies_available() const
Checks if shuffled graph copies are available.
Definition: ged_data.ipp:352
LabelID get_edge_label(EdgeID edge) const
Returns the label of a given edge.
Definition: ged_graph.ipp:135
GEDGraph::GraphID id_shuffled_graph_copy(GEDGraph::GraphID graph_id) const
Returns ID of a graph&#39;s shuffled copy.
Definition: ged_data.ipp:366
double mean_edge_ins_cost(const GEDGraph &graph) const
Returns the mean cost of inserting a edge contained in a graph.
Definition: ged_data.ipp:977
double swap_cost(const GEDGraph &g, const GEDGraph &h, const NodeMap::Assignment &assignment_1, const NodeMap::Assignment &assignment_2, NodeMap &node_map) const
Computes the cost of swapping two assignments in a node map while leaving the node map unchanged...
Definition: ged_data.ipp:570
void vectorize_node_label(LabelID node_label, std::vector< double > &vector_representation) const
Computes a node label&#39;s representation as a real-valued vector.
Definition: ged_data.ipp:473
std::pair< incident_edge_iterator, incident_edge_iterator > incident_edges(NodeID node) const
Provides access to all incident edges of a node.
Definition: ged_graph.ipp:150
std::size_t num_graphs_without_shuffled_copies() const
Returns the number of graphs in the instance without the shuffled copies.
Definition: ged_data.ipp:359
double max_edge_ins_cost(const GEDGraph &graph) const
Returns the maximal cost of inserting a edge contained in a graph.
Definition: ged_data.ipp:955
double min_edge_del_cost(const GEDGraph &graph) const
Returns the minimal cost of deleting a edge contained in a graph.
Definition: ged_data.ipp:944
Edit costs for graphs contain in CMU dataset.
Definition: cmu.hpp:53
double mean_edge_subs_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the mean cost of substituting a edge contained in a graph by a edge contained in another grap...
Definition: ged_data.ipp:887
std::vector< GEDGraph >::const_iterator begin() const
Provides access to the graphs contained in the instance.
Definition: ged_data.ipp:386
double max_node_subs_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the maximal cost of substituting a node contained in a graph by a node contained in another g...
Definition: ged_data.ipp:815
Edit costs for graphs contained in Letter datasets.
Definition: letter.hpp:50
double min_edge_ins_cost(const GEDGraph &graph) const
Returns the minimal cost of inserting a edge contained in a graph.
Definition: ged_data.ipp:966
std::pair< node_iterator, node_iterator > nodes() const
Provides access to all nodes in the graph.
Definition: ged_graph.ipp:205
double max_edge_del_cost(const GEDGraph &graph) const
Returns the maximal cost of deleting a edge contained in a graph.
Definition: ged_data.ipp:919
The normalized input graphs used by GEDLIB. All labels are integers.
Definition: ged_graph.hpp:104
double max_edge_edit_cost() const
Returns the maximal edge edit cost between any two graphs contained in the instance.
Definition: ged_data.ipp:903
void add_assignment(GEDGraph::NodeID i, GEDGraph::NodeID k)
Add node substitution, insertion, or deletion to the node map.
Definition: node_map.ipp:183
void set_induced_cost(double induced_cost)
Sets the induced cost of the node map.
Definition: node_map.ipp:204
constexpr LabelID dummy_label()
Returns a dummy label.
bool quasimetric_costs() const
Checks if the edit costs are quasimetric.
Definition: ged_data.ipp:669
double max_edge_subs_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the maximal cost of substituting a edge contained in a graph by a edge contained in another g...
Definition: ged_data.ipp:859
double min_node_edit_cost(const GEDGraph &g, const GEDGraph &h) const
Returns the minimal node edit cost between two graphs.
Definition: ged_data.ipp:1027
Global namespace for GEDLIB.
Eager initialization, no shuffled graph copies are constructed.
EditCosts
Selects the edit costs.
void save_node_map(const std::string &filename, GEDGraph::NodeID g_id, GEDGraph::NodeID h_id, const NodeMap &node_map, bool append=true) const
Saves a node map.
Definition: ged_data.ipp:480
std::size_t num_node_labels() const
Returns the number of node labels.
Definition: ged_data.ipp:400
GEDGraph::NodeID image(GEDGraph::NodeID node) const
Returns image of a node.
Definition: node_map.ipp:110
Implements constant edit cost functions.
Definition: constant.hpp:38
double mean_node_del_cost(const GEDGraph &graph) const
Returns the mean cost of deleting a node contained in a graph.
Definition: ged_data.ipp:765
Edit costs for graphs contained in Fingerprint dataset.
Definition: fingerprint.hpp:51
double min_node_ins_cost(const GEDGraph &graph) const
Returns the minimal cost of inserting a node contained in a graph.
Definition: ged_data.ipp:790
Edit cost functions for the dataset GREC.
Definition: grec_1.hpp:51
std::size_t NodeID
Internally used vertex ID type.
Definition: ged_graph.hpp:108
Abstract class for defining edit cost functions.
Definition: edit_costs.hpp:38
Eager initialization, shuffled graph copies are constructed.
Edit costs for graphs contained in Protein dataset.
Definition: protein.hpp:54
void load_node_map(const std::string &filename, GEDGraph::NodeID g_id, GEDGraph::NodeID h_id, NodeMap &node_map) const
Loads a node map from a file.
Definition: ged_data.ipp:501
std::pair< edge_iterator, edge_iterator > edges() const
Provides access to all edge in the graph.
Definition: ged_graph.ipp:217
std::size_t num_rows() const
Returns the number of rows.
Definition: matrix.ipp:85
std::size_t num_graphs() const
Returns the number of graphs.
Definition: ged_data.ipp:318