BWAPI
SnippyHolloW-BroodwarBotQ-f01ab56/src/Utils/MinHeap.h
Go to the documentation of this file.
00001 #pragma once
00002 #include <vector>
00003 #include <map>
00004 #include <utility>
00005 
00006 // Hacked from BWTA's Heap implementation
00007 // Mininmum value on top
00008 template<class _Tp, class _Val>
00009 class MinHeap 
00010 {
00011     private:
00018         std::vector< std::pair<_Tp, _Val> > data;
00019         std::map< _Tp, int> obj_to_pos; // maps to position in data
00020 
00026         int percolate_up(int index);
00027 
00033         int percolate_down(int index);
00034 
00035     public:
00036         MinHeap() {}
00037         MinHeap( std::pair< _Tp, _Val > x);
00038         ~MinHeap() {}
00039 
00044         void push(std::pair< _Tp, _Val > x);
00045 
00046         void pop();
00047 
00048         const std::pair< _Tp, _Val >& top() const;
00049         
00057         bool set( _Tp& x, _Val& v);
00058 
00064         // const _Val& get(_Tp& x) const;
00065 
00066         // bool contains(_Tp& x) const;
00067 
00068         bool empty() const;
00069 
00070         int size() const;
00071 
00072         // void clear();
00073 
00074         // bool erase(_Tp& x);
00075 
00076 };
00077 
00078 template <class _Tp, class _Val> 
00079 MinHeap<_Tp, _Val>::MinHeap( std::pair< _Tp, _Val > x)
00080 {
00081     data.push_back(x);
00082     obj_to_pos.insert(std::make_pair(x.first, 0));
00083 }
00084 
00085 template <class _Tp, class _Val>
00086 bool MinHeap<_Tp, _Val>::set(_Tp& x, _Val& v)
00087 {
00088     std::map<_Tp, int>::iterator it = obj_to_pos.find(x);
00089     if (it == obj_to_pos.end())
00090     {
00091         push(std::make_pair(x, v));
00092         return true;
00093     }
00094     int index = it->second;
00095     data[index].second = v;
00096     index = percolate_up(index);
00097     if (index >= 0 && index < (int)data.size())
00098     {
00099         percolate_down(index); // if only we knew where to go (up/down)
00100         // normally for A*, we only go up when we set, and "up" when we push
00101         return true;
00102     }
00103     return false;
00104 }
00105 
00106 template <class _Tp, class _Val>
00107 void MinHeap<_Tp, _Val>::push(std::pair< _Tp, _Val > x)
00108 {
00109     int index = data.size();
00110     if (obj_to_pos.insert(std::make_pair(x.first, index)).second)
00111     {
00112         data.push_back(x);
00113         percolate_up(index);
00114     }
00115 }
00116 
00117 template <class _Tp, class _Val>
00118 int MinHeap<_Tp, _Val>::percolate_up(int index)
00119 {
00120     if (index < 0 || index >= (int)data.size())
00121         return -1;
00122     unsigned int parent = (index - 1) / 2;
00123     while (index > 0 && data[parent].second > data[index].second)
00124     {
00125         std::pair<_Tp, _Val> temp = data[parent];
00126         data[parent] = data[index];
00127         data[index] = temp;
00128         obj_to_pos.find(data[index].first)->second = index;
00129         index = parent;
00130         parent = (index - 1) / 2;
00131     }
00132     return index;
00133 }
00134 
00135 template <class _Tp, class _Val>
00136 int MinHeap<_Tp, _Val>::percolate_down(int index)
00137 {
00138     if (index < 0 || index >= (int)data.size())
00139         return -1;
00140     unsigned int lchild = index*2 + 1;
00141     unsigned int rchild = index*2 + 2;
00142     while ((data.size()>lchild && data[index].second>data[lchild].second) || 
00143             (data.size()>rchild && data[index].second>data[rchild].second))
00144     {
00145         unsigned int dest = lchild;
00146         if (data.size()>rchild && data[rchild].second<data[lchild].second)
00147             dest = rchild;
00148         std::pair< _Tp, _Val > temp = data[dest];
00149         data[dest] = data[index];
00150         data[index] = temp;
00151         obj_to_pos.find(data[index].first)->second = index;
00152         index = dest;
00153         lchild = index*2 + 1;
00154         rchild = index*2 + 2;
00155     }
00156     obj_to_pos.find(data[index].first)->second = index;
00157     return index;
00158 }
00159 
00160 template <class _Tp, class _Val>
00161 bool MinHeap<_Tp, _Val>::empty() const
00162 {
00163     return data.empty();
00164 }
00165 
00166 template <class _Tp, class _Val>
00167 const std::pair<_Tp, _Val>& MinHeap<_Tp, _Val>::top() const
00168 {
00169     return data.front();
00170 }
00171 
00172 template <class _Tp, class _Val>
00173 int MinHeap<_Tp, _Val>::size() const
00174 {
00175     return data.size();
00176 }
00177 
00178 template <class _Tp, class _Val>
00179 void MinHeap<_Tp, _Val>::pop()
00180 {
00181     if (data.empty())
00182         return;
00183     obj_to_pos.erase(data.front().first);
00184     data.front() = data.back();
00185     data.pop_back();
00186     if (data.empty())
00187         return;
00188     std::map<_Tp, int>::iterator it = obj_to_pos.find(data.front().first);
00189     if (it != obj_to_pos.end())
00190     {
00191         it->second = 0;
00192         percolate_down(0);
00193     }
00194 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines