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 friend class NodeSet<NodeT>;
47
48 using by_objective_value_it_t = typename by_objective_value_t::const_iterator;
49 using by_level_it_t = typename by_level_t::const_iterator;
50
51 bool m_is_by_level = true;
52 by_objective_value_it_t m_by_objective_value_it;
53 by_level_it_t m_by_level_it;
54public:
55 const_iterator() = default;
56 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)
57 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)
58 bool operator!=(const const_iterator& t_rhs) const {
59 if (m_is_by_level != t_rhs.m_is_by_level) {
60 return true;
61 }
62 if (m_is_by_level) {
63 return m_by_level_it != t_rhs.m_by_level_it;
64 }
65 return m_by_objective_value_it != t_rhs.m_by_objective_value_it;
66 }
67
68 [[nodiscard]] bool is_by_level() const { return m_is_by_level; }
69
70 const_iterator& operator=(const const_iterator& t_rhs) {
71 if (this == &t_rhs) { return *this; }
72 m_by_level_it = t_rhs.m_by_level_it;
73 m_by_objective_value_it = t_rhs.m_by_objective_value_it;
74 m_is_by_level = t_rhs.m_is_by_level;
75 return *this;
76 }
77 const_iterator& operator++() {
78 if (m_is_by_level) {
79 ++m_by_level_it;
80 } else {
81 ++m_by_objective_value_it;
82 }
83 return *this;
84 }
85 const_iterator& operator--() {
86 if (m_is_by_level) {
87 --m_by_level_it;
88 } else {
89 --m_by_objective_value_it;
90 }
91 return *this;
92 }
93 const NodeT& operator*() const {
94 if (m_is_by_level) {
95 return m_by_level_it->second;
96 }
97 return m_by_objective_value_it->second;
98 }
99
100 const NodeT* operator->() const {
101 if (m_is_by_level) {
102 return &m_by_level_it->second;
103 }
104 return &m_by_objective_value_it->second;
105 }
106 /*
107 NodeInfoT* operator->() {
108 if (m_is_by_level) {
109 return &m_by_level_it->second;
110 }
111 return &m_by_objective_value_it->second;
112 }
113 */
114};
115
116template<class NodeT>
118
119 for (auto pair : t_node_set.m_by_objective_value) {
120 m_by_objective_value.emplace(std::move(pair));
121 }
122
123 for (auto pair : t_node_set.m_by_level) {
124 m_by_level.emplace(std::move(pair));
125 }
126
127 t_node_set.clear();
128
129}
130
131template<class NodeT>
133 auto it = m_by_objective_value.emplace(t_node.info().objective_value(), t_node);
134 m_by_level.emplace(t_node.level(), t_node);
135 return const_iterator(std::move(it));
136}
137
138template<class NodeT>
140 m_by_objective_value.clear();
141 m_by_level.clear();
142}
143
144template<class NodeT>
145bool idol::NodeSet<NodeT>::empty() const {
146 return m_by_objective_value.empty();
147}
148
149template<class NodeT>
150typename idol::NodeSet<NodeT>::const_iterator idol::NodeSet<NodeT>::erase(const NodeSet<NodeT>::const_iterator &t_it) {
151 const unsigned int id = t_it->id();
152
153 if (t_it.is_by_level()) {
154 const double objective_value = t_it->info().objective_value();
155 auto it = m_by_objective_value.lower_bound(objective_value);
156 for (; it->second.id() != id ; ++it);
157 m_by_objective_value.erase(it);
158 return const_iterator(m_by_level.erase(t_it.m_by_level_it));
159 }
160
161 const unsigned int level = t_it->level();
162 auto it = m_by_level.lower_bound(level);
163 for (; it->second.id() != id ; ++it);
164 m_by_level.erase(it);
165 return const_iterator(m_by_objective_value.erase(t_it.m_by_objective_value_it));
166}
167
168
169#endif //IDOL_NODESET_H