00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FST_LIB_QUEUE_H__
00023 #define FST_LIB_QUEUE_H__
00024
00025 #include <deque>
00026 #include <vector>
00027 using std::vector;
00028
00029 #include <fst/arcfilter.h>
00030 #include <fst/connect.h>
00031 #include <fst/heap.h>
00032 #include <fst/topsort.h>
00033
00034 namespace fst {
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 enum QueueType {
00059 TRIVIAL_QUEUE = 0,
00060 FIFO_QUEUE = 1,
00061 LIFO_QUEUE = 2,
00062 SHORTEST_FIRST_QUEUE = 3,
00063 TOP_ORDER_QUEUE = 4,
00064 STATE_ORDER_QUEUE = 5,
00065 SCC_QUEUE = 6,
00066 AUTO_QUEUE = 7,
00067 OTHER_QUEUE = 8
00068 };
00069
00070
00071
00072
00073 template <class S>
00074 class QueueBase {
00075 public:
00076 typedef S StateId;
00077
00078 QueueBase(QueueType type) : queue_type_(type) {}
00079 virtual ~QueueBase() {}
00080 StateId Head() const { return Head_(); }
00081 void Enqueue(StateId s) { Enqueue_(s); }
00082 void Dequeue() { Dequeue_(); }
00083 void Update(StateId s) { Update_(s); }
00084 bool Empty() const { return Empty_(); }
00085 void Clear() { Clear_(); }
00086 QueueType Type() { return queue_type_; }
00087
00088 private:
00089
00090
00091
00092 virtual StateId Head_() const = 0;
00093 virtual void Enqueue_(StateId s) = 0;
00094 virtual void Dequeue_() = 0;
00095 virtual void Update_(StateId s) = 0;
00096 virtual bool Empty_() const = 0;
00097 virtual void Clear_() = 0;
00098
00099 QueueType queue_type_;
00100 };
00101
00102
00103
00104
00105
00106 template <class S>
00107 class TrivialQueue : public QueueBase<S> {
00108 public:
00109 typedef S StateId;
00110
00111 TrivialQueue() : QueueBase<S>(TRIVIAL_QUEUE), front_(kNoStateId) {}
00112 StateId Head() const { return front_; }
00113 void Enqueue(StateId s) { front_ = s; }
00114 void Dequeue() { front_ = kNoStateId; }
00115 void Update(StateId s) {}
00116 bool Empty() const { return front_ == kNoStateId; }
00117 void Clear() { front_ = kNoStateId; }
00118
00119
00120 private:
00121
00122
00123
00124 virtual StateId Head_() const { return Head(); }
00125 virtual void Enqueue_(StateId s) { Enqueue(s); }
00126 virtual void Dequeue_() { Dequeue(); }
00127 virtual void Update_(StateId s) { Update(s); }
00128 virtual bool Empty_() const { return Empty(); }
00129 virtual void Clear_() { return Clear(); }
00130
00131 StateId front_;
00132 };
00133
00134
00135
00136 template <class S>
00137 class FifoQueue : public QueueBase<S>, public deque<S> {
00138 public:
00139 using deque<S>::back;
00140 using deque<S>::push_front;
00141 using deque<S>::pop_back;
00142 using deque<S>::empty;
00143 using deque<S>::clear;
00144
00145 typedef S StateId;
00146
00147 FifoQueue() : QueueBase<S>(FIFO_QUEUE) {}
00148 StateId Head() const { return back(); }
00149 void Enqueue(StateId s) { push_front(s); }
00150 void Dequeue() { pop_back(); }
00151 void Update(StateId s) {}
00152 bool Empty() const { return empty(); }
00153 void Clear() { clear(); }
00154
00155 private:
00156
00157
00158
00159 virtual StateId Head_() const { return Head(); }
00160 virtual void Enqueue_(StateId s) { Enqueue(s); }
00161 virtual void Dequeue_() { Dequeue(); }
00162 virtual void Update_(StateId s) { Update(s); }
00163 virtual bool Empty_() const { return Empty(); }
00164 virtual void Clear_() { return Clear(); }
00165 };
00166
00167
00168
00169 template <class S>
00170 class LifoQueue : public QueueBase<S>, public deque<S> {
00171 public:
00172 using deque<S>::front;
00173 using deque<S>::push_front;
00174 using deque<S>::pop_front;
00175 using deque<S>::empty;
00176 using deque<S>::clear;
00177
00178 typedef S StateId;
00179
00180 LifoQueue() : QueueBase<S>(LIFO_QUEUE) {}
00181 StateId Head() const { return front(); }
00182 void Enqueue(StateId s) { push_front(s); }
00183 void Dequeue() { pop_front(); }
00184 void Update(StateId s) {}
00185 bool Empty() const { return empty(); }
00186 void Clear() { clear(); }
00187
00188 private:
00189
00190
00191
00192 virtual StateId Head_() const { return Head(); }
00193 virtual void Enqueue_(StateId s) { Enqueue(s); }
00194 virtual void Dequeue_() { Dequeue(); }
00195 virtual void Update_(StateId s) { Update(s); }
00196 virtual bool Empty_() const { return Empty(); }
00197 virtual void Clear_() { return Clear(); }
00198 };
00199
00200
00201
00202
00203
00204
00205
00206 template <typename S, typename C, bool update = true>
00207 class ShortestFirstQueue : public QueueBase<S> {
00208 public:
00209 typedef S StateId;
00210 typedef C Compare;
00211
00212 ShortestFirstQueue(C comp)
00213 : QueueBase<S>(SHORTEST_FIRST_QUEUE), heap_(comp) {}
00214
00215 StateId Head() const { return heap_.Top(); }
00216
00217 void Enqueue(StateId s) {
00218 if (update) {
00219 for (StateId i = key_.size(); i <= s; ++i)
00220 key_.push_back(kNoKey);
00221 key_[s] = heap_.Insert(s);
00222 } else {
00223 heap_.Insert(s);
00224 }
00225 }
00226
00227 void Dequeue() {
00228 if (update)
00229 key_[heap_.Pop()] = kNoKey;
00230 else
00231 heap_.Pop();
00232 }
00233
00234 void Update(StateId s) {
00235 if (!update)
00236 return;
00237 if (s >= key_.size() || key_[s] == kNoKey) {
00238 Enqueue(s);
00239 } else {
00240 heap_.Update(key_[s], s);
00241 }
00242 }
00243
00244 bool Empty() const { return heap_.Empty(); }
00245
00246 void Clear() {
00247 heap_.Clear();
00248 if (update) key_.clear();
00249 }
00250
00251 private:
00252 Heap<S, C, false> heap_;
00253 vector<ssize_t> key_;
00254
00255
00256
00257
00258 virtual StateId Head_() const { return Head(); }
00259 virtual void Enqueue_(StateId s) { Enqueue(s); }
00260 virtual void Dequeue_() { Dequeue(); }
00261 virtual void Update_(StateId s) { Update(s); }
00262 virtual bool Empty_() const { return Empty(); }
00263 virtual void Clear_() { return Clear(); }
00264 };
00265
00266
00267
00268
00269
00270 template <typename S, typename L>
00271 class StateWeightCompare {
00272 public:
00273 typedef L Less;
00274 typedef typename L::Weight Weight;
00275 typedef S StateId;
00276
00277 StateWeightCompare(const vector<Weight>& weights, const L &less)
00278 : weights_(weights), less_(less) {}
00279
00280 bool operator()(const S x, const S y) const {
00281 return less_(weights_[x], weights_[y]);
00282 }
00283
00284 private:
00285 const vector<Weight>& weights_;
00286 L less_;
00287 };
00288
00289
00290
00291
00292 template <typename S, typename W>
00293 class NaturalShortestFirstQueue :
00294 public ShortestFirstQueue<S, StateWeightCompare<S, NaturalLess<W> > > {
00295 public:
00296 typedef StateWeightCompare<S, NaturalLess<W> > C;
00297
00298 NaturalShortestFirstQueue(const vector<W> &distance) :
00299 ShortestFirstQueue<S, C>(C(distance, less_)) {}
00300
00301 private:
00302 NaturalLess<W> less_;
00303 };
00304
00305
00306
00307 template <class S>
00308 class TopOrderQueue : public QueueBase<S> {
00309 public:
00310 typedef S StateId;
00311
00312
00313
00314
00315 template <class Arc, class ArcFilter>
00316
00317 TopOrderQueue(const Fst<Arc> &fst, ArcFilter filter)
00318 : QueueBase<S>(TOP_ORDER_QUEUE), front_(0), back_(kNoStateId),
00319 order_(0), state_(0) {
00320 bool acyclic;
00321 TopOrderVisitor<Arc> top_order_visitor(&order_, &acyclic);
00322 DfsVisit(fst, &top_order_visitor, filter);
00323 if (!acyclic)
00324 LOG(FATAL) << "TopOrderQueue: fst is not acyclic.";
00325 state_.resize(order_.size(), kNoStateId);
00326 }
00327
00328
00329
00330 TopOrderQueue(const vector<StateId> &order)
00331 : QueueBase<S>(TOP_ORDER_QUEUE), front_(0), back_(kNoStateId),
00332 order_(order), state_(order.size(), kNoStateId) {}
00333
00334 StateId Head() const { return state_[front_]; }
00335
00336 void Enqueue(StateId s) {
00337 if (front_ > back_) front_ = back_ = order_[s];
00338 else if (order_[s] > back_) back_ = order_[s];
00339 else if (order_[s] < front_) front_ = order_[s];
00340 state_[order_[s]] = s;
00341 }
00342
00343 void Dequeue() {
00344 state_[front_] = kNoStateId;
00345 while ((front_ <= back_) && (state_[front_] == kNoStateId)) ++front_;
00346 }
00347
00348 void Update(StateId s) {}
00349
00350 bool Empty() const { return front_ > back_; }
00351
00352 void Clear() {
00353 for (StateId i = front_; i <= back_; ++i) state_[i] = kNoStateId;
00354 back_ = kNoStateId;
00355 front_ = 0;
00356 }
00357
00358 private:
00359 StateId front_;
00360 StateId back_;
00361 vector<StateId> order_;
00362 vector<StateId> state_;
00363
00364
00365
00366
00367 virtual StateId Head_() const { return Head(); }
00368 virtual void Enqueue_(StateId s) { Enqueue(s); }
00369 virtual void Dequeue_() { Dequeue(); }
00370 virtual void Update_(StateId s) { Update(s); }
00371 virtual bool Empty_() const { return Empty(); }
00372 virtual void Clear_() { return Clear(); }
00373 };
00374
00375
00376
00377
00378 template <class S>
00379 class StateOrderQueue : public QueueBase<S> {
00380 public:
00381 typedef S StateId;
00382
00383 StateOrderQueue()
00384 : QueueBase<S>(STATE_ORDER_QUEUE), front_(0), back_(kNoStateId) {}
00385
00386 StateId Head() const { return front_; }
00387
00388 void Enqueue(StateId s) {
00389 if (front_ > back_) front_ = back_ = s;
00390 else if (s > back_) back_ = s;
00391 else if (s < front_) front_ = s;
00392 while (enqueued_.size() <= s) enqueued_.push_back(false);
00393 enqueued_[s] = true;
00394 }
00395
00396 void Dequeue() {
00397 enqueued_[front_] = false;
00398 while ((front_ <= back_) && (enqueued_[front_] == false)) ++front_;
00399 }
00400
00401 void Update(StateId s) {}
00402
00403 bool Empty() const { return front_ > back_; }
00404
00405 void Clear() {
00406 for (StateId i = front_; i <= back_; ++i) enqueued_[i] = false;
00407 front_ = 0;
00408 back_ = kNoStateId;
00409 }
00410
00411 private:
00412 StateId front_;
00413 StateId back_;
00414 vector<bool> enqueued_;
00415
00416
00417
00418
00419 virtual StateId Head_() const { return Head(); }
00420 virtual void Enqueue_(StateId s) { Enqueue(s); }
00421 virtual void Dequeue_() { Dequeue(); }
00422 virtual void Update_(StateId s) { Update(s); }
00423 virtual bool Empty_() const { return Empty(); }
00424 virtual void Clear_() { return Clear(); }
00425
00426 };
00427
00428
00429
00430
00431
00432
00433 template <class S, class Q>
00434 class SccQueue : public QueueBase<S> {
00435 public:
00436 typedef S StateId;
00437 typedef Q Queue;
00438
00439
00440
00441 SccQueue(const vector<StateId> &scc, vector<Queue*> *queue)
00442 : QueueBase<S>(SCC_QUEUE), queue_(queue), scc_(scc), front_(0),
00443 back_(kNoStateId) {}
00444
00445 StateId Head() const {
00446 while ((front_ <= back_) &&
00447 (((*queue_)[front_] && (*queue_)[front_]->Empty())
00448 || (((*queue_)[front_] == 0) &&
00449 ((front_ > trivial_queue_.size())
00450 || (trivial_queue_[front_] == kNoStateId)))))
00451 ++front_;
00452 if (front_ > back_)
00453 LOG(FATAL) << "SccQueue: head of empty queue";
00454 if ((*queue_)[front_])
00455 return (*queue_)[front_]->Head();
00456 else
00457 return trivial_queue_[front_];
00458 }
00459
00460 void Enqueue(StateId s) {
00461 if (front_ > back_) front_ = back_ = scc_[s];
00462 else if (scc_[s] > back_) back_ = scc_[s];
00463 else if (scc_[s] < front_) front_ = scc_[s];
00464 if ((*queue_)[scc_[s]]) {
00465 (*queue_)[scc_[s]]->Enqueue(s);
00466 } else {
00467 while (trivial_queue_.size() <= scc_[s])
00468 trivial_queue_.push_back(kNoStateId);
00469 trivial_queue_[scc_[s]] = s;
00470 }
00471 }
00472
00473 void Dequeue() {
00474 if (front_ > back_)
00475 LOG(FATAL) << "SccQueue: dequeue of empty queue";
00476 if ((*queue_)[front_])
00477 (*queue_)[front_]->Dequeue();
00478 else if (front_ < trivial_queue_.size())
00479 trivial_queue_[front_] = kNoStateId;
00480 }
00481
00482 void Update(StateId s) {
00483 if ((*queue_)[scc_[s]])
00484 (*queue_)[scc_[s]]->Update(s);
00485 }
00486
00487 bool Empty() const {
00488 if (front_ < back_)
00489 return false;
00490 else if (front_ > back_)
00491 return true;
00492 else if ((*queue_)[front_])
00493 return (*queue_)[front_]->Empty();
00494 else
00495 return (front_ > trivial_queue_.size())
00496 || (trivial_queue_[front_] == kNoStateId);
00497 }
00498
00499 void Clear() {
00500 for (StateId i = front_; i <= back_; ++i)
00501 if ((*queue_)[i])
00502 (*queue_)[i]->Clear();
00503 else if (i < trivial_queue_.size())
00504 trivial_queue_[i] = kNoStateId;
00505 front_ = 0;
00506 back_ = kNoStateId;
00507 }
00508
00509 private:
00510 vector<Queue*> *queue_;
00511 const vector<StateId> &scc_;
00512 mutable StateId front_;
00513 StateId back_;
00514 vector<StateId> trivial_queue_;
00515
00516
00517
00518
00519 virtual StateId Head_() const { return Head(); }
00520 virtual void Enqueue_(StateId s) { Enqueue(s); }
00521 virtual void Dequeue_() { Dequeue(); }
00522 virtual void Update_(StateId s) { Update(s); }
00523 virtual bool Empty_() const { return Empty(); }
00524 virtual void Clear_() { return Clear(); }
00525
00526 DISALLOW_COPY_AND_ASSIGN(SccQueue);
00527 };
00528
00529
00530
00531
00532 template <class S>
00533 class AutoQueue : public QueueBase<S> {
00534 public:
00535 typedef S StateId;
00536
00537
00538
00539
00540 template <class Arc, class ArcFilter>
00541 AutoQueue(const Fst<Arc> &fst, const vector<typename Arc::Weight> *distance,
00542 ArcFilter filter) : QueueBase<S>(AUTO_QUEUE) {
00543 typedef typename Arc::Weight Weight;
00544 typedef StateWeightCompare< StateId, NaturalLess<Weight> > Compare;
00545
00546
00547 uint64 props = fst.Properties(kAcyclic | kCyclic |
00548 kTopSorted | kUnweighted, false);
00549 if ((props & kTopSorted) || fst.Start() == kNoStateId) {
00550 queue_ = new StateOrderQueue<StateId>();
00551 VLOG(2) << "AutoQueue: using state-order discipline";
00552 } else if (props & kAcyclic) {
00553 queue_ = new TopOrderQueue<StateId>(fst, filter);
00554 VLOG(2) << "AutoQueue: using top-order discipline";
00555 } else if ((props & kUnweighted) && (Weight::Properties() & kIdempotent)) {
00556 queue_ = new LifoQueue<StateId>();
00557 VLOG(2) << "AutoQueue: using LIFO discipline";
00558 } else {
00559 uint64 properties;
00560
00561 SccVisitor<Arc> scc_visitor(&scc_, 0, 0, &properties);
00562 DfsVisit(fst, &scc_visitor, filter);
00563 StateId nscc = *max_element(scc_.begin(), scc_.end()) + 1;
00564 vector<QueueType> queue_types(nscc);
00565 NaturalLess<Weight> *less = 0;
00566 Compare *comp = 0;
00567 if (distance && (Weight::Properties() & kPath)) {
00568 less = new NaturalLess<Weight>;
00569 comp = new Compare(*distance, *less);
00570 }
00571
00572 bool unweighted;
00573 bool all_trivial;
00574 SccQueueType(fst, scc_, &queue_types, filter, less, &all_trivial,
00575 &unweighted);
00576
00577 if (unweighted) {
00578 queue_ = new LifoQueue<StateId>();
00579 VLOG(2) << "AutoQueue: using LIFO discipline";
00580 delete comp;
00581 delete less;
00582 return;
00583 }
00584
00585
00586 if (all_trivial) {
00587 queue_ = new TopOrderQueue<StateId>(scc_);
00588 VLOG(2) << "AutoQueue: using top-order discipline";
00589 delete comp;
00590 delete less;
00591 return;
00592 }
00593 VLOG(2) << "AutoQueue: using SCC meta-discipline";
00594 queues_.resize(nscc);
00595 for (StateId i = 0; i < nscc; ++i) {
00596 switch(queue_types[i]) {
00597 case TRIVIAL_QUEUE:
00598 queues_[i] = 0;
00599 VLOG(3) << "AutoQueue: SCC #" << i
00600 << ": using trivial discipline";
00601 break;
00602 case SHORTEST_FIRST_QUEUE:
00603 CHECK(comp);
00604 queues_[i] = new ShortestFirstQueue<StateId, Compare, false>(*comp);
00605 VLOG(3) << "AutoQueue: SCC #" << i <<
00606 ": using shortest-first discipline";
00607 break;
00608 case LIFO_QUEUE:
00609 queues_[i] = new LifoQueue<StateId>();
00610 VLOG(3) << "AutoQueue: SCC #" << i
00611 << ": using LIFO disciplle";
00612 break;
00613 case FIFO_QUEUE:
00614 default:
00615 queues_[i] = new FifoQueue<StateId>();
00616 VLOG(3) << "AutoQueue: SCC #" << i
00617 << ": using FIFO disciplle";
00618 break;
00619 }
00620 }
00621 queue_ = new SccQueue< StateId, QueueBase<StateId> >(scc_, &queues_);
00622 delete comp;
00623 delete less;
00624 }
00625 }
00626
00627 ~AutoQueue() {
00628 for (StateId i = 0; i < queues_.size(); ++i)
00629 delete queues_[i];
00630 delete queue_;
00631 }
00632
00633 StateId Head() const { return queue_->Head(); }
00634
00635 void Enqueue(StateId s) { queue_->Enqueue(s); }
00636
00637 void Dequeue() { queue_->Dequeue(); }
00638
00639 void Update(StateId s) { queue_->Update(s); }
00640
00641 bool Empty() const { return queue_->Empty(); }
00642
00643 void Clear() { queue_->Clear(); }
00644
00645
00646 private:
00647 QueueBase<StateId> *queue_;
00648 vector< QueueBase<StateId>* > queues_;
00649 vector<StateId> scc_;
00650
00651 template <class Arc, class ArcFilter, class Less>
00652 static void SccQueueType(const Fst<Arc> &fst,
00653 const vector<StateId> &scc,
00654 vector<QueueType> *queue_types,
00655 ArcFilter filter, Less *less,
00656 bool *all_trivial, bool *unweighted);
00657
00658
00659
00660
00661 virtual StateId Head_() const { return Head(); }
00662
00663 virtual void Enqueue_(StateId s) { Enqueue(s); }
00664
00665 virtual void Dequeue_() { Dequeue(); }
00666
00667 virtual void Update_(StateId s) { Update(s); }
00668
00669 virtual bool Empty_() const { return Empty(); }
00670
00671 virtual void Clear_() { return Clear(); }
00672
00673 DISALLOW_COPY_AND_ASSIGN(AutoQueue);
00674 };
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 template <class StateId>
00686 template <class A, class ArcFilter, class Less>
00687 void AutoQueue<StateId>::SccQueueType(const Fst<A> &fst,
00688 const vector<StateId> &scc,
00689 vector<QueueType> *queue_type,
00690 ArcFilter filter, Less *less,
00691 bool *all_trivial, bool *unweighted) {
00692 typedef A Arc;
00693 typedef typename A::StateId StateId;
00694 typedef typename A::Weight Weight;
00695
00696 *all_trivial = true;
00697 *unweighted = true;
00698
00699 for (StateId i = 0; i < queue_type->size(); ++i)
00700 (*queue_type)[i] = TRIVIAL_QUEUE;
00701
00702 for (StateIterator< Fst<Arc> > sit(fst); !sit.Done(); sit.Next()) {
00703 StateId state = sit.Value();
00704 for (ArcIterator< Fst<Arc> > ait(fst, state);
00705 !ait.Done();
00706 ait.Next()) {
00707 const Arc &arc = ait.Value();
00708 if (!filter(arc)) continue;
00709 if (scc[state] == scc[arc.nextstate]) {
00710 QueueType &type = (*queue_type)[scc[state]];
00711 if (!less || ((*less)(arc.weight, Weight::One())))
00712 type = FIFO_QUEUE;
00713 else if ((type == TRIVIAL_QUEUE) || (type == LIFO_QUEUE)) {
00714 if (!(Weight::Properties() & kIdempotent) ||
00715 (arc.weight != Weight::Zero() && arc.weight != Weight::One()))
00716 type = SHORTEST_FIRST_QUEUE;
00717 else
00718 type = LIFO_QUEUE;
00719 }
00720 if (type != TRIVIAL_QUEUE) *all_trivial = false;
00721 }
00722 if (!(Weight::Properties() & kIdempotent) ||
00723 (arc.weight != Weight::Zero() && arc.weight != Weight::One()))
00724 *unweighted = false;
00725 }
00726 }
00727 }
00728
00729
00730
00731
00732
00733 template <typename S, typename W>
00734 struct TrivialAStarEstimate {
00735 W operator()(S s) const { return W::One(); }
00736 };
00737
00738
00739
00740
00741
00742
00743
00744 template <typename S, typename L, typename E>
00745 class AStarWeightCompare {
00746 public:
00747 typedef L Less;
00748 typedef typename L::Weight Weight;
00749 typedef S StateId;
00750
00751 AStarWeightCompare(const vector<Weight>& weights, const L &less,
00752 const E &estimate)
00753 : weights_(weights), less_(less), estimate_(estimate) {}
00754
00755 bool operator()(const S x, const S y) const {
00756 Weight wx = Times(weights_[x], estimate_(x));
00757 Weight wy = Times(weights_[y], estimate_(y));
00758 return less_(wx, wy);
00759 }
00760
00761 private:
00762 const vector<Weight>& weights_;
00763 L less_;
00764 const E &estimate_;
00765 };
00766
00767
00768
00769
00770
00771 template <typename S, typename W, typename E>
00772 class NaturalAStarQueue :
00773 public ShortestFirstQueue<S, AStarWeightCompare<S, NaturalLess<W>, E> > {
00774 public:
00775 typedef AStarWeightCompare<S, NaturalLess<W>, E> C;
00776
00777 NaturalAStarQueue(const vector<W> &distance, const E &estimate) :
00778 ShortestFirstQueue<S, C>(C(distance, less_, estimate)) {}
00779
00780 private:
00781 NaturalLess<W> less_;
00782 };
00783
00784
00785
00786
00787
00788 template <typename S>
00789 struct TrivialStateEquivClass {
00790 S operator()(S s) const { return s; }
00791 };
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 template <typename Q, typename L, typename C>
00802 class PruneQueue : public QueueBase<typename Q::StateId> {
00803 public:
00804 typedef typename Q::StateId StateId;
00805 typedef typename L::Weight Weight;
00806
00807 PruneQueue(const vector<Weight> &distance, Q *queue, L comp,
00808 const C &class_func, Weight threshold)
00809 : QueueBase<StateId>(OTHER_QUEUE),
00810 distance_(distance),
00811 queue_(queue),
00812 less_(comp),
00813 class_func_(class_func),
00814 threshold_(threshold) {}
00815
00816 ~PruneQueue() { delete queue_; }
00817
00818 StateId Head() const { return queue_->Head(); }
00819
00820 void Enqueue(StateId s) {
00821 StateId c = class_func_(s);
00822 if (c >= class_distance_.size())
00823 class_distance_.resize(c + 1, Weight::Zero());
00824 if (less_(distance_[s], class_distance_[c]))
00825 class_distance_[c] = distance_[s];
00826
00827
00828 Weight limit = Times(class_distance_[c], threshold_);
00829 if (less_(distance_[s], limit))
00830 queue_->Enqueue(s);
00831 }
00832
00833 void Dequeue() { queue_->Dequeue(); }
00834
00835 void Update(StateId s) {
00836 StateId c = class_func_(s);
00837 if (less_(distance_[s], class_distance_[c]))
00838 class_distance_[c] = distance_[s];
00839 queue_->Update(s);
00840 }
00841
00842 bool Empty() const { return queue_->Empty(); }
00843 void Clear() { queue_->Clear(); }
00844
00845 private:
00846
00847
00848
00849 virtual StateId Head_() const { return Head(); }
00850 virtual void Enqueue_(StateId s) { Enqueue(s); }
00851 virtual void Dequeue_() { Dequeue(); }
00852 virtual void Update_(StateId s) { Update(s); }
00853 virtual bool Empty_() const { return Empty(); }
00854 virtual void Clear_() { return Clear(); }
00855
00856 const vector<Weight> &distance_;
00857 Q *queue_;
00858 L less_;
00859 const C &class_func_;
00860 Weight threshold_;
00861 vector<Weight> class_distance_;
00862
00863 DISALLOW_COPY_AND_ASSIGN(PruneQueue);
00864 };
00865
00866
00867
00868
00869
00870 template <typename Q, typename W, typename C>
00871 class NaturalPruneQueue :
00872 public PruneQueue<Q, NaturalLess<W>, C> {
00873 public:
00874 typedef typename Q::StateId StateId;
00875 typedef W Weight;
00876
00877 NaturalPruneQueue(const vector<W> &distance, Q *queue,
00878 const C &class_func_, Weight threshold) :
00879 PruneQueue<Q, NaturalLess<W>, C>(distance, queue, less_,
00880 class_func_, threshold) {}
00881
00882 private:
00883 NaturalLess<W> less_;
00884 };
00885
00886
00887 }
00888
00889 #endif
00890