/home/jpiovano/src/Odyssee++/trunk/Libs/LevelSet/src/PriorityQueue.h
Go to the documentation of this file.00001
00009 #ifndef PRIORITY_QUEUE_H
00010 #define PRIORITY_QUEUE_H
00011
00012 #include <list>
00013 #include <cmath>
00014 #include <iomanip>
00015
00016 namespace levelset {
00017
00031 template <class Element>
00032 class PriorityQueue
00033 {
00034 public:
00035 typedef std::list<Element> ElementList;
00036 typedef typename ElementList::iterator ElementListIterator;
00037 typedef std::pair<ElementListIterator, int> QueuePosition;
00038
00041
00043 PriorityQueue(unsigned _size = 2000,
00044 double _inc_max = 3
00045 );
00046
00048 ~PriorityQueue();
00049
00051
00053
00054
00056 bool empty() const;
00058 QueuePosition push(const Element &e, double t);
00060 void pop();
00062 const Element & top();
00064 QueuePosition increase_priority(const Element& e, QueuePosition& pos, double t_new);
00066 void clear();
00068 unsigned size() const;
00069
00071 void print() const;
00072
00073 private:
00074
00076
00078
00079 ElementList * m_tab;
00080 unsigned m_size;
00081 unsigned m_nb_elem;
00082 double m_t0;
00083 int m_i0;
00084 double m_delta;
00085 double m_inc_max;
00086
00088 };
00089
00090
00092
00093
00094
00095 template <class Element>
00096 PriorityQueue<Element>::PriorityQueue(unsigned _size, double _inc_max)
00097 : m_size(_size), m_t0(0), m_i0(0), m_nb_elem(0),m_inc_max(_inc_max)
00098 {
00099 m_tab = new ElementList[_size];
00100 m_delta = _inc_max / static_cast<double>(_size);
00101 }
00102
00103 template <class Element>
00104 PriorityQueue<Element>::~PriorityQueue()
00105 {
00106 delete[] m_tab;
00107 }
00108
00109
00111
00112
00113
00114 template <class Element>
00115 bool PriorityQueue<Element>::empty() const
00116 {
00117 return (m_nb_elem == 0);
00118 }
00119
00120 template <class Element>
00121 typename PriorityQueue<Element>::QueuePosition PriorityQueue<Element>::push(const Element &e, double t)
00122 {
00123
00124 if (t-m_t0 > m_inc_max)
00125 std::cerr << "Warning : Increment " << t-m_t0 << " superior to maximum increment " << m_inc_max << std::endl;
00126 else if (t-m_t0 < 0)
00127 std::cerr << "Warning : Priority " << t << " inferior to the lowest priority in the queue " << m_t0 << std::endl;
00128
00129 int i = 0;
00130 if (empty()) {
00131 m_t0 = t;
00132 m_i0 = 0;
00133 }
00134 else {
00135
00136 i = static_cast<int>(floor((t-m_t0) * m_size / m_inc_max));
00137
00138
00139 i = (i >= m_size)? m_size-1 : ((i < 0)? 0 : i);
00140 i = (i + m_i0) % m_size;
00141 }
00142
00143 m_nb_elem++;
00144 m_tab[i].push_front(e);
00145 return QueuePosition(m_tab[i].begin(), i);
00146 }
00147
00148 template <class Element>
00149 void PriorityQueue<Element>::pop()
00150 {
00151 if (empty()) return;
00152
00153
00154 while (m_tab[m_i0].empty()){
00155 m_i0 = (m_i0 + 1) % m_size;
00156 m_t0 += m_delta;
00157 }
00158
00159 m_nb_elem--;
00160 m_tab[m_i0].pop_back();
00161 }
00162
00163 template <class Element>
00164 const Element & PriorityQueue<Element>::top()
00165 {
00166
00167 while (m_tab[m_i0].empty()){
00168 m_i0 = (m_i0 + 1) % m_size;
00169 m_t0 += m_delta;
00170 }
00171
00172 return m_tab[m_i0].back();
00173 }
00174
00175 template <class Element>
00176 typename PriorityQueue<Element>::QueuePosition PriorityQueue<Element>::increase_priority(const Element& e, QueuePosition& pos, double t_new)
00177 {
00178 if (t_new-m_t0 > m_inc_max)
00179 std::cerr << "Warning : Increment " << t_new-m_t0 << " superior to maximum increment" << m_inc_max << std::endl;
00180 else if (t_new - m_t0 < 0)
00181 std::cerr << "Warning : Priority " << t_new << " inferior to the lowest priority in the queue " << m_t0 << std::endl;
00182
00183
00184 int i = static_cast<int>(floor((t_new-m_t0) * m_size / m_inc_max));
00185
00186 i = (i >= m_size)? m_size-1 : ((i < 0)? 0 : i);
00187 i = (i + m_i0) % m_size;
00188
00189 m_tab[pos.second].erase(pos.first);
00190 m_tab[i].push_front(e);
00191 return QueuePosition(m_tab[i].begin(), i);
00192 }
00193
00194 template <class Element>
00195 void PriorityQueue<Element>::clear()
00196 {
00197 m_nb_elem = 0;
00198 m_t0 = 0;
00199 m_i0 = 0;
00200 for (int i= 0 ; i<m_size ; i++)
00201 m_tab[i].clear();
00202 }
00203
00204 template <class Element>
00205 unsigned PriorityQueue<Element>::size() const
00206 {
00207 return m_nb_elem;
00208 }
00209
00210 template <class Element>
00211 void PriorityQueue<Element>::print() const
00212 {
00213 std::cout << "-------------------------------------" << std::endl;
00214 std::cout << "m_t0 = " << m_t0 << std::endl;
00215 std::cout << "m_i0 = " << m_i0 << std::endl;
00216 std::cout << "size = " << m_nb_elem << std::endl;
00217 for (int i = 0; i < m_size; i++){
00218 if (!m_tab[i].empty()){
00219
00220 int j = (i-(int)m_i0 >= 0)? i-(int)m_i0 : i-(int)m_i0+m_size;
00221
00222
00223 std::cout << " i=" << std::setw(2) << i
00224 << "| l=" << std::setw(2) << j
00225 << "| p=" << std::setw(5) << m_t0 + j*m_delta
00226 << "->" << std::setw(5) << m_t0 + j*m_delta + m_delta;
00227
00228 for (typename ElementList::iterator it = m_tab[i].begin() ; it!= m_tab[i].end() ; it++)
00229 std::cout << " " << *it ;
00230
00231 std::cout << std::endl;
00232 }
00233 }
00234 }
00235
00236 }
00237
00238 #endif // PRIORITY_QUEUE_H