27 #ifndef SRC_METHODS_COMPACT_MIP_IPP_ 28 #define SRC_METHODS_COMPACT_MIP_IPP_ 33 template<
class UserNodeLabel,
class UserEdgeLabel>
34 CompactMIP<UserNodeLabel, UserEdgeLabel>::
37 template<
class UserNodeLabel,
class UserEdgeLabel>
38 CompactMIP<UserNodeLabel, UserEdgeLabel>::
39 CompactMIP(
const GEDData<UserNodeLabel, UserEdgeLabel> & ged_data) :
40 MIPBasedMethod<UserNodeLabel, UserEdgeLabel>(ged_data),
44 template<
class UserNodeLabel,
class UserEdgeLabel>
54 std::pair<GEDGraph::NodeID, GEDGraph::NodeID> key;
55 for (
auto i = g.
nodes().first; i != g.
nodes().second; i++) {
57 for (
auto k = h.
nodes().first; k != h.
nodes().second; k++) {
60 x_[key] = model.addVar(1, 1, 0, variable_type_());
63 x_[key] = model.addVar(0, 1, 0, variable_type_());
65 z_[key] = model.addVar(0, GRB_INFINITY, 1, GRB_CONTINUOUS);
71 for (
auto i = g.
nodes().first; i != g.
nodes().second; i++) {
73 x_[key] = model.addVar(0, 1, 0, variable_type_());
74 z_[key] = model.addVar(0, GRB_INFINITY, 1, GRB_CONTINUOUS);
79 for (
auto k = h.
nodes().first; k != h.
nodes().second; k++) {
81 x_[key] = model.addVar(0, 1, 0, variable_type_());
82 z_[key] = model.addVar(0, GRB_INFINITY, 1, GRB_CONTINUOUS);
88 for (
auto i = g.
nodes().first; i != g.
nodes().second; i++) {
92 for (
auto k = h.
nodes().first; k != h.
nodes().second; k++) {
96 model.addConstr(lhs, GRB_EQUAL, 1);
98 for (
auto k = h.
nodes().first; k != h.
nodes().second; k++) {
102 for (
auto i = g.
nodes().first; i != g.
nodes().second; i++) {
106 model.addConstr(lhs, GRB_EQUAL, 1);
112 for (
auto i = g.
nodes().first; i != g.
nodes().second; i++) {
114 for (
auto k = h.
nodes().first; k != h.
nodes().second; k++) {
117 lhs = edit_cost - z_.at(key);
119 for (
auto j = g.
nodes().first; j != g.
nodes().second; j++) {
121 for (
auto l = h.
nodes().first; l != h.
nodes().second; l++) {
125 lhs += edit_cost * x_.at(key);
129 for (
auto j = g.
nodes().first; j != g.
nodes().second; j++) {
133 lhs += edit_cost * x_.at(key);
136 for (
auto l = h.
nodes().first; l != h.
nodes().second; l++) {
140 lhs += edit_cost * x_.at(key);
144 lhs -= (1 - x_.at(key)) * u;
145 model.addConstr(lhs, GRB_LESS_EQUAL, 0);
151 for (
auto i = g.
nodes().first; i != g.
nodes().second; i++) {
154 lhs = edit_cost - z_.at(key);
156 for (
auto j = g.
nodes().first; j != g.
nodes().second; j++) {
158 for (
auto l = h.
nodes().first; l != h.
nodes().second; l++) {
162 lhs += edit_cost * x_.at(key);
166 for (
auto j = g.
nodes().first; j != g.
nodes().second; j++) {
170 lhs += edit_cost * x_.at(key);
173 lhs -= (1 - x_.at(key)) * u;
174 model.addConstr(lhs, GRB_LESS_EQUAL, 0);
179 for (
auto k = h.
nodes().first; k != h.
nodes().second; k++) {
182 lhs = edit_cost - z_.at(key);
184 for (
auto j = g.
nodes().first; j != g.
nodes().second; j++) {
186 for (
auto l = h.
nodes().first; l != h.
nodes().second; l++) {
190 lhs += edit_cost * x_.at(key);
194 for (
auto l = h.
nodes().first; l != h.
nodes().second; l++) {
198 lhs += edit_cost * x_.at(key);
201 lhs -= (1 - x_.at(key)) * u;
202 model.addConstr(lhs, GRB_LESS_EQUAL, 0);
208 template<
class UserNodeLabel,
class UserEdgeLabel>
214 for (
auto it = x_.begin(); it != x_.end(); it++) {
215 if (it->second.get(GRB_DoubleAttr_X) > 0) {
217 k = it->first.second;
227 template<
class UserNodeLabel,
class UserEdgeLabel>
232 for (
auto it = x_.begin(); it != x_.end(); it++) {
233 i = std::min(it->first.first, g.
num_nodes());
234 k = std::min(it->first.second, h.
num_nodes());
235 lsape_instance(i, k) -= it->second.get(GRB_DoubleAttr_X);
240 template<
class UserNodeLabel,
class UserEdgeLabel>
245 return GRB_CONTINUOUS;
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.
const GEDData< UserNodeLabel, UserEdgeLabel > & ged_data_
The data on which the method is run.
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...
Mixed integer linear programming formulation of the graph edit distance.
LabelID get_node_label(NodeID node) const
Returns the label of a given node.
virtual void mip_populate_model_(const GEDGraph &g, const GEDGraph &h, GRBModel &model) final
Runs the local search from an initial node map.
static NodeID dummy_node()
Returns a dummy node.
LabelID get_edge_label(EdgeID edge) const
Returns the label of a given edge.
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.
void add_assignment(GEDGraph::NodeID i, GEDGraph::NodeID k)
Add node substitution, insertion, or deletion to the node map.
void set_induced_cost(double induced_cost)
Sets the induced cost of the node map.
constexpr LabelID dummy_label()
Returns a dummy label.
Global namespace for GEDLIB.
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...
std::size_t NodeID
Internally used vertex ID type.
bool map_root_to_root_
If true, the model populated by mip_populate_model_() must enforce that the nodes with ID 0 are mappe...