1 #ifndef AI_TOOLBOX_POMDP_LINEAR_SUPPORT_HEADER_FILE
2 #define AI_TOOLBOX_POMDP_LINEAR_SUPPORT_HEADER_FILE
4 #include <boost/heap/fibonacci_heap.hpp>
11 #include <unordered_set>
12 #include <boost/functional/hash.hpp>
123 std::tuple<double, ValueFunction>
operator()(
const M & model);
129 using SupportSet = std::unordered_set<VEntry, boost::hash<VEntry>>;
130 using BeliefSet = std::unordered_set<Belief, boost::hash<Belief>>;
134 struct VertexComparator {
135 bool operator() (
const Vertex & lhs,
const Vertex & rhs)
const;
140 SupportSet::iterator support;
146 using Agenda = boost::heap::fibonacci_heap<Vertex, boost::heap::compare<VertexComparator>>;
153 const auto S = model.getS();
158 unsigned timestep = 0;
160 double variation = tolerance_ * 2;
161 while ( timestep < horizon_ && ( !useTolerance || variation > tolerance_ ) ) {
164 auto projections = project(v[timestep-1]);
174 SupportSet allSupports;
178 BeliefSet triedVertices;
185 Belief corner(S); corner.setZero();
186 for (
size_t s = 0; s < S; ++s) {
190 if (inserted) goodSupports.push_back(*it);
206 for (
size_t i = 0; i < vertices.first.size(); ++i) {
207 const auto & vertex = vertices.first[i];
208 if (triedVertices.find(vertex) != std::end(triedVertices))
214 double currentValue = vertices.second[i];
219 const auto gsBegin = std::cbegin(goodSupports);
220 const auto gsEnd = std::cend(goodSupports);
223 auto diff = trueValue - currentValue;
225 auto it = allSupports.insert(std::move(support));
227 newVertex.belief = vertex;
228 newVertex.currentValue = currentValue;
229 newVertex.support = it.first;
230 newVertex.error = diff;
231 agenda_.push(std::move(newVertex));
234 triedVertices.insert(std::move(vertex));
237 if (agenda_.size() == 0)
240 Vertex best = agenda_.top();
243 AI_LOGGER(
AI_SEVERITY_INFO,
"Selected Vertex " << best.belief.transpose() <<
" as best, with support: " << best.support->values.transpose() <<
", action: " << best.support->action);
245 std::vector<Agenda::handle_type> verticesToRemove;
250 for (
auto it = agenda_.begin(); it != agenda_.end(); ++it) {
253 if (it->belief.dot(best.support->values) > it->currentValue)
254 verticesToRemove.push_back(Agenda::s_handle_from_iterator(it));
258 for (
auto & h : verticesToRemove) {
264 const auto bestAddr = &(*best.support);
265 const auto supBegin = bestAddr;
266 const auto supEnd = bestAddr + 1;
267 const auto chkBegin = std::cbegin(goodSupports);
268 const auto chkEnd = std::cend(goodSupports);
274 goodSupports.push_back(*best.support);
278 v.emplace_back(std::move(goodSupports));
281 if ( useTolerance ) {
285 return std::make_tuple(useTolerance ? variation : 0.0, v);