idol
A C++ Framework for Optimization
Loading...
Searching...
No Matches
NodeSet.h
1//
2// Created by henri on 17/10/22.
3//
4
5#ifndef IDOL_NODESET_H
6#define IDOL_NODESET_H
7
8#include <map>
9#include "idol/general/utils/IteratorForward.h"
10
11namespace idol {
12 template<class NodeT>
13 class NodeSet;
14}
15
16template<class NodeT>
18 using by_objective_value_t = std::multimap<double, NodeT>;
19 using by_level_t = std::multimap<unsigned int, NodeT>;
20 by_objective_value_t m_by_objective_value;
21 by_level_t m_by_level;
22public:
23 class const_iterator;
24
27
28 [[nodiscard]] ByObjectiveValueNodes by_objective_value() const { return ByObjectiveValueNodes(m_by_objective_value); }
29 [[nodiscard]] ByLevelNodes by_level() const { return ByLevelNodes(m_by_level); }
30
31 const_iterator emplace(NodeT t_node);
32
33 void clear();
34
35 [[nodiscard]] bool empty() const;
36
37 [[nodiscard]] unsigned int size() const { return m_by_objective_value.size(); }
38
39 const_iterator erase(const const_iterator& t_it);
40
41 void merge(NodeSet<NodeT>&& t_node_set);
42};
43
44template<class NodeT>
46
47 for (auto pair : t_node_set.m_by_objective_value) {
48 m_by_objective_value.emplace(std::move(pair));
49 }
50
51 for (auto pair : t_node_set.m_by_level) {
52 m_by_level.emplace(std::move(pair));
53 }
54
55 t_node_set.clear();
56
57}
58
59template<class NodeT>
61 auto it = m_by_objective_value.template emplace(t_node.info().objective_value(), t_node);
62 m_by_level.template emplace(t_node.level(), t_node);
63 return const_iterator(std::move(it));
64}
65
66template<class NodeT>
68 m_by_objective_value.clear();
69 m_by_level.clear();
70}
71
72template<class NodeT>
73bool idol::NodeSet<NodeT>::empty() const {
74 return m_by_objective_value.empty();
75}
76
77template<class NodeT>
78typename idol::NodeSet<NodeT>::const_iterator idol::NodeSet<NodeT>::erase(const NodeSet::const_iterator &t_it) {
79 const unsigned int id = t_it->id();
80
81 if (t_it.is_by_level()) {
82 const double objective_value = t_it->info().objective_value();
83 auto it = m_by_objective_value.lower_bound(objective_value);
84 for (; it->second.id() != id ; ++it);
85 m_by_objective_value.erase(it);
86 return const_iterator(m_by_level.erase(t_it.m_by_level_it));
87 }
88
89 const unsigned int level = t_it->level();
90 auto it = m_by_level.lower_bound(level);
91 for (; it->second.id() != id ; ++it);
92 m_by_level.erase(it);
93 return const_iterator(m_by_objective_value.erase(t_it.m_by_objective_value_it));
94}
95
96
97template<class NodeT>
99 friend class NodeSet<NodeT>;
100
101 using by_objective_value_it_t = typename by_objective_value_t::const_iterator;
102 using by_level_it_t = typename by_level_t::const_iterator;
103
104 bool m_is_by_level = true;
105 by_objective_value_it_t m_by_objective_value_it;
106 by_level_it_t m_by_level_it;
107public:
108 const_iterator() = default;
109 const_iterator(by_objective_value_it_t t_it) : m_by_objective_value_it(std::move(t_it)), m_is_by_level(false) {} // NOLINT(google-explicit-constructor)
110 const_iterator(by_level_it_t t_it) : m_by_level_it(std::move(t_it)), m_is_by_level(true) {} // NOLINT(google-explicit-constructor)
111 bool operator!=(const const_iterator& t_rhs) const {
112 if (m_is_by_level != t_rhs.m_is_by_level) {
113 return true;
114 }
115 if (m_is_by_level) {
116 return m_by_level_it != t_rhs.m_by_level_it;
117 }
118 return m_by_objective_value_it != t_rhs.m_by_objective_value_it;
119 }
120
121 [[nodiscard]] bool is_by_level() const { return m_is_by_level; }
122
123 const_iterator& operator=(const const_iterator& t_rhs) {
124 if (this == &t_rhs) { return *this; }
125 m_by_level_it = t_rhs.m_by_level_it;
126 m_by_objective_value_it = t_rhs.m_by_objective_value_it;
127 m_is_by_level = t_rhs.m_is_by_level;
128 return *this;
129 }
130 const_iterator& operator++() {
131 if (m_is_by_level) {
132 ++m_by_level_it;
133 } else {
134 ++m_by_objective_value_it;
135 }
136 return *this;
137 }
138 const_iterator& operator--() {
139 if (m_is_by_level) {
140 --m_by_level_it;
141 } else {
142 --m_by_objective_value_it;
143 }
144 return *this;
145 }
146 const NodeT& operator*() const {
147 if (m_is_by_level) {
148 return m_by_level_it->second;
149 }
150 return m_by_objective_value_it->second;
151 }
152
153 const NodeT* operator->() const {
154 if (m_is_by_level) {
155 return &m_by_level_it->second;
156 }
157 return &m_by_objective_value_it->second;
158 }
159 /*
160 NodeInfoT* operator->() {
161 if (m_is_by_level) {
162 return &m_by_level_it->second;
163 }
164 return &m_by_objective_value_it->second;
165 }
166 */
167};
168
169#endif //IDOL_NODESET_H