BWAPI
|
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