BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Kinetic/Heap_pointer_event_queue.h
Go to the documentation of this file.
00001 // Copyright (c) 2005  Stanford University (USA).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Kinetic_data_structures/include/CGAL/Kinetic/Heap_pointer_event_queue.h $
00016 // $Id: Heap_pointer_event_queue.h 40832 2007-11-08 00:27:20Z ameyer $
00017 // 
00018 //
00019 // Author(s)     : Daniel Russel <drussel@alumni.princeton.edu>
00020 
00021 #ifndef CGAL_KINETIC_HEAP_POINTER_EVENT_QUEUE_H
00022 #define CGAL_KINETIC_HEAP_POINTER_EVENT_QUEUE_H
00023 #include <CGAL/Kinetic/basic.h>
00024 #include <iostream>
00025 #include <vector>
00026 #include <utility>
00027 #include <functional>
00028 #include <CGAL/assertions.h>
00029 #include <iostream>
00030 #include <CGAL/Kinetic/Ref_counted.h>
00031 #include <CGAL/Kinetic/internal/infinity_or_max.h>
00032 #include <algorithm>
00033 
00034 CGAL_KINETIC_BEGIN_INTERNAL_NAMESPACE
00035 
00036 template <class Priority>
00037 class Heap_pointer_event_queue_item_handle;
00038 
00039 // The interface for an item stored in the ::Heap_pointer_event_queue
00040 template <class Priority>
00041 class Heap_pointer_event_queue_item: public Ref_counted<Heap_pointer_event_queue_item<Priority> >
00042 {
00043   typedef Ref_counted<Heap_pointer_event_queue_item<Priority> > P;
00044 public:
00045 
00046   /* struct Key: public typename P::Handle {
00047     Key(){}
00048     Key(Item_handle h): P::Handle(h){}
00049     bool is_valid() const {
00050       return this->get() != NULL;
00051     }
00052     };*/
00053   typedef Heap_pointer_event_queue_item_handle<Priority>  Key;
00054 
00055   Heap_pointer_event_queue_item():bin_(-1), time_(infinity_or_max<Priority>(Priority(0))){}
00056   Heap_pointer_event_queue_item(int bin, const Priority &t): bin_(bin), time_(t){}
00057 
00058   virtual std::ostream& write(std::ostream &out) const =0;
00059   const Priority& time() const {return time_;};
00060   virtual void process() =0;
00061   virtual void audit(Key) const=0;
00062   virtual void *kds() const =0;
00063   virtual CGAL::Comparison_result compare_concurrent(Key a, Key b) const =0;
00064   void set_bin(int bin) const { bin_=bin;}
00065   int bin() const {return bin_;};
00066   virtual ~Heap_pointer_event_queue_item(){}
00067   //virtual const void *event() const=0;
00068 private:
00069   mutable int bin_;
00070   Priority time_;
00071 };
00072 
00073 CGAL_OUTPUT1(Heap_pointer_event_queue_item);
00074 
00075 
00076 template <class Priority>
00077 class Heap_pointer_event_queue_item_handle: public Ref_counted<Heap_pointer_event_queue_item<Priority> >::Handle
00078 {
00079   typedef typename Ref_counted<Heap_pointer_event_queue_item<Priority> >::Handle P;
00080 public:
00081   std::ostream &write(std::ostream &out) const {
00082     return P::operator*().write(out);
00083   }
00084   template <class T>
00085   Heap_pointer_event_queue_item_handle(T* t): P(t){}
00086   Heap_pointer_event_queue_item_handle(){}
00087   Heap_pointer_event_queue_item_handle(const P&p): P(p){}
00088 };
00089 
00090 CGAL_OUTPUT1(Heap_pointer_event_queue_item_handle);
00091 
00092 // The how a dummy item is stored in the ::Heap_pointer_event_queue
00093 /*
00094   One dummy item is used to represent events which will never happen.
00095 */
00096 template <class Priority>
00097 class Heap_pointer_event_queue_dummy_item: public Heap_pointer_event_queue_item<Priority>
00098 {
00099   typedef Heap_pointer_event_queue_item<Priority> P;
00100 public:
00101   Heap_pointer_event_queue_dummy_item(): P(-2, internal::infinity_or_max(Priority())){}
00102   virtual void process() {
00103   }
00104   virtual void *kds() const {return NULL;}
00105   virtual CGAL::Comparison_result compare_concurrent(typename P::Key a, 
00106                                                      typename P::Key b) const {
00107     if (a < b) return CGAL::SMALLER;
00108     else if (b < a) return CGAL::LARGER;
00109     else return CGAL::EQUAL;
00110     //return CGAL::compare(a,b);
00111   }
00112   virtual std::ostream& write(std::ostream &out) const
00113   {
00114     out << "Never.";
00115     return out;
00116   }
00117   virtual void audit(typename P::Key) const {
00118     std::cout << "Auditing a dummy event" << std::endl;
00119   }
00120   virtual ~Heap_pointer_event_queue_dummy_item(){}
00121 };
00122 
00123 // The how a real item is stored in the ::Heap_pointer_event_queue
00124 /*
00125   This just stores an object of type Event and passes the virtual calls on to it.
00126 
00127   The object is reference counted so you don't have to worry about the
00128   queue deleting it or not.
00129 */
00130 template <class Priority, class Event>
00131 class Heap_pointer_event_queue_item_rep: public internal::Heap_pointer_event_queue_item<Priority>
00132 {
00133   typedef internal::Heap_pointer_event_queue_item<Priority> P;
00134 public:
00135   //typedef CGAL::Ref_counted_pointer<Heap_pointer_event_queue_item_rep<Priority, Event> > Pointer;
00136   //typedef CGAL::Ref_counted_pointer<const Heap_pointer_event_queue_item_rep<Priority, Event> > Const_pointer;
00137   Heap_pointer_event_queue_item_rep(): internal::Heap_pointer_event_queue_item<Priority>(){}
00138   Heap_pointer_event_queue_item_rep(const Priority &t, const Event &e,
00139                                     unsigned int bin): internal::Heap_pointer_event_queue_item<Priority>(bin, t),
00140                                                        event_(e){}
00141   virtual void process() {
00142     event_.process();
00143   }
00144   virtual void *kds() const {return event_.kds();}
00145   virtual CGAL::Comparison_result compare_concurrent(typename P::Key a, 
00146                                                      typename P::Key b) const {
00147     return event_.compare_concurrent(a,b);
00148   }
00149   virtual void audit(typename P::Key k) const {
00150     event_.audit(k);
00151   }
00152   virtual std::ostream& write(std::ostream &out) const
00153   {
00154     out << "(";
00155     event_.write(out);
00156     out << ")";
00157     return out;
00158   }
00159   // Access the actual event
00160   /*
00161     There is no non-const access so you can't change the time.
00162   */
00163   const Event &event() const
00164   {
00165     return event_;
00166   }
00167   Event &event()
00168   {
00169     return event_;
00170   }
00171   void set_event(const Event &e) {
00172     event_=e;
00173   }
00174   virtual ~Heap_pointer_event_queue_item_rep(){}
00175 
00176 protected:
00177   Event event_;
00178 };
00179 
00180 CGAL_KINETIC_END_INTERNAL_NAMESPACE
00181 
00182 CGAL_KINETIC_BEGIN_NAMESPACE
00183 
00184 template <class Priority> class Bin_pointer_event_queue;
00185 
00187 
00198 template <class FK, bool INF=false>
00199 class Heap_pointer_event_queue
00200 {
00201 public:
00202   typedef typename FK::Root Priority;
00203   friend class Bin_pointer_event_queue<Priority>;
00204   typedef Heap_pointer_event_queue<Priority> This;
00205   typedef internal::Heap_pointer_event_queue_item<Priority> Item;
00206   typedef typename Item::Handle Item_handle;
00207   typedef enum Child {FIRST=0, SECOND=1}
00208     Child;
00209 
00210   class Compare
00211   {
00212   public:
00213     Compare(){}
00214     bool operator()(Item_handle i0, Item_handle i1) const
00215     {
00216       CGAL::Comparison_result cr= CGAL::compare(i0->time(), i1->time());
00217       if (cr == CGAL::SMALLER) return true;
00218       else if (cr == CGAL::LARGER) return false; 
00219       else {
00220         if (i0->kds() < i1->kds()) return true;
00221         else if (i0->kds() > i1->kds()) return false;
00222         else {
00223           cr= i0->compare_concurrent(Key(i0), Key(i1));
00224           if (cr == CGAL::SMALLER) return true;
00225           else if (cr == CGAL::LARGER) return false;
00226           else {
00227             //CGAL_error();
00228             return false;
00229           }
00230         }
00231         
00232       }
00233     }
00234   };
00235 
00236 
00237   //typedef Priority_t Priority;
00238 
00240 
00243   typedef typename Item::Key Key;
00244   /*struct Key: public Item_handle {
00245     Key(){};
00246     Key(Item*i): Item_handle(i){}
00247     Key(Item_handle ih): Item_handle(ih){}
00248     static Key null() {
00249     return Key();
00250     }
00251     };*/
00252   //typedef Item_handle Key;
00253 
00255   Heap_pointer_event_queue(const Priority&, const Priority &end, FK, int sz=1000): end_(end) {
00256     queue_.reserve(sz);
00257     null_event_= Key(new internal::Heap_pointer_event_queue_dummy_item<Priority>());
00258   }
00259 
00260   Heap_pointer_event_queue(const Priority&, FK, int sz=1000) {
00261     queue_.reserve(sz);
00262     null_event_= Key(new internal::Heap_pointer_event_queue_dummy_item<Priority>());
00263   }
00264 
00265   const Priority& end_priority() const
00266   {
00267     return end_;
00268   }
00269 
00270   void set_interval(const Priority &, const Priority &e)
00271   {
00272     end_=e;
00273   }
00274 
00275   bool is_after_end(const Priority &t) const {
00276     if (INF) return false;
00277     else return  CGAL::compare(t,end_priority()) == CGAL::LARGER;
00278   }
00279   void audit_events() const {
00280     for (typename  std::vector<Item_handle>::const_iterator it= queue_.begin(); 
00281          it != queue_.end(); ++it) {
00282       (* it)->audit(Key(*it));
00283     }
00284   }
00285 
00286   void audit_event(Key k) const {
00287     k->audit(k);
00288   }
00289 
00291 
00294   template <class E>
00295   Key insert(const Priority &t, const E & e) {
00296     if (!is_after_end(t)) {
00297       Item_handle k= new internal::Heap_pointer_event_queue_item_rep<Priority, E>(t, e, queue_.size());
00298       queue_.push_back(k);
00299       bubble_up(queue_.size()-1);
00300       //std::push_heap(queue_.begin(), queue_.end());
00301       CGAL_expensive_postcondition(is_valid());
00302       CGAL_postcondition(k->bin() != -1);
00303       return Key(k);
00304     } else {
00305       return null_event_;
00306     }
00307   }
00308 
00310   void erase(const Key &item) {
00311     if (item == end_key()) return;
00312     CGAL_expensive_precondition(item != Key());
00313     CGAL_expensive_precondition(is_in_heap(item));
00314     int bin= item->bin();
00315     //if (bin ==-1) return;
00316     CGAL_precondition(static_cast<unsigned int> (bin) < queue_.size() && bin >= 0);
00317 
00318     // this is a bit more work than strictly necessary
00319     swap(queue_.size()-1, bin);
00320     queue_.pop_back();
00321     if (static_cast<unsigned int>(bin) < queue_.size()) {
00322       bubble(bin);
00323     }
00324     item->set_bin(-1);
00325     CGAL_expensive_postcondition(is_valid());
00326   }
00327 
00329 
00330   /*
00331     template <class E>
00332     struct Event_pointer {
00333     typedef const Heap_pointer_event_queue_item_rep<Priority, E>* Pointer;
00334     struct Handle: public  Heap_pointer_event_queue_item_rep<Priority, E>::Const_pointer {
00335     Handle(Pointer p):
00336     Heap_pointer_event_queue_item_rep<Priority, E>
00337     ::Const_pointer(reinterpret_cast<const Heap_pointer_event_queue_item_rep<Priority, E>*>(p)){
00338     }
00339     Handle(){}
00340 
00341     };
00342     };*/
00343 
00345 
00351   /*template <class E>
00352     typename Event_pointer<E>::Pointer event(const Key &item, const E &) const {
00353     return reinterpret_cast<typename Event_pointer<E>::Pointer >( item.get());
00354     }*/
00355 
00356   template <class E>
00357   const E& get(const Key &item) const
00358   {
00359     CGAL_precondition(item && item != null_event_);
00360     return reinterpret_cast<internal::Heap_pointer_event_queue_item_rep<Priority, E>*>( item.get())->event();
00361   }
00362 
00363 
00364   template <class E>
00365   E& get(Key item)
00366   {
00367     CGAL_precondition(item && item != null_event_);
00368     typename internal::Heap_pointer_event_queue_item<Priority> *ptr= item.get();
00369     typename internal::Heap_pointer_event_queue_item_rep<Priority, E>* nptr
00370       = reinterpret_cast<internal::Heap_pointer_event_queue_item_rep<Priority, E>*>(ptr);
00371     return nptr->event();
00372   }
00373 
00375 
00378   template <class NE>
00379   Key set(const Key &item, const NE &ne) {
00380     CGAL_expensive_precondition(is_in_heap(item));
00381     CGAL_precondition(item && item != null_event_);
00382     //CGAL_expensive_precondition(item.get()->time() == ne.time());
00383     CGAL_expensive_precondition(item);
00384     int bin = item.get()->bin();
00385     CGAL_expensive_precondition(Key(queue_[bin])==item);
00386     queue_[bin]= new internal::Heap_pointer_event_queue_item_rep<Priority, NE>(item.get()->time(), ne, bin);
00387     CGAL_expensive_postcondition(is_valid());
00388     return queue_[bin];
00389   }
00390 
00392 
00395   Priority front_priority() const
00396   {
00397     CGAL_precondition(!queue_.empty());
00398     return queue_.front()->time();
00399   }
00400 
00402   const Priority& priority(const Key &item) const
00403   {
00404     CGAL_precondition(item);
00405     return item->time();
00406   }
00407 
00409   bool empty() const
00410   {
00411     return queue_.empty();
00412   }
00413 
00415   void clear() {
00416     // ref counted pointers are nice.
00417     queue_.clear();
00418   }
00419 
00420 
00421 
00423 
00426   void process_front() {
00427     CGAL_precondition(!empty());
00428     //if (queue_.front()->time() < end_priority()) {
00429     //CGAL_precondition_code(Item_handle k= queue_.front());
00430     CGAL_LOG(Log::SOME, "Processing " << queue_.front() << std::endl);
00431     Item_handle ih= queue_.front();
00432     pop_front();
00433     //std::pop_heap(queue_.begin(), queue_.end());
00434     ih->process();
00435     //CGAL_expensive_postcondition(is_valid());
00436     /*}
00437       else {
00438       clear();
00439       }*/
00440   }
00441 
00443   bool print() const
00444   {
00445     write(std::cout);
00446     return true;
00447   }
00448   /*
00449     void process_final_events() {
00450     bool do_i_use_this;
00451     std::vector<Item_handle> c;
00452     c.swap(final_events_);
00453     for (unsigned int i=0; i< c.size(); ++i){
00454     c[i]->set_processed(true);
00455     }
00456     }*/
00458 
00461   bool write(std::ostream &out) const
00462   {
00463     //std::cout << "Not writing queue.\n";
00464     //return true;
00465 #if 0
00466     std::vector<Item_handle> bins;
00467 
00468     for (unsigned int i=0; i< queue_.size(); ++i) {
00469       bins.push_back(queue_[i]);
00470     }
00471 
00472     std::sort(bins.begin(), bins.end(), compare_);
00473 
00474     typename std::vector<Item_handle>::const_iterator curi= bins.begin(), endi= bins.end();
00475 #else
00476     typename std::vector<Item_handle>::const_iterator curi= queue_.begin(), endi= queue_.end();
00477 #endif
00478     for (; curi != endi; ++curi) {
00479       Priority t=(*curi)->time();
00480       // HACK HACK because CGAL::to_double(t) won't compile with gcc 3.4
00481       std::pair<double,double> d= CGAL::to_interval(t);
00482       //CGAL::to_double(t);
00483       out << "<" << d.first << "..." << d.second << ": ";
00484       (*curi)->write(out);
00485       out << ">\n";
00486     }
00487     out << std::endl;
00488 #if 0
00489     for (unsigned int i=1; i< bins.size(); ++i) {
00490       if (bins[i-1]->time()== bins[i]->time()) {
00491         out << "Warning, two concurrent events: " << bins[i] << " and "
00492             << bins[i-1] << " at time " << bins[i]->time() << std::endl;
00493       }
00494     }
00495 #endif
00496 
00497     /*if (!final_events.empty()) {
00498       out << "Finally: \n";
00499       for (unsigned int i=0; i< final_events_.size(); ++i){
00500         final_events_[i]->write(out) << std::endl;
00501       }
00502       }*/
00503 
00504     
00505     //out << std::endl;
00506     return false;
00507   }
00508 
00509   Key end_key() const
00510   {
00511     return null_event_;
00512   }
00513 
00514   bool contains(Key k) const {
00515     return is_in_heap(k);
00516   }
00517 
00518 
00519   Key front() const {
00520     return Key(queue_.front());
00521   }
00522 
00523 
00524 protected:
00526   std::vector<Item_handle> queue_;
00527   Compare compare_;
00528   //std::vector<Item_handle> final_events_;
00529   Key null_event_;
00530   Priority end_;
00531 
00532   bool is_in_heap(Key k) const
00533   {
00534     for (unsigned int i=0; i< queue_.size(); ++i) {
00535       if (queue_[i]==k) return true;
00536     }
00537     return false;
00538   }
00539 
00541   void swap(unsigned int i, unsigned int j) {
00542     std::swap(queue_[i], queue_[j]);
00543     int bin= queue_[i]->bin();
00544     queue_[i]->set_bin(queue_[j]->bin());
00545     queue_[j]->set_bin(bin);
00546   }
00547 
00549   int parent(unsigned int i) const
00550   {
00551     return (static_cast<int>(i)-1)/2;
00552   };
00553 
00555   unsigned int child(unsigned int i, Child which) const
00556   {
00557     return 2*i+1+which;
00558   }
00559 
00561   bool less_items(unsigned int i, unsigned int j) const
00562   {
00563     if (static_cast<unsigned int>(j) >= queue_.size()) return true;
00564     else if (static_cast<unsigned int>(i) >= queue_.size()) return false;
00565     else {
00566       return compare_(queue_[i], queue_[j]);
00567     }
00568   }
00570   bool less_than_child(unsigned int  i, unsigned int c) const
00571   {
00572     int ch= child(i,c);
00573     return less_items(i, ch);
00574   }
00576   bool less_than_parent(unsigned int i) const
00577   {
00578     if (i==0) return false;
00579     else return less_items(i, parent(i));
00580   }
00581 
00583   void pop_front() {
00584     CGAL_expensive_precondition(!empty());
00585     Item_handle item= queue_.front();
00586     swap(0, queue_.size()-1);
00587     queue_.back()->set_bin(-1);
00588     queue_.pop_back();
00589     if (!queue_.empty()) bubble_down(0);
00590   }
00591 
00593   void bubble_down(unsigned int i) {
00594     CGAL_expensive_precondition(i<queue_.size());
00595     while (i < queue_.size()) {
00596       unsigned int lc= child(i,FIRST), rc= child(i,SECOND);
00597       if (!less_items(rc, lc)) {        // make the sorting stable
00598         if (less_items(lc, i)) {
00599           swap(i, lc);
00600           i=lc;
00601         } else break;
00602       }
00603       else {
00604         if (less_items(rc, i)) {
00605           swap(i, rc);
00606           i=rc;
00607         } else break;
00608       }
00609     }
00610   }
00612   void bubble_up(unsigned int i) {
00613     CGAL_expensive_precondition(i< queue_.size());
00614     while (less_than_parent(i)) {
00615       swap(i, parent(i));
00616       i=parent(i);
00617     }
00618   }
00620   void bubble(unsigned int i) {
00621     bubble_up(i);
00622     bubble_down(i);
00623   }
00624 
00626   bool is_valid() const
00627   {
00628     for (unsigned int i=0; i< queue_.size(); ++i) {
00629       //int bin= i;
00630       int back= queue_[i]->bin();
00631       CGAL_assertion(static_cast<unsigned int>(back)==i || write(std::cerr));
00632       CGAL_assertion(!less_than_parent(i) || write(std::cerr));
00633       //CGAL_assertion(less_than_child(i, FIRST));
00634       //CGAL_assertion(less_than_child(i, SECOND));
00635     }
00636     return true;
00637   }
00638 
00639 };
00640 
00641 template <class D, bool INF>
00642 std::ostream &operator<<(std::ostream &out, const Heap_pointer_event_queue<D, INF> &q)
00643 {
00644   q.write(out);
00645   return out;
00646 }
00647 
00648 
00649 CGAL_KINETIC_END_NAMESPACE
00650 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines