27 #ifndef SRC_METHODS_STAR_IPP_ 28 #define SRC_METHODS_STAR_IPP_ 34 template<
class UserNodeLabel,
class UserEdgeLabel>
35 Star<UserNodeLabel, UserEdgeLabel>::
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_() {}
46 template<
class UserNodeLabel,
class UserEdgeLabel>
50 sorted_node_labels_[graph.
id()] = SortedNodeLabels_(graph, sort_method_);
53 template<
class UserNodeLabel,
class UserEdgeLabel>
57 sort_method_= COUNTING;
60 template<
class UserNodeLabel,
class UserEdgeLabel>
64 return "[--sort-method <arg>]";
67 template<
class UserNodeLabel,
class UserEdgeLabel>
71 if (option ==
"sort-method") {
75 else if (arg ==
"COUNTING") {
76 sort_method_ = COUNTING;
79 throw Error(std::string(
"Invalid argument \"") + arg +
"\" for option upper-bound. Usage: options = \"[--sort-method STD|COUNTING] [...]\"");
86 template<
class UserNodeLabel,
class UserEdgeLabel>
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());
94 double min_edit_cost{this->
ged_data_.min_edit_cost(g, h)};
98 #pragma omp parallel for if(this->num_threads_ > 1) 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++) {
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;
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;
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;
115 template<
class UserNodeLabel,
class UserEdgeLabel>
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;
123 return 1 /
static_cast<double>(inverse_scaling_factor);
127 template<
class UserNodeLabel,
class UserEdgeLabel>
131 sorted_node_labels_() {
132 for (
auto node = g.
nodes().first; node != g.
nodes().second; node++) {
133 sorted_node_labels_[*node] = std::vector<LabelID>();
137 switch (sort_method) {
139 std::sort(sorted_node_labels_[*node].begin(), sorted_node_labels_[*node].end());
148 template<
class UserNodeLabel,
class UserEdgeLabel>
152 sorted_node_labels_() {}
154 template<
class UserNodeLabel,
class UserEdgeLabel>
158 operator=(
const SortedNodeLabels_ & sorted_edge_labels) {
159 sorted_node_labels_ = sorted_edge_labels.sorted_node_labels_;
162 template<
class UserNodeLabel,
class UserEdgeLabel>
163 const std::vector<LabelID> &
167 return sorted_node_labels_.at(node);
171 template<
class UserNodeLabel,
class UserEdgeLabel>
175 const SortedNodeLabels_ & sorted_node_labels_g,
const SortedNodeLabels_ & sorted_node_labels_h)
const {
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) {
187 else if (*label_g < *label_h) {
199 cost +=
static_cast<double>(2 * std::max(g.
degree(i), h.
degree(k)) - std::min(g.
degree(i), h.
degree(k)) - intersection_size);
205 template<
class UserNodeLabel,
class UserEdgeLabel>
209 return static_cast<double>(1 + 2 * g.
degree(i));
212 template<
class UserNodeLabel,
class UserEdgeLabel>
216 return static_cast<double>(1 + 2 * h.
degree(k));
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.
std::size_t num_nodes() const
Returns the number of nodes.
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.
NodeID head(EdgeID edge) const
Returns the head of an edge.
virtual void lsape_populate_instance_(const GEDGraph &g, const GEDGraph &h, DMatrix &lsape_instance) final
Populates the LSAPE instance.
Computes lower and upper bounds for uniform edit costs.
std::size_t degree(NodeID node) const
Returns node degree.
std::size_t maxdeg() const
Returns the maximum degree of the graph.
std::size_t num_cols() const
Returns the number of columns.
void counting_sort(std::vector< LabelID >::iterator first, std::vector< LabelID >::iterator last)
Implementation of counting sort.
LabelID get_node_label(NodeID node) const
Returns the label of a given node.
std::pair< incident_edge_iterator, incident_edge_iterator > incident_edges(NodeID node) const
Provides access to all incident edges of a node.
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:...
virtual double lsape_lower_bound_scaling_factor_(const GEDGraph &g, const GEDGraph &h) final
Returns scaling factor for lower bound.
std::pair< node_iterator, node_iterator > nodes() const
Provides access to all nodes in the graph.
The normalized input graphs used by GEDLIB. All labels are integers.
virtual void lsape_init_graph_(const GEDGraph &graph) final
Initializes global variables for one graph.
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...
std::size_t NodeID
Internally used vertex ID type.
GraphID id() const
Returns the ID of the graph.
std::size_t num_rows() const
Returns the number of rows.