ZonoOpt v2.0.1
Loading...
Searching...
No Matches
MI_DataStructures.hpp
Go to the documentation of this file.
1#ifndef ZONOOPT_MI_DATA_STRUCTURES_
2#define ZONOOPT_MI_DATA_STRUCTURES_
3
15#include <queue>
16#include <mutex>
17#include <utility>
18#include <memory>
19#include <set>
20#include <algorithm>
21#include <vector>
22#include <functional>
23
24#include "ADMM.hpp"
26
27namespace ZonoOpt::detail {
28
29 struct MI_data
30 {
31 std::shared_ptr<ADMM_data> admm_data;
32 std::pair<int, int> idx_b; // indices of binary variables
33 bool zero_one_form = false; // true: binary->{0,1}. false: binary->{-1,1}
34 };
35
36 template <typename T>
37 class ThreadSafeAccess
38 {
39 public:
40 ThreadSafeAccess() = default;
41
42 // get method
43 T get() const
44 {
45 std::lock_guard<std::mutex> lock(mtx);
46 return data;
47 }
48
49 // set method
50 void set(const T& value)
51 {
52 std::lock_guard<std::mutex> lock(mtx);
53 data = value;
54 }
55
56 private:
57 mutable std::mutex mtx;
58 T data;
59 };
60
61 template <typename T>
62 class ThreadSafeIncrementable
63 {
64 public:
65 explicit ThreadSafeIncrementable(T value) : data(value) {}
66
67 // get method
68 T get() const
69 {
70 std::lock_guard<std::mutex> lock(mtx);
71 return data;
72 }
73
74 // set method
75 void set(T value)
76 {
77 std::lock_guard<std::mutex> lock(mtx);
78 data = value;
79 }
80
81 // increment
82 void operator+=(T value)
83 {
84 std::lock_guard<std::mutex> lock(mtx);
85 data += value;
86 }
87
88 private:
89 mutable std::mutex mtx;
90 T data;
91 };
92
93 class ThreadSafeMultiset
94 {
95 public:
96 // constructor
97 ThreadSafeMultiset() = default;
98
99 // add J
100 void add(const zono_float J)
101 {
102 std::lock_guard<std::mutex> lock(mtx);
103 data.insert(J);
104 }
105
106 // remove J
107 void remove(const zono_float J)
108 {
109 std::lock_guard<std::mutex> lock(mtx);
110 if (const auto it = data.find(J); it != data.end())
111 data.erase(it);
112 }
113
114 // clear
115 void clear()
116 {
117 std::lock_guard<std::mutex> lock(mtx);
118 data.clear();
119 }
120
121 // get min, bool indicates if valid (i.e. not empty)
122 std::pair<zono_float, bool> get_min() const
123 {
124 std::lock_guard<std::mutex> lock(mtx);
125 if (data.empty())
126 return std::make_pair(std::numeric_limits<zono_float>::infinity(), false);
127 else
128 return std::make_pair(*data.begin(), true);
129 }
130
131 // get size
132 size_t size() const
133 {
134 std::lock_guard<std::mutex> lock(mtx);
135 return data.size();
136 }
137
138 private:
139 mutable std::mutex mtx;
140 std::multiset<zono_float> data;
141 };
142
143 template <typename T>
144 class ThreadSafeVector
145 {
146 public:
147 // constructor
148 ThreadSafeVector() = default;
149
150 // add element
151 void push_back(const T& value)
152 {
153 std::lock_guard<std::mutex> lock(mtx);
154 data.push_back(value);
155 }
156
157 // clear vector
158 void clear()
159 {
160 std::lock_guard<std::mutex> lock(mtx);
161 data.clear();
162 }
163
164 // get size
165 size_t size() const
166 {
167 std::lock_guard<std::mutex> lock(mtx);
168 return data.size();
169 }
170
171 // get vector
172 std::vector<T> get() const
173 {
174 std::lock_guard<std::mutex> lock(mtx);
175 return data;
176 }
177
178 // check containment
179 bool contains(const T& value, std::function<bool(const OptSolution&, const OptSolution&)>& compare) const
180 {
181 std::lock_guard<std::mutex> lock(mtx);
182 for (auto it=data.begin(); it!=data.end(); ++it)
183 {
184 if (compare(*it, value)) return true;
185 }
186 return false;
187 }
188
189 private:
190 mutable std::mutex mtx;
191 std::vector<T> data;
192 };
193
194 class Node final : public ADMM_solver
195 {
196 public:
197 // constructors
198 explicit Node(const std::shared_ptr<ADMM_data>& data) : ADMM_solver(data)
199 {
200 // init box constraints
201 this->x_box = *data->x_box;
202 }
203
204 // copy constructor
205 Node(const Node& other) : ADMM_solver(other)
206 {
207 this->x_box = other.x_box;
208 this->solution = other.solution;
209 this->width = this->x_box.width();
210 }
211
212 // public fields
213 OptSolution solution = OptSolution();
214 zono_float width = std::numeric_limits<zono_float>::infinity(); // width of the box
215
216 // run contractor
217 bool run_contractor()
218 {
219 const bool contractor_feasible = this->startup(this->x_box, this->solution);
220 this->width = this->x_box.width();
221 return contractor_feasible;
222 }
223
224 // fix bound
225 bool fix_bound(int ind, const zono_float val)
226 {
227 // update bounds
228 this->x_box[ind] = Interval(val, val);
229
230 // run contractor
231 const bool contractor_feasible = this->startup(this->x_box, this->solution, {ind});
232 this->width = this->x_box.width();
233 return contractor_feasible;
234 }
235
236 // solve
237 void solve(std::atomic<bool>* stop=nullptr)
238 {
239 this->solve_core(this->x_box, this->solution, stop);
240 }
241
242 // update convergence tolerances
243 void update_convergence_tolerances(const zono_float eps_prim, const zono_float eps_dual)
244 {
245 this->eps_prim = eps_prim;
246 this->eps_dual = eps_dual;
247 }
248
249 // get box
250 const Box& get_box() const
251 {
252 return x_box;
253 }
254
255 private:
256 // members
257 Box x_box;
258 };
259
260 template <typename T, typename Compare=std::less<T>>
261 class PriorityQueuePrunable final : public std::priority_queue<T, std::vector<T>, Compare>
262 {
263 public:
264 // constructor
265 explicit PriorityQueuePrunable(const Compare& comp = Compare()) : std::priority_queue<T, std::vector<T>, Compare>(comp) {}
266
267 // prune queue
268 void prune(const T& t)
269 {
270 auto it_prune = std::find_if(this->c.begin(), this->c.end(), [&](const T& item) {
271 return this->comp(item, t);
272 });
273 if (it_prune != this->c.end())
274 {
275 this->c.erase(it_prune, this->c.end());
276 }
277 }
278
279 // bottom
280 const T& bottom() const
281 {
282 return this->c.back();
283 }
284
285 // pop top
286 T pop_top()
287 {
288 T top = std::move(this->c.front());
289 this->pop();
290 return top;
291 }
292
293 // clear
294 void clear()
295 {
296 while (!this->empty())
297 this->pop();
298 }
299 };
300
301} // namespace ZonoOpt::detail
302
303
304#endif
ADMM implementation used within ZonoOpt.
Optimization settings and solution data structures for ZonoOpt library.
#define zono_float
Defines the floating-point type used in ZonoOpt.
Definition ZonoOpt.hpp:45