GEDLIB  1.0
blp_no_edge_labels.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_BLP_NO_EDGE_LABELS_IPP_
28 #define SRC_METHODS_BLP_NO_EDGE_LABELS_IPP_
29 
30 
31 namespace ged {
32 
33 template<class UserNodeLabel, class UserEdgeLabel>
34 BLPNoEdgeLabels<UserNodeLabel, UserEdgeLabel>::
35 ~BLPNoEdgeLabels() {}
36 
37 template<class UserNodeLabel, class UserEdgeLabel>
38 BLPNoEdgeLabels<UserNodeLabel, UserEdgeLabel>::
39 BLPNoEdgeLabels(const GEDData<UserNodeLabel, UserEdgeLabel> & ged_data) :
40 MIPBasedMethod<UserNodeLabel, UserEdgeLabel>(ged_data),
41 x_(),
42 s_(),
43 t_() {}
44 
45 template<class UserNodeLabel, class UserEdgeLabel>
46 void
48 mip_populate_model_(const GEDGraph & g, const GEDGraph & h, GRBModel & model) {
49 
50  // Clear the variables and the constant for the objective.
51  x_.clear();
52  s_.clear();
53  t_.clear();
54 
55  // Determine minimal edge deletion or insertion cost.
56  double min_edge_ins_del_cost{std::min(this->ged_data_.min_edge_del_cost(g), this->ged_data_.min_edge_ins_cost(h))};
57 
58  // Determine N.
59  std::size_t N{g.num_nodes() + h.num_nodes()};
60 
61  // Add substitution variables to the model.
62  NodeMap::Assignment key;
63  for (GEDGraph::GraphID i{0}; i < N; i++) {
64  for (GEDGraph::GraphID k{0}; k < N; k++) {
65  key.first = i;
66  key.second = k;
67  if ((i == 0) and (k == 0) and this->map_root_to_root_) {
68  x_[key] = model.addVar(1, 1, this->ged_data_.node_cost(g.get_node_label(i), h.get_node_label(k)), variable_type_());
69  }
70  else if ((i < g.num_nodes()) and (k < h.num_nodes())) {
71  x_[key] = model.addVar(0, 1, this->ged_data_.node_cost(g.get_node_label(i), h.get_node_label(k)), variable_type_());
72  }
73  else if (i < g.num_nodes()) {
74  x_[key] = model.addVar(0, 1, this->ged_data_.node_cost(g.get_node_label(i), dummy_label()), variable_type_());
75  }
76  else if (k < h.num_nodes()) {
77  x_[key] = model.addVar(0, 1, this->ged_data_.node_cost(dummy_label(), h.get_node_label(k)), variable_type_());
78  }
79  else {
80  x_[key] = model.addVar(0, 1, 0, variable_type_());
81  }
82  s_[key] = model.addVar(0, 1, min_edge_ins_del_cost / 2, variable_type_());
83  t_[key] = model.addVar(0, 1, min_edge_ins_del_cost / 2, variable_type_());
84  }
85  }
86 
87  // Add node constraints to the model.
88  GRBLinExpr lhs;
89  for (GEDGraph::GraphID i{0}; i < N; i++) {
90  key.first = i;
91  lhs = 0;
92  for (GEDGraph::GraphID k{0}; k < N; k++) {
93  key.second = k;
94  lhs += x_.at(key);
95  }
96  model.addConstr(lhs, GRB_EQUAL, 1);
97  }
98  for (GEDGraph::GraphID k{0}; k < N; k++) {
99  key.second = k;
100  lhs = 0;
101  for (GEDGraph::GraphID i{0}; i < N; i++) {
102  key.first = i;
103  lhs += x_.at(key);
104  }
105  model.addConstr(lhs, GRB_EQUAL, 1);
106  }
107 
108  // Add topology constraints to the model.
109  for (GEDGraph::GraphID i{0}; i < N; i++) {
110  for (GEDGraph::GraphID k{0}; k < N; k++) {
111  key.first = i;
112  key.second = k;
113  lhs = s_.at(key) - t_.at(key);
114  if (i < g.num_nodes()) {
115  for (auto ij = g.incident_edges(i).first; ij != g.incident_edges(i).second; ij++) {
116  key.first = g.head(*ij);
117  lhs += x_.at(key);
118  }
119  }
120  if (k < h.num_nodes()) {
121  key.first = i;
122  for (auto kl = h.incident_edges(k).first; kl != h.incident_edges(k).second; kl++) {
123  key.second = h.head(*kl);
124  lhs -= x_.at(key);
125  }
126  }
127  model.addConstr(lhs, GRB_EQUAL, 0);
128  }
129  }
130 
131 
132 }
133 
134 template<class UserNodeLabel, class UserEdgeLabel>
135 void
137 mip_model_to_node_map_(const GEDGraph & g, const GEDGraph & h, GRBModel & model, NodeMap & node_map) {
138 
139  // Initialize local variables.
140  std::vector<bool> delete_node(g.num_nodes(), true);
141  std::vector<bool> insert_node(h.num_nodes(), true);
142  GEDGraph::NodeID i, k;
143 
144  // Add node substitutions.
145  for (auto it = x_.begin(); it != x_.end(); it++) {
146  i = it->first.first;
147  k = it->first.second;
148  if ((i < g.num_nodes()) and (k < h.num_nodes()) and (it->second.get(GRB_DoubleAttr_X) > 0)) {
149  node_map.add_assignment(i, k);
150  delete_node[i] = false;
151  insert_node[k] = false;
152  }
153  }
154 
155  // Add node deletions.
156  for (i = 0; i < g.num_nodes(); i++) {
157  if (delete_node.at(i)) {
158  node_map.add_assignment(i, GEDGraph::dummy_node());
159  }
160  }
161 
162  // Add node insertions.
163  for (k = 0; k < h.num_nodes(); k++) {
164  if (insert_node.at(k)) {
165  node_map.add_assignment(GEDGraph::dummy_node(), k);
166  }
167  }
168 
169  // Set induced cost.
170  this->ged_data_.compute_induced_cost(g, h, node_map);
171 
172 }
173 
174 template<class UserNodeLabel, class UserEdgeLabel>
175 bool
177 mip_model_to_lsape_projection_problem_(const GEDGraph & g, const GEDGraph & h, GRBModel & model, DMatrix & lsape_instance) {
178  GEDGraph::NodeID i, k;
179  for (auto it = x_.begin(); it != x_.end(); it++) {
180  i = std::min(it->first.first, g.num_nodes());
181  k = std::min(it->first.second, h.num_nodes());
182  lsape_instance(i, k) -= it->second.get(GRB_DoubleAttr_X);
183  }
184  return true;
185 }
186 
187 template<class UserNodeLabel, class UserEdgeLabel>
188 char
190 variable_type_() const {
191  if (this->relax_) {
192  return GRB_CONTINUOUS;
193  }
194  return GRB_BINARY;
195 }
196 
197 }
198 
199 
200 #endif /* SRC_METHODS_BLP_NO_EDGE_LABELS_IPP_ */
bool relax_
If true, the model populated by mip_populate_model_() must be continuous.
std::size_t num_nodes() const
Returns the number of nodes.
Definition: ged_graph.ipp:211
A class for node maps.
Definition: node_map.hpp:43
std::vector< GEDGraph >::size_type GraphID
Type of internally used graph IDs.
Definition: ged_graph.hpp:112
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 bool mip_model_to_lsape_projection_problem_(const GEDGraph &g, const GEDGraph &h, GRBModel &model, DMatrix &lsape_instance) final
Given a, possibly sub-optimally, solved model, this method constructs an LSAPE instance for projectin...
LabelID get_node_label(NodeID node) const
Returns the label of a given node.
Definition: ged_graph.ipp:126
static NodeID dummy_node()
Returns a dummy node.
Definition: ged_graph.ipp:56
Binary linear programming formulation of the graph edit distance without edge labels.
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 void mip_populate_model_(const GEDGraph &g, const GEDGraph &h, GRBModel &model) final
Runs the local search from an initial node map.
The normalized input graphs used by GEDLIB. All labels are integers.
Definition: ged_graph.hpp:104
void add_assignment(GEDGraph::NodeID i, GEDGraph::NodeID k)
Add node substitution, insertion, or deletion to the node map.
Definition: node_map.ipp:183
constexpr LabelID dummy_label()
Returns a dummy label.
Global namespace for GEDLIB.
virtual void mip_model_to_node_map_(const GEDGraph &g, const GEDGraph &h, GRBModel &model, NodeMap &node_map) final
Given a, possibly sub-optimally, solved unrelaxed model, this method constructs a node map and sets i...
std::size_t NodeID
Internally used vertex ID type.
Definition: ged_graph.hpp:108
bool map_root_to_root_
If true, the model populated by mip_populate_model_() must enforce that the nodes with ID 0 are mappe...