GEDLIB  1.0
star.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_METHODS_STAR_IPP_
28 #define SRC_METHODS_STAR_IPP_
29 
30 
31 namespace ged {
32 
33 // === Definitions of destructor and constructor. ===
34 template<class UserNodeLabel, class UserEdgeLabel>
35 Star<UserNodeLabel, UserEdgeLabel>::
36 ~Star() {}
37 
38 template<class UserNodeLabel, class UserEdgeLabel>
39 Star<UserNodeLabel, UserEdgeLabel>::
40 Star(const GEDData<UserNodeLabel, UserEdgeLabel> & ged_data) :
41 LSAPEBasedMethod<UserNodeLabel, UserEdgeLabel>(ged_data),
42 sort_method_{COUNTING},
43 sorted_node_labels_() {}
44 
45 // === Definitions of member functions inherited from LSAPEBasedMethod. ===
46 template<class UserNodeLabel, class UserEdgeLabel>
47 void
49 lsape_init_graph_(const GEDGraph & graph) {
50  sorted_node_labels_[graph.id()] = SortedNodeLabels_(graph, sort_method_);
51 }
52 
53 template<class UserNodeLabel, class UserEdgeLabel>
54 void
57  sort_method_= COUNTING;
58 }
59 
60 template<class UserNodeLabel, class UserEdgeLabel>
61 std::string
64  return "[--sort-method <arg>]";
65 }
66 
67 template<class UserNodeLabel, class UserEdgeLabel>
68 bool
70 lsape_parse_option_(const std::string & option, const std::string & arg) {
71  if (option == "sort-method") {
72  if (arg == "STD") {
73  sort_method_ = STD;
74  }
75  else if (arg == "COUNTING") {
76  sort_method_ = COUNTING;
77  }
78  else {
79  throw Error(std::string("Invalid argument \"") + arg + "\" for option upper-bound. Usage: options = \"[--sort-method STD|COUNTING] [...]\"");
80  }
81  return true;
82  }
83  return false;
84 }
85 
86 template<class UserNodeLabel, class UserEdgeLabel>
87 void
89 lsape_populate_instance_(const GEDGraph & g, const GEDGraph & h, DMatrix & master_problem) {
90 
91  const SortedNodeLabels_ & sorted_node_labels_g = sorted_node_labels_.at(g.id());
92  const SortedNodeLabels_ & sorted_node_labels_h = sorted_node_labels_.at(h.id());
93 
94  double min_edit_cost{this->ged_data_.min_edit_cost(g, h)};
95 
96 #ifdef _OPENMP
97  omp_set_num_threads(this->num_threads_ - 1);
98 #pragma omp parallel for if(this->num_threads_ > 1)
99 #endif
100  for (std::size_t row_in_master = 0; row_in_master < master_problem.num_rows(); row_in_master++) {
101  for (std::size_t col_in_master = 0; col_in_master < master_problem.num_cols(); col_in_master++) {
102  if ((row_in_master < g.num_nodes()) and (col_in_master < h.num_nodes())) {
103  master_problem(row_in_master, col_in_master) = compute_substitution_cost_(g, h, row_in_master, col_in_master, sorted_node_labels_g, sorted_node_labels_h) * min_edit_cost;
104  }
105  else if (row_in_master < g.num_nodes()) {
106  master_problem(row_in_master, h.num_nodes()) = compute_deletion_cost_(g, row_in_master) * min_edit_cost;
107  }
108  else if (col_in_master < h.num_nodes()) {
109  master_problem(g.num_nodes(), col_in_master) = compute_insertion_cost_(h, col_in_master) * min_edit_cost;
110  }
111  }
112  }
113 }
114 
115 template<class UserNodeLabel, class UserEdgeLabel>
116 double
119  std::size_t inverse_scaling_factor{std::max(g.maxdeg(), h.maxdeg()) + 1};
120  if (inverse_scaling_factor < 4) {
121  inverse_scaling_factor = 4;
122  }
123  return 1 / static_cast<double>(inverse_scaling_factor);
124 }
125 
126 // === Definition of private class SortedUserEdgeLabels_. ===
127 template<class UserNodeLabel, class UserEdgeLabel>
130 SortedNodeLabels_(const GEDGraph & g, SortMethod_ sort_method) :
131 sorted_node_labels_() {
132  for (auto node = g.nodes().first; node != g.nodes().second; node++) {
133  sorted_node_labels_[*node] = std::vector<LabelID>();
134  for (auto edge = g.incident_edges(*node).first; edge != g.incident_edges(*node).second; edge++) {
135  sorted_node_labels_[*node].push_back(g.get_node_label(g.head(*edge)));
136  }
137  switch (sort_method) {
138  case STD:
139  std::sort(sorted_node_labels_[*node].begin(), sorted_node_labels_[*node].end());
140  break;
141  default:
142  util::counting_sort(sorted_node_labels_[*node].begin(), sorted_node_labels_[*node].end());
143  break;
144  }
145  }
146 }
147 
148 template<class UserNodeLabel, class UserEdgeLabel>
152 sorted_node_labels_() {}
153 
154 template<class UserNodeLabel, class UserEdgeLabel>
155 void
158 operator=(const SortedNodeLabels_ & sorted_edge_labels) {
159  sorted_node_labels_ = sorted_edge_labels.sorted_node_labels_;
160 }
161 
162 template<class UserNodeLabel, class UserEdgeLabel>
163 const std::vector<LabelID> &
167  return sorted_node_labels_.at(node);
168 }
169 
170 // === Definition of private helper functions. ===
171 template<class UserNodeLabel, class UserEdgeLabel>
172 double
175  const SortedNodeLabels_ & sorted_node_labels_g, const SortedNodeLabels_ & sorted_node_labels_h) const {
176 
177  // Compute multiset intersection size.
178  std::size_t intersection_size{0};
179  auto label_g = sorted_node_labels_g.get_incident_labels(i).begin();
180  auto label_h = sorted_node_labels_h.get_incident_labels(k).begin();
181  while ((label_g != sorted_node_labels_g.get_incident_labels(i).end()) and (label_h != sorted_node_labels_h.get_incident_labels(k).end())) {
182  if (*label_g == *label_h) {
183  intersection_size++;
184  label_g++;
185  label_h++;
186  }
187  else if (*label_g < *label_h) {
188  label_g++;
189  }
190  else {
191  label_h++;
192  }
193  }
194 
195  // Collect node cost.
196  double cost{g.get_node_label(i) != h.get_node_label(k) ? 1.0 : 0.0};
197 
198  // Collect edge and neighbor costs.
199  cost += static_cast<double>(2 * std::max(g.degree(i), h.degree(k)) - std::min(g.degree(i), h.degree(k)) - intersection_size);
200 
201  // Return overall substitution cost.
202  return cost;
203 }
204 
205 template<class UserNodeLabel, class UserEdgeLabel>
206 double
209  return static_cast<double>(1 + 2 * g.degree(i));
210 }
211 
212 template<class UserNodeLabel, class UserEdgeLabel>
213 double
216  return static_cast<double>(1 + 2 * h.degree(k));
217 }
218 
219 }
220 
221 
222 
223 #endif /* SRC_METHODS_STAR_IPP_ */
virtual bool lsape_parse_option_(const std::string &option, const std::string &arg) final
Parses one option that is not among the ones shared by all derived classes of ged::LSAPEBasedMethod.
Definition: star.ipp:70
std::size_t num_nodes() const
Returns the number of nodes.
Definition: ged_graph.ipp:211
std::size_t num_threads_
The number of threads to be used.
const GEDData< UserNodeLabel, UserEdgeLabel > & ged_data_
The data on which the method is run.
Definition: ged_method.hpp:124
NodeID head(EdgeID edge) const
Returns the head of an edge.
Definition: ged_graph.ipp:199
virtual void lsape_populate_instance_(const GEDGraph &g, const GEDGraph &h, DMatrix &lsape_instance) final
Populates the LSAPE instance.
Definition: star.ipp:89
Computes lower and upper bounds for uniform edit costs.
Definition: star.hpp:45
std::size_t degree(NodeID node) const
Returns node degree.
Definition: ged_graph.ipp:162
std::size_t maxdeg() const
Returns the maximum degree of the graph.
Definition: ged_graph.ipp:168
std::size_t num_cols() const
Returns the number of columns.
Definition: matrix.ipp:110
void counting_sort(std::vector< LabelID >::iterator first, std::vector< LabelID >::iterator last)
Implementation of counting sort.
Definition: misc.ipp:111
LabelID get_node_label(NodeID node) const
Returns the label of a given node.
Definition: ged_graph.ipp:126
Runtime error class.
Definition: error.hpp:37
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
virtual std::string lsape_valid_options_string_() const final
Returns string of all valid options that are not among the ones shared by all derived classes of ged:...
Definition: star.ipp:63
virtual double lsape_lower_bound_scaling_factor_(const GEDGraph &g, const GEDGraph &h) final
Returns scaling factor for lower bound.
Definition: star.ipp:118
std::pair< node_iterator, node_iterator > nodes() const
Provides access to all nodes in the graph.
Definition: ged_graph.ipp:205
The normalized input graphs used by GEDLIB. All labels are integers.
Definition: ged_graph.hpp:104
virtual void lsape_init_graph_(const GEDGraph &graph) final
Initializes global variables for one graph.
Definition: star.ipp:49
Global namespace for GEDLIB.
virtual void lsape_set_default_options_() final
Sets all options that are not among the ones shared by all derived classes of ged::LSAPEBasedMethod t...
Definition: star.ipp:56
std::size_t NodeID
Internally used vertex ID type.
Definition: ged_graph.hpp:108
GraphID id() const
Returns the ID of the graph.
Definition: ged_graph.ipp:184
std::size_t num_rows() const
Returns the number of rows.
Definition: matrix.ipp:85