27 #ifndef SRC_METHODS_PARTITION_IPP_ 28 #define SRC_METHODS_PARTITION_IPP_ 33 template<
class UserNodeLabel,
class UserEdgeLabel>
34 Partition<UserNodeLabel, UserEdgeLabel>::
37 template<
class UserNodeLabel,
class UserEdgeLabel>
38 Partition<UserNodeLabel, UserEdgeLabel>::
39 Partition(
const GEDData<UserNodeLabel, UserEdgeLabel> & ged_data) :
40 GEDMethod<UserNodeLabel, UserEdgeLabel>(ged_data),
42 unmatched_substructs_() {}
45 template<
class UserNodeLabel,
class UserEdgeLabel>
54 template<
class UserNodeLabel,
class UserEdgeLabel>
59 unmatched_substructs_.clear();
62 SubstructMap_ & is_substruct_in_g = substruct_maps_.at(g.
id());
63 unmatched_substructs_.clear();
65 std::map<GEDGraph::NodeID, bool> is_deleted_node;
66 for (
auto node_1 = h.
nodes().first; node_1 != h.
nodes().second; node_1++) {
67 is_deleted_node[*node_1] =
false;
69 std::map<GEDGraph::EdgeID, bool> is_deleted_edge;
70 for (
auto edge_1 = h.
edges().first; edge_1 != h.
edges().second; edge_1++) {
71 is_deleted_edge[*edge_1] =
false;
74 check_node_subtructs_(h, is_substruct_in_g, is_deleted_node);
75 check_edge_subtructs_(h, is_substruct_in_g, is_deleted_edge);
76 check_node_edge_subtructs_(h, is_substruct_in_g, is_deleted_node, is_deleted_edge);
77 check_node_edge_node_subtructs_(h, is_substruct_in_g, is_deleted_node, is_deleted_edge);
78 check_node_edge_edge_subtructs_(h, is_substruct_in_g, is_deleted_node, is_deleted_edge);
84 template<
class UserNodeLabel,
class UserEdgeLabel>
88 substruct_maps_[graph.
id()] = SubstructMap_();
89 SubstructMap_ & is_substruct = substruct_maps_.at(graph.
id());
90 for (
LabelID edge_label_1{1}; edge_label_1 < this->
ged_data_.num_edge_labels(); edge_label_1++) {
91 Substruct_ edge_substruct(EDGE, edge_label_1);
92 is_substruct[edge_substruct] = contains_substruct_(graph, edge_substruct);
94 for (
LabelID node_label_1{1}; node_label_1 < this->
ged_data_.num_node_labels(); node_label_1++) {
95 Substruct_ node_substruct(NODE, node_label_1);
96 bool contains_node_substruct{contains_substruct_(graph, node_substruct)};
97 is_substruct[node_substruct] = contains_node_substruct;
98 for (
LabelID edge_label_1{1}; edge_label_1 < this->
ged_data_.num_edge_labels(); edge_label_1++) {
99 Substruct_ node_edge_substruct(NODE_EDGE, node_label_1, edge_label_1);
100 bool contains_node_edge_substruct{
false};
101 if (contains_node_substruct) {
102 contains_node_edge_substruct = contains_substruct_(graph, node_edge_substruct);
103 is_substruct[node_edge_substruct] = contains_node_edge_substruct;
106 is_substruct[node_edge_substruct] =
false;
108 for (
LabelID node_label_2{1}; node_label_2 < this->
ged_data_.num_node_labels(); node_label_2++) {
109 Substruct_ node_edge_node_substruct(NODE_EDGE_NODE, node_label_1, edge_label_1, node_label_2);
110 if (contains_node_edge_substruct) {
111 is_substruct[node_edge_node_substruct] = contains_substruct_(graph, node_edge_node_substruct);
114 is_substruct[node_edge_node_substruct] =
false;
117 for (
LabelID edge_label_2{1}; edge_label_2 < this->
ged_data_.num_edge_labels(); edge_label_2++) {
118 Substruct_ node_edge_edge_substruct(NODE_EDGE_EDGE, node_label_1, edge_label_1, edge_label_2);
119 if (contains_node_edge_substruct) {
120 is_substruct[node_edge_edge_substruct] = contains_substruct_(graph, node_edge_edge_substruct);
123 is_substruct[node_edge_edge_substruct] =
false;
130 template<
class UserNodeLabel,
class UserEdgeLabel>
135 std::vector<LabelID> node_labels_h;
136 for (
auto node = h.
nodes().first; node != h.
nodes().second; node++) {
140 std::vector<LabelID> edge_labels_h;
141 for (
auto edge = h.
edges().first; edge != h.
edges().second; edge++) {
145 substruct_maps_[g.
id()] = SubstructMap_();
146 SubstructMap_ & is_substruct = substruct_maps_.at(g.
id());
147 for (
LabelID edge_label_1 : edge_labels_h) {
148 Substruct_ edge_substruct(EDGE, edge_label_1);
149 is_substruct[edge_substruct] = contains_substruct_(g, edge_substruct);
151 for (
LabelID node_label_1 : node_labels_h) {
152 Substruct_ node_substruct(NODE, node_label_1);
153 bool contains_node_substruct{contains_substruct_(g, node_substruct)};
154 is_substruct[node_substruct] = contains_node_substruct;
155 for (
LabelID edge_label_1 : edge_labels_h) {
156 Substruct_ node_edge_substruct(NODE_EDGE, node_label_1, edge_label_1);
157 bool contains_node_edge_substruct{
false};
158 if (contains_node_substruct) {
159 contains_node_edge_substruct = contains_substruct_(g, node_edge_substruct);
160 is_substruct[node_edge_substruct] = contains_node_edge_substruct;
163 is_substruct[node_edge_substruct] =
false;
165 for (
LabelID node_label_2 : node_labels_h) {
166 Substruct_ node_edge_node_substruct(NODE_EDGE_NODE, node_label_1, edge_label_1, node_label_2);
167 if (contains_node_edge_substruct) {
168 is_substruct[node_edge_node_substruct] = contains_substruct_(g, node_edge_node_substruct);
171 is_substruct[node_edge_node_substruct] =
false;
174 for (
LabelID edge_label_2 : edge_labels_h) {
175 Substruct_ node_edge_edge_substruct(NODE_EDGE_EDGE, node_label_1, edge_label_1, edge_label_2);
176 if (contains_node_edge_substruct) {
177 is_substruct[node_edge_edge_substruct] = contains_substruct_(g, node_edge_edge_substruct);
180 is_substruct[node_edge_edge_substruct] =
false;
187 template<
class UserNodeLabel,
class UserEdgeLabel>
191 switch (substruct.type) {
193 return contains_node_substruct_(g, substruct);
195 return contains_edge_substruct_(g, substruct);
197 return contains_node_edge_substruct_(g, substruct);
199 return contains_node_edge_node_substruct_(g, substruct);
201 return contains_node_edge_edge_substruct_(g, substruct);
206 template<
class UserNodeLabel,
class UserEdgeLabel>
210 for (
auto node_1 = h.
nodes().first; node_1 != h.
nodes().second; node_1++) {
212 if (not is_substruct_in_g.at(node_substruct)) {
213 unmatched_substructs_.push_back(node_substruct);
214 is_deleted_node.at(*node_1) =
true;
219 template<
class UserNodeLabel,
class UserEdgeLabel>
223 for (
auto node_1 = g.
nodes().first; node_1 != g.
nodes().second; node_1++) {
231 template<
class UserNodeLabel,
class UserEdgeLabel>
235 for (
auto edge_1 = h.
edges().first; edge_1 != h.
edges().second; edge_1++) {
237 if (not is_substruct_in_g.at(edge_substruct)) {
238 unmatched_substructs_.push_back(edge_substruct);
239 is_deleted_edge.at(*edge_1) =
true;
244 template<
class UserNodeLabel,
class UserEdgeLabel>
248 for (
auto edge_1 = g.
edges().first; edge_1 != g.
edges().second; edge_1++) {
256 template<
class UserNodeLabel,
class UserEdgeLabel>
259 check_node_edge_subtructs_(
const GEDGraph & h,
const SubstructMap_ & is_substruct_in_g, std::map<GEDGraph::NodeID, bool> & is_deleted_node, std::map<GEDGraph::EdgeID, bool> & is_deleted_edge) {
260 for (
auto node_1 = h.
nodes().first; node_1 != h.
nodes().second; node_1++) {
261 if (is_deleted_node.at(*node_1)) {
265 if (is_deleted_edge.at(*edge_1)) {
269 if (not is_substruct_in_g.at(node_edge_substruct)) {
270 unmatched_substructs_.push_back(node_edge_substruct);
271 is_deleted_node.at(*node_1) =
true;
272 is_deleted_edge.at(*edge_1) =
true;
279 template<
class UserNodeLabel,
class UserEdgeLabel>
283 std::vector<GEDGraph::NodeID> candidate_nodes;
284 for (
auto node_1 = g.
nodes().first; node_1 != g.
nodes().second; node_1++) {
286 candidate_nodes.push_back(*node_1);
289 if (candidate_nodes.empty()) {
292 for (
auto node_1 = candidate_nodes.begin(); node_1 != candidate_nodes.end(); node_1++) {
302 template<
class UserNodeLabel,
class UserEdgeLabel>
305 check_node_edge_node_subtructs_(
const GEDGraph & h,
const SubstructMap_ & is_substruct_in_g, std::map<GEDGraph::NodeID, bool> & is_deleted_node, std::map<GEDGraph::EdgeID, bool> & is_deleted_edge) {
306 for (
auto node_1 = h.
nodes().first; node_1 != h.
nodes().second; node_1++) {
307 if (is_deleted_node.at(*node_1)) {
312 if (is_deleted_edge.at(*edge_1) or is_deleted_node.at(node_2)) {
316 if (not is_substruct_in_g.at(node_edge_node_substruct)) {
317 unmatched_substructs_.push_back(node_edge_node_substruct);
318 is_deleted_node.at(*node_1) =
true;
319 is_deleted_edge.at(*edge_1) =
true;
320 is_deleted_node.at(node_2) =
true;
327 template<
class UserNodeLabel,
class UserEdgeLabel>
331 std::vector<GEDGraph::NodeID> candidate_nodes;
332 for (
auto node_1 = g.
nodes().first; node_1 != g.
nodes().second; node_1++) {
334 candidate_nodes.push_back(*node_1);
337 if (candidate_nodes.empty()) {
340 for (
auto node_1 = candidate_nodes.begin(); node_1 != candidate_nodes.end(); node_1++) {
352 template<
class UserNodeLabel,
class UserEdgeLabel>
355 check_node_edge_edge_subtructs_(
const GEDGraph & h,
const SubstructMap_ & is_substruct_in_g, std::map<GEDGraph::NodeID, bool> & is_deleted_node, std::map<GEDGraph::EdgeID, bool> & is_deleted_edge) {
356 for (
auto node_1 = h.
nodes().first; node_1 != h.
nodes().second; node_1++) {
357 if (is_deleted_node.at(*node_1)) {
361 if (is_deleted_edge.at(*edge_1)) {
364 bool found_unmatched_substruct{
false};
366 if ((*edge_1 == *edge_2) or is_deleted_edge.at(*edge_2)) {
370 if (not is_substruct_in_g.at(node_edge_edge_substruct)) {
371 unmatched_substructs_.push_back(node_edge_edge_substruct);
372 is_deleted_node.at(*node_1) =
true;
373 is_deleted_edge.at(*edge_1) =
true;
374 is_deleted_edge.at(*edge_2) =
true;
375 found_unmatched_substruct =
true;
379 if (found_unmatched_substruct) {
386 template<
class UserNodeLabel,
class UserEdgeLabel>
390 std::vector<GEDGraph::NodeID> candidate_nodes;
391 for (
auto node_1 = g.
nodes().first; node_1 != g.
nodes().second; node_1++) {
393 candidate_nodes.push_back(*node_1);
396 if (candidate_nodes.empty()) {
399 for (
auto node_1 = candidate_nodes.begin(); node_1 != candidate_nodes.end(); node_1++) {
403 if (*edge_1 == *edge_2) {
417 template<
class UserNodeLabel,
class UserEdgeLabel>
432 node_label_1 = label_1;
435 edge_label_1 = label_1;
438 node_label_1 = label_1;
439 edge_label_1 = label_2;
442 node_label_1 = label_1;
443 edge_label_1 = label_2;
444 node_label_2 = label_3;
447 node_label_1 = label_1;
448 edge_label_1 = label_2;
449 edge_label_2 = label_3;
454 template<
class UserNodeLabel,
class UserEdgeLabel>
458 operator<(
const Substruct_ & rhs)
const {
459 if (node_label_1 < rhs.node_label_1) {
462 if (node_label_1 > rhs.node_label_1) {
465 if (edge_label_1 < rhs.edge_label_1) {
468 if (edge_label_1 > rhs.edge_label_1) {
471 if (node_label_2 < rhs.node_label_2) {
474 if (node_label_2 > rhs.node_label_2) {
477 if (edge_label_2 < rhs.edge_label_2) {
480 if (edge_label_2 > rhs.edge_label_2) {
486 template<
class UserNodeLabel,
class UserEdgeLabel>
487 const std::vector<typename Partition<UserNodeLabel, UserEdgeLabel>::Substruct_> &
490 return unmatched_substructs_;
Computes a lower bound for uniform edit costs.
const GEDData< UserNodeLabel, UserEdgeLabel > & ged_data_
The data on which the method is run.
void set_lower_bound(double lower_bound)
Sets the lower bound for GED.
NodeID head(EdgeID edge) const
Returns the head of an edge.
virtual void ged_run_(const GEDGraph &g, const GEDGraph &h, Result &result) final
Runs the method with options specified by set_options().
virtual void ged_init_() final
Initializes the method.
A wrapper structure for the result of calls to ged::GEDMethod::run_as_util() and ged::GEDMethod::ged_...
std::size_t LabelID
Internally used type of node and edge labels.
LabelID get_node_label(NodeID node) const
Returns the label of a given node.
static NodeID dummy_node()
Returns a dummy node.
LabelID get_edge_label(EdgeID edge) const
Returns the label of a given edge.
std::pair< incident_edge_iterator, incident_edge_iterator > incident_edges(NodeID node) const
Provides access to all incident edges of a node.
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.
detail::GedGraphAL::edge_descriptor EdgeID
Internally used edge ID type.
constexpr LabelID dummy_label()
Returns a dummy label.
Global namespace for GEDLIB.
std::size_t NodeID
Internally used vertex ID type.
GraphID id() const
Returns the ID of the graph.
std::pair< edge_iterator, edge_iterator > edges() const
Provides access to all edge in the graph.