From d3ecd5f49d4e911d8b7dac3ce278f987c9e7781a Mon Sep 17 00:00:00 2001 From: dmatetelki Date: Wed, 30 Jul 2014 14:26:03 +0200 Subject: [PATCH] priority_queue.hpp with ineffective modifyKey --- lib/graph/priority_queue.hpp | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 lib/graph/priority_queue.hpp diff --git a/lib/graph/priority_queue.hpp b/lib/graph/priority_queue.hpp new file mode 100644 index 0000000..970507d --- /dev/null +++ b/lib/graph/priority_queue.hpp @@ -0,0 +1,51 @@ +#ifndef PRIORITY_QUEUE_HPP +#define PRIORITY_QUEUE_HPP + +#include // std::m_map +#include // std::find_if + +/** @brief Priority Queu with top, push, pop, modifyKey. + * + * The priority queue based Dijkstra (shortest path) algorith requires the + * modifyKey functionality, which the std::priority_queue does not have. + * + * @note modifyKey is very ineffective, since std::map is not a + * bidirectional map, looking up an element based on value is linear. + * + * @todo replace std::map with a Fibonacci heap to improve performance. + */ + +template < + typename Key, + typename T, + typename Compare = std::less, + typename Allocator = std::allocator > +> +class PriorityQueue +{ +public: + + PriorityQueue() : m_map() {} + + // capacity + size_t size() const { return m_map.size(); } + bool empty() const { return m_map.empty(); } + + // lookup + std::pair top() const { return *m_map.begin(); } + + // modifiers + void pop() { m_map.erase(m_map.begin()); } + void push(const Key& key, const T& value) { m_map.emplace(key, value); } + void modifyKey(const T& value, const Key& diff) { + auto it = std::find_if(m_map.begin(), m_map.end(), [&value](const std::pair & p) { return p.second == value; } ); + Key key = it->first; // take a copy + m_map.erase(it); + m_map.emplace(key + diff, value); + } + +private: + std::map m_map; +}; + +#endif // PRIORITY_QUEUE_HPP