GEDLIB  1.0
bp_beam.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_BP_BEAM_IPP_
28 #define SRC_METHODS_BP_BEAM_IPP_
29 
30 namespace ged {
31 
32 // === Definitions of destructor and constructor. ===
33 template<class UserNodeLabel, class UserEdgeLabel>
34 BPBeam<UserNodeLabel, UserEdgeLabel>::
35 ~BPBeam() {}
36 
37 template<class UserNodeLabel, class UserEdgeLabel>
38 BPBeam<UserNodeLabel, UserEdgeLabel>::
39 BPBeam(const GEDData<UserNodeLabel, UserEdgeLabel> & ged_data) :
40 LSBasedMethod<UserNodeLabel, UserEdgeLabel>(ged_data),
41 beam_size_{5},
42 num_orderings_{1} {}
43 
44 // === Definitions of member functions inherited from LSBasedMethod. ===
45 template<class UserNodeLabel, class UserEdgeLabel>
46 void
48 ls_run_from_initial_solution_(const GEDGraph & g, const GEDGraph & h, double lower_bound, const NodeMap & initial_node_map, NodeMap & output_node_map) {
49 
50  // Get the relational representation of the initial node map.
51  std::vector<NodeMap::Assignment> assignments;
52  initial_node_map.as_relation(assignments);
53  assignments.emplace_back(GEDGraph::dummy_node(), GEDGraph::dummy_node());
54 
55  // Initialize the output node map.
56  output_node_map = initial_node_map;
57 
58  // Run BPBeam multiple times if random ordering of the assignments is chosen.
59  for (std::size_t iteration{0}; iteration < num_orderings_; iteration++) {
60 
61  // Shuffle the assignments.
62  shuffle_assignments_(assignments);
63 
64  // Initialize the queue open.
65  std::vector<TreeNode_> open;
66  open.emplace_back(initial_node_map, assignments);
67 
68  // Iterate as long as open is not empty.
69  while (not open.empty()) {
70 
71  // Get the tree node top with the cheapest node map and remove it from open.
72  TreeNode_ top(open.at(0));
73  open.erase(open.begin());
74  if (top.node_map().induced_cost() < output_node_map.induced_cost()) {
75  output_node_map = top.node_map();
76  }
77 
78  // Top is a leaf in the search tree, so no children need to be expanded.
79  if (top.depth() == assignments.size() - 1) {
80  continue;
81  }
82 
83  // Put all children of top in the queue and update the output node map if a cheaper node map is encountered.
84  for (std::size_t pos_swapped_assignment{top.depth()}; pos_swapped_assignment < assignments.size(); pos_swapped_assignment++) {
85  open.emplace_back(top, this->ged_data_, g, h, pos_swapped_assignment);
86  }
87 
88  // Sort the queue and shrink it to the beam size.
89  sort_and_shrink_to_beam_size_(open);
90  }
91  }
92 }
93 
94 template<class UserNodeLabel, class UserEdgeLabel>
95 void
98  beam_size_ = 5;
99  num_orderings_ = 1;
100 }
101 
102 template<class UserNodeLabel, class UserEdgeLabel>
103 bool
105 ls_parse_option_(const std::string & option, const std::string & arg) {
106  bool return_value{false};
107  std::string ordering_options("");
108  if (option == "beam-size") {
109  try {
110  beam_size_ = std::stoul(arg);
111  }
112  catch (...) {
113  throw Error(std::string("Invalid argument \"") + arg + "\" for option beam-size. Usage: options = \"[--beam-size <convertible to int greater 0>]\"");
114  }
115  if (beam_size_ <= 0) {
116  throw Error(std::string("Invalid argument \"") + arg + "\" for option beam-size. Usage: options = \"[--beam-size <convertible to int greater 0>]\"");
117  }
118  return_value = true;
119  }
120  else if (option == "num-orderings") {
121  try {
122  num_orderings_ = std::stoul(arg);
123  }
124  catch (...) {
125  throw Error(std::string("Invalid argument \"") + arg + "\" for option num-random-orderings. Usage: options = \"[--num-orderings <convertible to int greater 0>]\"");
126  }
127  if (num_orderings_ < 1) {
128  throw Error(std::string("Invalid argument \"") + arg + "\" for option num-random-orderings. Usage: options = \"[--num-orderings <convertible to int greater 0>]\"");
129  }
130  return_value = true;
131  }
132  return return_value;
133 }
134 
135 template<class UserNodeLabel, class UserEdgeLabel>
136 std::string
139  return "[--beam-size <arg>] [--num-orderings <arg>]";
140 }
141 
142 // == Definitions of private helper member functions. ===
143 template<class UserNodeLabel, class UserEdgeLabel>
144 void
146 sort_and_shrink_to_beam_size_(std::vector<TreeNode_> & open) const {
147  std::sort(open.begin(), open.end());
148  while (open.size() > beam_size_) {
149  open.pop_back();
150  }
151 }
152 
153 template<class UserNodeLabel, class UserEdgeLabel>
154 void
156 shuffle_assignments_(std::vector<NodeMap::Assignment> & assignments) {
157  if (num_orderings_ > 1) {
158  std::random_device rng;
159  std::mt19937 urng(rng());
160  std::shuffle(assignments.begin(), assignments.end(), urng);
161  }
162 }
163 
164 // == Definitions of private class TreeNode_. ===
165 template<class UserNodeLabel, class UserEdgeLabel>
168 TreeNode_(const TreeNode_ & tree_node) :
169 node_map_(tree_node.node_map_),
170 assignments_(tree_node.assignments_),
171 depth_{tree_node.depth_} {}
172 
173 template<class UserNodeLabel, class UserEdgeLabel>
176 TreeNode_(const NodeMap & node_map, const std::vector<NodeMap::Assignment> & assignments) :
177 node_map_(node_map),
178 assignments_(assignments),
179 depth_{0} {}
180 
181 template<class UserNodeLabel, class UserEdgeLabel>
184 TreeNode_(const TreeNode_ & tree_node, const GEDData<UserNodeLabel, UserEdgeLabel> & ged_data, const GEDGraph & g, const GEDGraph & h, std::size_t pos_swapped_assignment) :
185 node_map_(tree_node.node_map_),
186 assignments_(tree_node.assignments_),
187 depth_{tree_node.depth_ + 1} {
188  NodeMap::Assignment assignment_1(assignments_.at(depth_ - 1));
189  NodeMap::Assignment assignment_2(assignments_.at(pos_swapped_assignment));
190  double swap_cost{ged_data.swap_cost(g, h, assignment_1, assignment_2, node_map_)};
191  ged_data.swap_assignments(assignment_1, assignment_2, swap_cost, node_map_);
192  assignments_[depth_ - 1].second = assignment_2.second;
193  assignments_[pos_swapped_assignment].second = assignment_1.second;
194 }
195 
196 template<class UserNodeLabel, class UserEdgeLabel>
197 const NodeMap &
200 node_map() const {
201  return node_map_;
202 }
203 
204 template<class UserNodeLabel, class UserEdgeLabel>
205 std::size_t
208 depth() const {
209  return depth_;
210 }
211 
212 template<class UserNodeLabel, class UserEdgeLabel>
213 bool
216 operator<(const TreeNode_ & tree_node) const {
217  return (node_map_ < tree_node.node_map_);
218 }
219 
220 }
221 
222 #endif /* SRC_METHODS_BP_BEAM_IPP_ */
Contains the standardized input data along with basic functionality.
Definition: ged_data.hpp:55
Computes an upper bound for general edit costs.
Definition: bp_beam.hpp:52
void as_relation(std::vector< Assignment > &relation) const
Constructs the representation as relation.
Definition: node_map.ipp:164
A class for node maps.
Definition: node_map.hpp:43
virtual void ls_set_default_options_() final
Sets all options that are not among the ones shared by all derived classes of ged::LSBasedMethod to d...
Definition: bp_beam.ipp:97
const GEDData< UserNodeLabel, UserEdgeLabel > & ged_data_
The data on which the method is run.
Definition: ged_method.hpp:124
void swap_assignments(const NodeMap::Assignment &assignment_1, const NodeMap::Assignment &assignment_2, double swap_cost, NodeMap &node_map) const
Swaps two assignments in a node map.
Definition: ged_data.ipp:656
double induced_cost() const
Returns the induced cost.
Definition: node_map.ipp:210
virtual void ls_run_from_initial_solution_(const GEDGraph &g, const GEDGraph &h, double lower_bound, const NodeMap &initial_node_map, NodeMap &output_node_map) final
Runs the local search from an initial node map.
Definition: bp_beam.ipp:48
Runtime error class.
Definition: error.hpp:37
static NodeID dummy_node()
Returns a dummy node.
Definition: ged_graph.ipp:56
double swap_cost(const GEDGraph &g, const GEDGraph &h, const NodeMap::Assignment &assignment_1, const NodeMap::Assignment &assignment_2, NodeMap &node_map) const
Computes the cost of swapping two assignments in a node map while leaving the node map unchanged...
Definition: ged_data.ipp:570
virtual std::string ls_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: bp_beam.ipp:138
The normalized input graphs used by GEDLIB. All labels are integers.
Definition: ged_graph.hpp:104
virtual bool ls_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::LSBasedMethod.
Definition: bp_beam.ipp:105
Global namespace for GEDLIB.