BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Kinetic/Two_list_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/Two_list_pointer_event_queue.h $
00016 // $Id: Two_list_pointer_event_queue.h 41341 2007-12-27 16:23:41Z spion $
00017 // 
00018 //
00019 // Author(s)     : Daniel Russel <drussel@alumni.princeton.edu>
00020 
00021 #ifndef CGAL_KINETIC_BIN_QUEUE_H
00022 #define CGAL_KINETIC_BIN_QUEUE_H
00023 #include <CGAL/Kinetic/basic.h>
00024 #include <iostream>
00025 #include <CGAL/Kinetic/internal/debug_counters.h>
00026 #include <CGAL/In_place_list.h>
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 #include <boost/utility.hpp>
00034 #include <boost/type_traits/remove_const.hpp>
00035 #include <CGAL/Kinetic/internal/debug_counters.h>
00036 
00037 //int two_list_remaining=0;
00038 
00039 //int growth__=0;
00040 //int shrink__=0;
00041 //int queue_insertions__=0;
00042 //int queue_front_insertions__=0;
00043 
00044 CGAL_KINETIC_BEGIN_INTERNAL_NAMESPACE
00045 
00046 
00047 template <class Item>
00048 struct Two_list_pointer_event_queue_key: public Item::Handle
00049 {
00050   typedef Two_list_pointer_event_queue_key<Item> This;
00051   typedef typename Item::Handle P;
00052   Two_list_pointer_event_queue_key(){};
00053   Two_list_pointer_event_queue_key(Item  *p): Item::Handle(p){}
00054   std::ostream& write(std::ostream &out) {
00055     if (Item::Handle::get()) {
00056       out << "(" << Item::Handle::get() << ": " << *Item::Handle::get() << ")";
00057     }
00058     else {
00059       out << "null";
00060     }
00061     return out;
00062   }
00063   /*operator bool() const
00064     {
00065     return Item::Handle::get() != NULL;
00066     }*/
00067   bool is_valid() const {
00068     return  Item::Handle::get() != NULL;
00069   }
00070   /*bool operator!() const
00071     {
00072     return Item::Handle::operator!();
00073     }*/
00074   bool operator==(const This &o) const
00075   {
00076     return Item::Handle::get() == o.get();
00077   }
00078   bool operator!=(const This &o) const
00079   {
00080     return Item::Handle::get() != o.get();
00081   }
00082   //using P::operator<;
00083   bool operator<(const This& o) const
00084   {
00085     return P::get() < o.get();
00086   }
00087 
00088   Item* pointer() {
00089     return Item::Handle::get();
00090   }
00091   const Item* pointer() const
00092   {
00093     return Item::Handle::get();
00094   }
00095  
00096   //using P::operator>;
00097 };
00098 
00099 template  <class I>
00100 std::ostream &operator<<(std::ostream &out, Two_list_pointer_event_queue_key<I> k)
00101 {
00102   k.write(out);
00103   return out;
00104 }
00105 
00106 
00107 
00108 
00109 // The interface for an item stored in the ::Pointer_event_queue
00110 template <class Priority>
00111 class Two_list_event_queue_item:
00112   public CGAL::In_place_list_base<Two_list_event_queue_item<Priority> >,
00113   public Ref_counted<Two_list_event_queue_item<Priority> >
00114 {
00115 
00116   typedef Two_list_event_queue_item<Priority> This;
00117 
00118   Two_list_event_queue_item(const Two_list_event_queue_item &o){bool do_not_copy;}
00119   void operator=(const Two_list_event_queue_item &o) {
00120     bool do_not_copy;
00121   }
00122 public:
00123   typedef Two_list_pointer_event_queue_key<This> Key;
00124   Two_list_event_queue_item() { /*++two_list_remaining;*/}
00125   Two_list_event_queue_item(const Priority &t): time_(t){/*++two_list_remaining;*/}
00126   virtual ~Two_list_event_queue_item(){/*--two_list_remaining;*/
00127   }
00128 
00129   enum List {FRONT, BACK, INF};
00130 
00131   const Priority& time() const {return time_;};
00132 
00133   List in_list() const
00134   {
00135     return front_list_;
00136   }
00137   void set_in_list(List lt) {
00138     front_list_=lt;
00139   }
00140 
00141   
00142 
00143   bool operator<(const This &o) const {
00144     CGAL::Comparison_result c= CGAL::compare(time(), o.time());
00145     if (c != CGAL::EQUAL) return c== CGAL::SMALLER;
00146     else {
00147       if (kds() < o.kds()) return true;
00148       else if (kds() > o.kds()) return false;
00149       else {
00150         CGAL::Comparison_result c= compare_concurrent(Key((This*) this),Key((This*) &o));
00151         return c==CGAL::SMALLER;
00152       }
00153     }
00154   }
00155 
00156   virtual std::ostream& write(std::ostream &out) const{
00157     out << "Dummy event." << std::endl;
00158     return out;
00159   }
00160   virtual void process() {
00161     CGAL_error();
00162     CGAL_ERROR("Writing dummy queue element.");
00163   }
00164   virtual CGAL::Comparison_result compare_concurrent(Key , Key ) const {
00165     CGAL_error();
00166     return CGAL::EQUAL;
00167   };
00168   virtual bool merge_concurrent(Key , Key ) {
00169     CGAL_error();
00170     return false;
00171   }
00172   virtual void *kds() const{return NULL;}
00173   virtual void audit(Key) const{};
00174 private:
00175   Priority time_;
00176   List front_list_;
00177 };
00178 
00179 template <class Priority>
00180 inline std::ostream& operator<<(std::ostream &out, const Two_list_event_queue_item<Priority> &i)
00181 {
00182   i.write(out);
00183   return out;
00184 }
00185 
00186 
00187 // The how a dummy item is stored in the ::Two_list_event_queue
00188 /*
00189   One dummy item is used to represent events which will never happen.
00190 */
00191 /*template <class Priority>
00192 class Two_list_event_queue_dummy_item: public Two_list_event_queue_item<Priority>
00193 {
00194   typedef Two_list_event_queue_item<Priority> P;
00195 public:
00196   Two_list_event_queue_dummy_item(){}
00197   Two_list_event_queue_dummy_item(const Two_list_event_queue_dummy_item &):
00198     Two_list_event_queue_item<Priority>(){}
00199   virtual void process() {
00200     std::cerr << "Trying to process a NULL event.\n";
00201     CGAL_error();
00202   }
00203   virtual CGAL::Comparison_result compare_concurrent(typename P::Key , typename P::Key ) const{return CGAL::EQUAL;}
00204   virtual bool merge_concurrent(typename P::Key, typename P::Key){
00205     return false;
00206   }
00207   virtual std::ostream& write(std::ostream &out) const
00208   {
00209     out << "Never";
00210     return out;
00211   }
00212   virtual ~Two_list_event_queue_dummy_item(){}
00213   };*/
00214 
00215 // The how a real item is stored in the ::Two_list_event_queue
00216 /*
00217   This just stores an object of type Event and passes the virtual calls on to it.
00218 
00219   The object is reference counted so you don't have to worry about the
00220   queue deleting it or not.
00221 */
00222 template <class Priority, class Event>
00223 class Two_list_event_queue_item_rep: public internal::Two_list_event_queue_item<Priority>
00224 {
00225   typedef  Two_list_event_queue_item<Priority> P;
00226 public:
00227   Two_list_event_queue_item_rep(): internal::Two_list_event_queue_item<Priority>(){}
00228   Two_list_event_queue_item_rep(const Priority &t, const Event &e): 
00229     Two_list_event_queue_item<Priority>(t),
00230     event_(e){}
00231 
00232   virtual std::ostream& write(std::ostream &out) const
00233   {
00234     event_.write(out);
00235     out << " at " << P::time();
00236     return out;
00237   }
00238   virtual void process() {
00239     event_.process();
00240   }
00241   virtual void audit(typename P::Key k) const {
00242     event_.audit(k);
00243   }
00244   virtual CGAL::Comparison_result compare_concurrent(typename P::Key a, typename P::Key b) const{
00245     return event_.compare_concurrent(a,b);
00246   }
00247   virtual bool merge_concurrent(typename P::Key a, typename P::Key b){
00248     return event_.merge_concurrent(a,b);;
00249   }
00250   virtual void *kds() const{return event_.kds();}
00251 
00252   // Access the actual event
00253   const Event &event() const
00254   {
00255     return event_;
00256   }
00257 
00258  // Access the actual event
00259   Event &event()
00260   {
00261     return event_;
00262   }
00263   
00264   virtual ~Two_list_event_queue_item_rep(){}
00265 
00266 protected:
00267   Event event_;
00268 };
00269 
00270 
00271 /* This is needed since the list cannot allocate an element of the abstract base class. I could just make it non-abstract. Why not?*/
00272 /*template <class T>
00273 struct Two_list_event_queue_item_allocator
00274 {
00275   typedef Two_list_event_queue_dummy_item<T> dummy_value_type;
00276 
00277   typedef Two_list_event_queue_item<T>* pointer;
00278   typedef std::size_t size_type;
00279   typedef std::ptrdiff_t difference_type;
00280   typedef const pointer const_pointer;
00281   typedef Two_list_event_queue_item<T>& reference;
00282   typedef const Two_list_event_queue_item<T>& const_reference;
00283   typedef dummy_value_type value_type;
00284 
00285   Two_list_event_queue_item_allocator(){}
00286   pointer allocate(size_t sz, void* =0) const
00287   {
00288     return static_cast<pointer>(::operator new(sz*sizeof(dummy_value_type)));
00289   }
00290   void deallocate(pointer p, size_type ) {
00291     ::operator delete(static_cast<void*>(p));
00292   }
00293   size_type max_size() const throw() {
00294     return (std::numeric_limits<size_type>::max)()/sizeof(dummy_value_type);
00295   }
00296   template <class TT>
00297   void construct(pointer p, const TT &) {
00298     new(static_cast<void*>(p)) dummy_value_type();
00299   }
00300   void destroy(pointer p) {
00301     p->~Two_list_event_queue_item<T>();
00302   }
00303   };*/
00304 
00305 CGAL_KINETIC_END_INTERNAL_NAMESPACE
00306 
00307 CGAL_KINETIC_BEGIN_NAMESPACE
00308 
00309 
00310 
00311 
00313 
00324 template <class FK, bool INF=false, unsigned int TARGET=8>
00325 class Two_list_pointer_event_queue
00326 {
00327   typedef typename FK::Root PriorityT;
00328   typedef typename FK::FT NT;
00329   typedef Two_list_pointer_event_queue<FK, INF, TARGET> This;
00330   typedef typename internal::Two_list_event_queue_item<PriorityT> Item;
00331 
00332   typedef typename CGAL::In_place_list<Item, false/*,
00333                                                     internal::Two_list_event_queue_item_allocator<PriorityT>*/ > Queue;
00334   typedef typename Queue::iterator Iterator;
00335 
00336 
00337 
00338 
00339 public:
00340   typedef PriorityT Priority;
00341 
00342   typedef internal::Two_list_pointer_event_queue_key<Item> Key;
00343 
00344 
00345 
00346 
00348   Two_list_pointer_event_queue(Priority start_time,
00349                                Priority end_time, 
00350                                FK, int =0):
00351     null_event_(new internal::Two_list_event_queue_item<Priority>()){
00352     CGAL_precondition(!INF);
00353     initialize(start_time, end_time);
00354   }
00355 
00357   Two_list_pointer_event_queue(Priority start_time,
00358                                FK, int =0): 
00359     null_event_(new internal::Two_list_event_queue_item<Priority>()){
00360     CGAL_precondition(INF);
00361     initialize(start_time);
00362   }
00363 
00364   ~Two_list_pointer_event_queue() {
00365     // release pointers
00366     std::vector<Key> all;
00367     all.reserve(front_.size()+back_.size());
00368     for (typename Queue::iterator it = front_.begin(); 
00369          it != front_.end(); ++it) {
00370       all.push_back(Key(&*it));
00371     }
00372     for (typename Queue::iterator it = back_.begin(); 
00373          it != back_.end(); ++it) {
00374       all.push_back(Key(&*it));
00375     }
00376     front_.clear();
00377     back_.clear();
00378     for (unsigned int i=0; i< all.size(); ++i) {
00379       unmake_event(all[i].get());
00380     }
00381   }
00382 
00383   
00384   /*template <class E>
00385   Key insert_at_end(const E & e) {
00386 
00387   }*/
00388   
00389 
00390   bool is_after_end(const Priority &t) const {
00391     if (INF) return false; 
00392     else return  CGAL::compare(t,end_priority()) == CGAL::LARGER;
00393   }
00394 
00396 
00399   template <class E>
00400   Key insert(const Priority &t, const E & e) {
00401     CGAL_expensive_precondition(audit());
00402  
00403 
00404     Item *ni = make_event(t, e);
00405 
00406     //CGAL_exactness_assertion(t >= lbs_);
00407     //lb_=(std::min)(t, lb_);
00408     if ( is_after_end(ni->time())){
00409       return end_key();
00410     } 
00411 
00412 
00413     if (leq_ub(ni->time())) {
00414       ni->set_in_list(Item::FRONT);
00415       typename Queue::iterator iit=std::upper_bound(front_.begin(), front_.end(), *ni);
00416    
00417       front_.insert(iit, *ni);
00418       CGAL_expensive_assertion(audit());
00419       if (front_.size() > 2*max_front_size()) {
00420         shrink_front();
00421       }
00422       //++queue_front_insertions__;
00423     }  else if (front_.empty()) {
00424       CGAL_assertion(back_.empty());
00425       CGAL_assertion(INF || CGAL::compare(t, end_priority()) != CGAL::LARGER);
00426       //CGAL_assertion(INF || CGAL::compare(end_priority(), std::numeric_limits<Priority>::infinity()) == CGAL::SMALLER);
00427       if (true){
00428         //++queue_front_insertions__;
00429         front_.push_back(*ni);
00430         ub_= CGAL::to_interval(t).second;
00431         ni->set_in_list(Item::FRONT);
00432       } 
00433     } else {
00434       ni->set_in_list(Item::BACK);
00435       back_.push_back(*ni);
00436     }
00437     CGAL_expensive_postcondition(audit());
00438     CGAL_expensive_postcondition(contains(Key(ni)));
00439     //std::cout << "Made event " << ni << std::endl;
00440     return Key(ni);
00441   }
00442 
00443 
00445 
00448   void erase(const Key &item) {
00449     //std::cout << "Erase event " << item.pointer() << std::endl;
00450     if (item== end_key()) return;
00451 #ifndef NDEBUG
00452     if (!contains(item)) {
00453       std::cerr << "Erasing event not in queue ";
00454       item->write(std::cerr);
00455       std::cerr << std::endl;
00456     }
00457 #endif
00458     CGAL_expensive_precondition(contains(item));
00459     CGAL_expensive_precondition(audit());
00460     Item *i=item.get();
00461     if (item->in_list() == Item::FRONT) {
00462       front_.erase(i);
00463       if (front_.empty() && !back_.empty()) grow_front();
00464     }
00465     else if (item->in_list() == Item::BACK) {
00466       back_.erase(i);
00467     }
00468     if (item->in_list() == Item::FRONT || item->in_list() == Item::BACK) {
00469       unmake_event(i);
00470     }
00471 
00472     CGAL_expensive_postcondition(audit());
00473   }
00474 
00475   template <class E>
00476   const E& get(const Key &item) const
00477   {
00478     return reinterpret_cast<internal::Two_list_event_queue_item_rep<Priority, E>*>( item.get())->event();
00479   }
00480 
00481   template <class E>
00482   E& get(const Key &item)  {
00483     return reinterpret_cast<internal::Two_list_event_queue_item_rep<Priority, E>*>( item.get())->event();
00484   }
00485 
00487 
00490   template <class NE>
00491   Key set(const Key &item, const NE &ne) {
00492     CGAL_expensive_precondition(contains(item));
00493     CGAL_precondition(item != end_key());
00494     Item *oi= item.get();
00495     typename Item::List front= item->in_list();
00496     Item *ni= make_event(item->time(), ne);
00497     ni->set_in_list(front);
00498     if (front != Item::INF) {
00499       if (front== Item::FRONT) {
00500         front_.insert(oi, *ni);
00501         front_.erase(oi);
00502       }
00503       else {
00504         back_.insert(oi, *ni);
00505         back_.erase(oi);
00506       }
00507       unmake_event(oi);
00508       return Key(ni);
00509     }
00510     else {
00511 #ifndef NDEBUG
00512       bool found=false;
00513       for (unsigned int i=0; i< inf_.size(); ++i) {
00514         if (inf_[i].get() == oi) {
00515           inf_[i]=ni;
00516           found=true;
00517           break;
00518         }
00519       }
00520       CGAL_postcondition(found);
00521 #endif
00522       unmake_event(oi);
00523       return Key(ni);
00524     }
00525     // unreachable
00526 
00527   }
00528 
00530 
00533   const Priority& front_priority() const
00534   {
00535     CGAL_precondition(!front_.empty());
00536     return front_.front().time();
00537   }
00538 
00539 
00540   Key front() const
00541   {
00542     CGAL_precondition(!front_.empty());
00543     return Key(const_cast<Item*>(&front_.front()));
00544   }
00545 
00547   const Priority& priority(const Key &item) const
00548   {
00549     return item->time();
00550   }
00551 
00553   bool empty() const
00554   {
00555     CGAL_precondition(!front_.empty() || back_.empty());
00556     return front_.empty() 
00557       || CGAL::compare(front_.front().time(), end_priority()) == CGAL::LARGER;
00558   }
00559 
00561 
00564   void process_front() {
00565     CGAL_precondition(!empty());
00566     CGAL_expensive_precondition(audit());
00567     if (!front_.empty()) {
00568       Item *i= &front_.front();
00569       CGAL_LOG(Log::SOME, "Processing event " << *i << std::endl);
00570       front_.pop_front();
00571       CGAL_expensive_postcondition(audit());
00572       if (front_.empty() && !back_.empty()) grow_front();
00573       i->process();
00574 
00575       /*if (!front_.empty() && i->time() == front_.front().time()) {
00576         CGAL_LOG(Log::SOME, "Degeneracy at time "
00577         << i->time() << " the events are: "
00578         << *i << " and " << front_.front() << std::endl);
00579         }*/
00580 
00581       unmake_event(i);
00582     }
00583     else {
00584       CGAL_assertion(back_.empty());
00585     }
00586   }
00587 
00589   bool print() const
00590   {
00591     write(std::cout);
00592     return true;
00593   }
00594 
00595   void write(const Queue &q, std::ostream& out) const {
00596     for (typename Queue::const_iterator it = q.begin(); it != q.end(); ++it) {
00597       out << "(" << &*it << ": " << *it << ")";
00598       out << std::endl;
00599     }
00600   }
00601 
00602   bool write(std::ostream &out) const
00603   {
00604     write(front_, std::cout);
00605     out << "--" << ub_ << "--" << std::endl;
00606     write(back_, std::cout);
00607     out << std::endl;
00608     return true;
00609   }
00610 
00611   Key end_key() const
00612   {
00613     return null_event_;
00614   }
00615 
00616   
00617 
00618   const Priority& end_priority() const
00619   {
00620     return end_time_;
00621   }
00622 
00623 
00624   void set_interval(const Priority &start_time, const Priority &end_time) {
00625     CGAL_precondition(!INF);
00626     initialize(start_time, end_time);
00627   }
00628   
00629   void audit_events() const {
00630     for (typename Queue::const_iterator it= front_.begin(); it != front_.end(); ++it) {
00631       it->audit(Key(const_cast<Item*>(&*it)));
00632     }
00633     for (typename Queue::const_iterator it= back_.begin(); it != back_.end(); ++it) {
00634       it->audit(Key(const_cast<Item*>(&*it)));
00635     }
00636   }
00637 
00638   void audit_event(Key k) const {
00639     k->audit(k);
00640   }
00641 
00642   void clear() {
00643     front_.clear();
00644     back_.clear();
00645     //all_in_front_=false;
00646   }
00647 
00648 protected:
00649   void initialize(const Priority &start_time, const Priority &end_time) {
00650     ub_=CGAL::to_interval(start_time).second;
00651     // should be nextafter
00652     step_=1;
00653     //all_in_front_= false;
00654     end_time_=end_time;
00655   }
00656 
00657  void initialize(const Priority &start_time) {
00658    CGAL_precondition(INF);
00659    ub_=CGAL::to_interval(start_time).second;
00660     // should be nextafter
00661    step_=1;
00662     //all_in_front_= false;
00663   }
00664   bool leq_ub(const Priority &t) const {
00665     //if (all_in_front_) return true;
00666     //else 
00667     // pretty much anything fast will have a fast to_interval, so use it
00668     std::pair<double,double> iv= CGAL::to_interval(t);
00669     if (iv.first > ub_) {
00670       return false;
00671     } else if (iv.second <= ub_) {
00672       return true;
00673     } else {
00674       return CGAL::compare(t, Priority(ub_)) != CGAL::LARGER;
00675     }
00676   }
00677 
00678  
00679   template <class E>
00680   Item *make_event(const Priority &t, E &e) {
00681     typedef typename boost::remove_const<E>::type NCE;
00682     Item *ni
00683       = new internal::Two_list_event_queue_item_rep<Priority, NCE>(t, e);
00684     intrusive_ptr_add_ref(ni);
00685     return ni;
00686   }
00687 
00688   void unmake_event(Item *i) {
00689     intrusive_ptr_release(i);
00690   }
00691 
00692   bool audit() {
00693     for (typename Queue::const_iterator it = front_.begin(); it != front_.end(); ++it) {
00694       Priority t= it->time();
00695       CGAL_assertion(leq_ub(t));
00696       CGAL_assertion(it->in_list()== Item::FRONT);
00697       //CGAL_exactness_assertion(t >= lb_);
00698     }
00699     for (typename Queue::const_iterator it = back_.begin(); it != back_.end(); ++it) {
00700       Priority t= it->time();
00701       CGAL_assertion(!leq_ub(t));
00702       CGAL_assertion(it->in_list()== Item::BACK);
00703     }
00704 #ifndef NDEBUG
00705     for (unsigned int i=0; i< inf_.size(); ++i) {
00706       Priority t= inf_[i]->time();
00707       CGAL_assertion(INF || CGAL::compare(t, end_priority())== CGAL::LARGER);
00708       CGAL_assertion(inf_[i]->in_list() == Item::INF);
00709     }
00710 #endif
00711     {
00712       typename Queue::const_iterator it = front_.begin();
00713       ++it;
00714       for (; it != front_.end(); ++it) {
00715         Priority tc= it->time();
00716         Priority tp= boost::prior(it)->time();
00717 #ifndef NDEBUG
00718         if (CGAL::compare(tc, tp) == CGAL::SMALLER) {
00719           std::cout << "ERROR: Out of order " << tc << std::endl << tp << std::endl << std::endl;
00720           ++internal::audit_failures__;
00721         }
00722 #endif
00723         //CGAL_assertion(tc >= tp);
00724       }
00725     }
00726     return true;
00727   }
00728 public:
00729   bool contains(const Key k) const
00730   {
00731     //if (k.pointer()->time() == std::numeric_limits<Priority>::infinity()) return true;
00732     for (typename Queue::const_iterator it = front_.begin(); it != front_.end(); ++it) {
00733       if (&*it == k.pointer()) return true;
00734     }
00735     for (typename Queue::const_iterator it = back_.begin(); it != back_.end(); ++it) {
00736       if (&*it == k.pointer()) return true;
00737     }
00738 #ifndef NDEBUG
00739     for (unsigned int i=0; i< inf_.size(); ++i) {
00740       const Key j=inf_[i];
00741       const Key ki= k;
00742       if (j==ki) return true;
00743     }
00744 #else
00745     if (k.pointer()->in_list() == Item::INF) return true;
00746 #endif
00747     return false;
00748   }
00749 protected:
00750   unsigned int select(Queue &source, Queue &target/*, bool binf*/) {
00751     CGAL_assertion_code(unsigned int sz= source.size() + target.size();)
00752     int count=0;
00753     Iterator it= source.begin();
00754     while (it != source.end()) {
00755       // CGAL_assertion(it->time() >= a);
00756     
00757       if (leq_ub(it->time())) {
00758         Item *i= &*it;
00759         Iterator t= boost::next(it);
00760         source.erase(it);
00761         it=t;
00762         target.push_back(*i);
00763         ++count;
00764       }
00765       else {
00766         ++it;
00767       }
00768     }
00769     CGAL_assertion(sz==source.size() + target.size());
00770     return count;
00771   }
00772 
00773   /*NT step() const{
00774     return (std::max)(ub_-lb_, NT(1));
00775     }*/
00776 
00777   NT av(NT a, NT b) const
00778   {
00779     return .5*(a+b);
00780   }
00781 
00782   template <class It>
00783   void set_front(It b, It e, typename Item::List val) {
00784     for (; b!= e; ++b) {
00785       b->set_in_list(val);
00786     }
00787   }
00788   template <class C, class It>
00789   void make_inf(C &c, It b, It e) {
00790     for (It cit = b; cit != e; ++cit) {
00791       CGAL_assertion(INF || CGAL::compare(cit->time(), end_priority()) == CGAL::LARGER);
00792       //std::cout << "Dropping inf event " << &*cit << std::endl;
00793 #ifndef NDEBUG
00794       inf_.push_back(&*cit);
00795 #endif
00796       cit->set_in_list(Item::INF);
00797       It p= boost::prior(cit);
00798       c.erase(cit);
00799       unmake_event(&*cit);
00800       cit=p;
00801     }
00802     //c.erase(b, e);
00803   }
00804 
00805   void grow_front(Queue &cand, int recursive_count=0) {
00806     const bool dprint=false;
00807     CGAL_assertion(front_.empty());
00808     CGAL_assertion(!cand.empty());
00809     //CGAL_assertion(!all_in_front_);
00810     CGAL_assertion(step_ != 0);
00811     if (dprint) std::cout << "Growing front from " << ub_ << " with step " 
00812                           << step_ << "(" << recursive_count << ") ";
00813 
00814     //CGAL_assertion(ub_<end_split());
00815     if (cand.size() + front_.size() < max_front_size()) {
00816       if (dprint) std::cout << "Setting ub to end of " << end_time_ << std::endl;
00817       front_.splice(front_.end(), cand);
00818       return;
00819     }
00820 
00821     //CGAL_assertion(!too_big(ub_));
00822 
00823     /*if ( CGAL::compare(end_priority(), Priority(ub_)) == CGAL::SMALLER) {
00824       all_in_front_=true;
00825       //ub_=end_split();
00826       }*/
00827 
00828     CGAL_assertion_code(unsigned int num=)
00829       select(cand, front_/*, all_in_front_*/);
00830     CGAL_assertion(front_.size() >= num);
00831     /*if (all_in_front_) {
00832       make_inf(cand, cand.begin(), cand.end());
00833       } else*/
00834     if (front_.empty()) {
00835       if (recursive_count > 10) {
00836         // do something
00837         std::cerr << "Too many recursions " << std::endl;
00838         //all_in_front_=true;
00839         ub_=CGAL::to_interval(end_time_).second; //CGAL::to_interval(end_time_).second*2;// std::numeric_limits<double>::infinity();
00840         /*unsigned int num=*/ select(cand, front_/*, all_in_front_*/);
00841         select(back_, front_);
00842         make_inf(cand, cand.begin(), cand.end());
00843         make_inf(back_, back_.begin(), back_.end());
00844         //grow_front(cand, recursive_count+1);
00845       } else {
00846         if (dprint) {
00847           std::cout << "undershot." << std::endl;
00848           write(front_, std::cout);
00849           std::cout << "-- " << ub_ << "--\n";
00850           write(cand, std::cout);
00851           std::cout << "--\n";
00852           write(back_, std::cout);
00853         }
00854         ub_+= step_;
00855         step_*=2.0;
00856         CGAL_assertion(step_!=0);
00857         cand.splice(cand.end(), back_);
00858         grow_front(cand, recursive_count+1);
00859       }
00860     } else {
00861       //      unsigned int ncand= cand.size();
00862       back_.splice(back_.begin(), cand);
00863       if (front_.size() >  max_front_size()) {
00864         if (recursive_count > 10) {
00865           //std::cerr << "Gave up on isolating front. Let with size " << front_.size() << " ub=" << ub_ << "step=" << step_ <<  "\n";
00866           return;
00867         } else {
00868           // keep the bit length shortish
00869           double frac= .75+.25*max_front_size()/static_cast<double>(front_.size()+1);
00870           double ostep= step_;
00871           CGAL_assertion(frac < 1.1);
00872           CGAL_assertion(frac >= 0.0);
00873           //double rfrac= std::ceil(frac*256.0)/256.0;
00874           step_*=frac;
00875           //else nstep = step_*.6;
00876           //CGAL_assertion(nstep >0);
00877           cand.swap(front_);
00878           //ub_=lb_;
00879           if (step_ == 0) {
00880             CGAL_ERROR( "underflow in queue ");
00881             CGAL_ERROR_WRITE(write(LOG_STREAM));
00882             CGAL_assertion(cand.empty());
00883             step_=.0000001;
00884             return;
00885           } else {
00886             //CGAL_assertion(!all_in_front_);
00887             
00888             if (dprint) {
00889               std::cout << "...overshot" << std::endl;
00890               write(front_, std::cout);
00891               std::cout << "-- " << ub_ << "(" <<step_ << ")" << "--\n";
00892               write(cand, std::cout);
00893               std::cout << "--\n";
00894               write(back_, std::cout);
00895             }
00896             ub_=ub_-ostep+step_;  
00897             grow_front(cand, recursive_count+1);
00898           }
00899         }
00900       }
00901       else {
00902         if (dprint) std::cout << std::endl;
00903       }
00904     }
00905     CGAL_postcondition(cand.empty());
00906   }
00907 
00908   void grow_front() {
00909     //++growth__;
00910     //std::cout << "Growing front from " << ub_ << std::endl;
00911     //CGAL_assertion(is_valid());
00912     CGAL_precondition(!back_.empty());
00913     CGAL_precondition(front_.empty());
00914     CGAL_assertion_code(unsigned int sz= front_.size()+back_.size()+ inf_.size());
00915     Queue cand;
00916     cand.splice(cand.begin(), back_);
00917     ub_ += step_;
00918     grow_front(cand);
00919     set_front(front_.begin(), front_.end(), Item::FRONT);
00920     front_.sort();
00921     ub_= CGAL::to_interval(front_.back().time()).second;
00922     // hmmmm, now I should make a second pass to merge. Ick.
00923 
00924     CGAL_assertion(sz==front_.size()+back_.size() + inf_.size());
00925     CGAL_assertion(audit());
00926     //std::cout << "to " << ub_ << std::endl;
00927   }
00928 
00929   void shrink_front() {
00930     //++shrink__;
00931     //std::cout << "Shrinking front from " << ub_ << std::endl;
00932     typename Queue::iterator it=front_.begin();
00933     unsigned int mf= max_front_size();
00934     for (unsigned int i=0; i < mf; ++i) {
00935       ++it;
00936     }
00937 
00938     // use tii_ so that it does not subdivide
00939 
00940     double split =  CGAL::to_interval(it->time()).second;
00941     if (!INF && (CGAL::compare(end_priority(), it->time())==CGAL::SMALLER
00942                  || CGAL::compare(end_priority(), Priority(split))==CGAL::SMALLER)) {
00943       std::cout << "Past end in Queue " << end_priority() << ", "
00944                 << it->time() << ", " << Priority(split) << std::endl;
00945       //all_in_front_=true;
00946       ub_= CGAL::to_interval(end_time_).second;
00947       set_front(back_.begin(), back_.end(), Item::FRONT);
00948       front_.splice(front_.end(), back_);
00949 
00950       while (it != front_.end()) {
00951         if (CGAL::compare(it->time(), end_priority())==CGAL::LARGER) break;
00952       }
00953       set_front(it, front_.end(), Item::INF);
00954       std::vector<Item*> temp;
00955       for (typename Queue::iterator c= it; c != front_.end(); ++c) {
00956         temp.push_back(&*c);
00957 #ifndef NDEBUG
00958         inf_.push_back(&*c);
00959 #endif
00960         //std::cout << "Dropping inf event " << &*c << std::endl;
00961       }
00962       front_.erase(it, front_.end());
00963 
00964    
00965     
00966       for (unsigned int i=0; i< temp.size(); ++i) {
00967         unmake_event(temp[i]);
00968       }
00969     } else {
00970       while (CGAL::compare(it->time(), Priority(split)) != CGAL::LARGER
00971              && it != front_.end()) ++it;
00972       
00973       if (it != front_.end()) {
00974         
00975         set_front(it, front_.end(), Item::BACK);
00976         back_.splice(back_.begin(), front_, it, front_.end());
00977         double oub=ub_;
00978         //all_in_front_=false;
00979         ub_ = split;
00980         //CGAL_assertion(!too_big(ub_));
00981         //CGAL_assertion(ub_ <= end_split());
00982         step_= std::abs(ub_-oub);
00983         if (step_<=0) {
00984           /*if (dprint) std::cout << "fixing step since " << oub 
00985             << " equals new bound" << std::endl;*/
00986           CGAL_ERROR("Roundoff error in split " << split << " " << ub_ << " "
00987                              <<  oub);
00988           step_=.00001;
00989         }
00990         //CGAL_assertion(!all_in_front_);
00991         /*CGAL_postcondition_code(if (step_<0) std::cerr << step_ << std::endl;);
00992         CGAL_postcondition_code(if (step_<0) std::cerr << ub_ << std::endl;);
00993         CGAL_postcondition_code(if (step_<0) std::cerr << oub << std::endl;);
00994         CGAL_postcondition_code(if (step_<0) std::cerr << front_.back().time() << std::endl;);
00995         CGAL_postcondition_code(if (step_==0) for (typename Queue::const_iterator it=front_.begin(); it != front_.end(); ++it) std::cout << *it << std::endl);
00996         CGAL_postcondition(step_>=0);*/
00997       }
00998     }
00999   }
01000 
01001   /*NT end_split() const
01002     {
01003     return end_split_;
01004     }*/
01005 
01006   /*const Priority& end_time() const
01007     {
01008     return end_time_;
01009     }*/
01010 
01011   unsigned int max_front_size() const
01012   {
01013     return TARGET;
01014     //return (std::max)(4U, static_cast<unsigned int>(std::sqrt(static_cast<double>(front_.size()+back_.size()))));
01015   }
01016 
01017   //typename FK::To_isolating_interval tii_;
01018   Queue front_, back_;
01019 #ifndef NDEBUG
01020   std::vector<Key> inf_;
01021 #endif
01022   double ub_;
01023   double step_;
01024   //bool all_in_front_;
01025   Priority end_time_;
01026   Key null_event_;
01027   //NT end_split_;
01028 };
01029 
01030 template <class D, unsigned int T, bool INF>
01031 std::ostream &operator<<(std::ostream &out, const Two_list_pointer_event_queue<D, INF, T> &q)
01032 {
01033   q.write(out);
01034   return out;
01035 }
01036 
01037 
01038 CGAL_KINETIC_END_NAMESPACE
01039 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines