Transit Planner  1.0
An experiment on transfer patterns robustness
src/Label.h
00001 // Copyright 2011: Eugen Sawin, Philip Stahl, Jonas Sternisko
00002 #ifndef SRC_LABEL_H_
00003 #define SRC_LABEL_H_
00004 
00005 #include <boost/serialization/access.hpp>
00006 #include <climits>
00007 #include <cassert>
00008 #include <set>
00009 #include <string>
00010 #include <vector>
00011 #include <algorithm>
00012 #include <bitset>
00013 
00014 using std::set;
00015 using std::string;
00016 using std::vector;
00017 using std::bitset;
00018 using std::min;
00019 
00020 
00021 class LabelVec {
00022  public:
00023   struct Field {
00024     Field(const int at, const unsigned char penalty,
00025           const unsigned char maxPenalty)
00026       : at(at), penalty(penalty), maxPenalty(maxPenalty), cost(0),
00027         parent(NULL) {}
00028 
00029     Field(const int at, const unsigned char penalty,
00030           const unsigned char maxPenalty, const unsigned int cost,
00031           const bool walk, const bool inactive, Field* parent)
00032       : at(at), penalty(penalty), maxPenalty(maxPenalty), cost(cost),
00033         parent(parent) {
00034       used(true);
00035       this->walk(walk);
00036       this->inactive(inactive);
00037     }
00038 
00039     bool used() const { return _misc.test(0); }
00040     bool closed() const { return _misc.test(1); }
00041     bool inactive() const { return _misc.test(2); }
00042     bool walk() const { return _misc.test(3); }
00043 
00044     void used(bool value) { _misc.set(0, value); }
00045     void closed(bool value) { _misc.set(1, value); }
00046     void inactive(bool value) { _misc.set(2, value); }
00047     void walk(bool value) { _misc.set(3, value); }
00048 
00049     int at;
00050     unsigned char penalty;
00051     unsigned char maxPenalty;
00052     unsigned int cost;
00053     Field* parent;
00054     bitset<4> _misc;  // 0:used 1:closed 2:inactive 3:walk
00055   };
00056 
00057   // A label proxy interfacing with the internal structures of  LabelVec.
00058   class Hnd {
00059    public:
00060     struct Comp {
00061       bool operator()(const Hnd& lhs, const Hnd& rhs) const {
00062         return rhs < lhs;
00063       }
00064     };
00065 
00066     Hnd(const Hnd& rhs)
00067       : _values(rhs._values),
00068         _field(rhs._field),
00069         _inactive(rhs._inactive) {
00070       assert(at() == rhs.at());
00071     }
00072 
00073     Hnd() : _values(0), _field(NULL), _inactive(false) {}
00074 
00075     Hnd(unsigned int cost, unsigned char penalty, bool inactive,
00076         LabelVec::Field* field)
00077       : _values((cost << 8) | penalty), _field(field),
00078         _inactive(inactive) {}
00079 
00080     Hnd& operator=(const Hnd& rhs) {
00081       if (this == &rhs) {
00082         return *this;
00083       }
00084       _values = rhs._values;
00085       _field = rhs._field;
00086       _inactive = rhs._inactive;
00087       return *this;
00088     }
00089 
00090     bool operator>(const Hnd& rhs) const {
00091       return _values > rhs._values;
00092     }
00093 
00094     bool operator<(const Hnd& rhs) const {
00095       return _values < rhs._values;
00096     }
00097 
00098     // Implicit bool conversion showing whether the label is valid.
00099     operator bool() const { return valid(); }
00100 
00101     // Returns whether the label is valid. This is used for terminating
00102     // tracebacks of optimal paths.
00103     bool valid() const { return _field; }
00104 
00105     unsigned int cost() const { return _values >> 8; }
00106     unsigned char penalty() const { return _values & 0xff; }
00107     unsigned char maxPenalty() const { return _field->maxPenalty; }
00108     int at() const { return _field->at; }
00109     bool closed() const { return _field->closed(); }
00110     bool inactive() const { return _inactive; }
00111     bool walk() const { return _field->walk(); }
00112 
00113     void inactive(bool value) { _inactive = value; }
00114     void closed(bool value) { _field->closed(value); }
00115 
00116     Field* field() const { return _field; }
00117 
00118    private:
00119     unsigned int _values;
00120     Field* _field;
00121     bool _inactive;
00122   };
00123 
00124   typedef vector<Hnd>::const_iterator const_iterator;
00125 
00126   LabelVec();
00127   LabelVec(const int at, const unsigned char maxPenalty);
00128 
00129   const_iterator begin() const;
00130 
00131   const_iterator end() const;
00132 
00133   // Returns whether the cost, penalty pair is optimal within the vector.
00134   bool candidate(const unsigned int cost, const unsigned char penalty) const;
00135 
00136   // Adds a new label, possibly overwritting the old label with same penalty.
00137   Field* add(const unsigned int cost, const unsigned char penalty,
00138              const unsigned char maxPenalty,
00139              const bool walk, const bool inactive, Field* parent);
00140 
00141   void add(const Hnd& label, const Hnd& parent);
00142 
00143   // Returns const reference to the field at given penalty.
00144   const Field& field(const unsigned char penalty) const;
00145 
00146   // Removes all inactive labels.
00147   int pruneInactive();
00148 
00149   // Returns the vector size, which equals to the max penalty + 1.
00150   int size() const;
00151 
00152   // Returns the minimum cost value of all labels.
00153   int minCost() const;
00154 
00155   // Returns the minimum penalty value of all labels.
00156   int minPenalty() const;
00157 
00158   // Returns the node index at which this labels are connected.
00159   int at() const;
00160 
00161   // Sets the inactive value to true
00162   // for all labels which are worse the given cost and penalty
00163   void deactivate(const unsigned int cost, const unsigned char penalty);
00164 
00165  private:
00166   int _at;
00167   int _numUsed;
00168   vector<Field> _fields;
00169   mutable bool _updated;
00170   mutable vector<Hnd> _bakedLabels;
00171 };
00172 
00173 // Holds a label vector for each node and ways to operate on them.
00174 class LabelMatrix {
00175  public:
00176   typedef LabelVec::Hnd Hnd;
00177   typedef vector<LabelVec>::const_iterator const_iterator;
00178 
00179   // Resizes the matrix given the number of nodes and max penalty.
00180   // Resizing deletes all previous labels.
00181   void resize(const int numNodes, const unsigned char maxPenalty);
00182 
00183   // Returns whether given cost, penalty pair is optimal for given node id.
00184   bool candidate(const int at, unsigned int cost, unsigned char penalty) const;
00185 
00186   // Returns whether there is a label with given penalty for given node id.
00187   bool contains(const int at, unsigned char penalty) const;
00188 
00189   // Returns whether the label at given node id and penalty is set closed.
00190   bool closed(const int at, unsigned char penalty) const;
00191 
00192   // This is a specialisation for adding labels without parent labels.
00193   Hnd add(const int at, const unsigned int cost, const unsigned char penalty,
00194           const unsigned char maxPenalty);
00195 
00196   // Adds a successor label for given node id with given cost and penalty.
00197   // Returns a label proxy for the newly created label data.
00198   Hnd add(const int at, const unsigned int cost, const unsigned char penalty,
00199           const unsigned char maxPenalty, const bool walk, const bool inactive,
00200           const Hnd& parent);
00201 
00202   // Removes all inactive labels.
00203   // Returns the number of labels removed.
00204   int pruneInactive();
00205 
00206   // Returns the parent label proxy for given successor label.
00207   // If no parent is available it returns an invalid label.
00208   Hnd parent(const Hnd& succ) const;
00209 
00210   // Returns a const reference to the label vector for given node index.
00211   const LabelVec& at(const int at) const;
00212 
00213   // Returns a reference to the label vector for given node index.
00214   LabelVec& at(const int at);
00215 
00216   // Sets the inactive value to true for all labels at the given node
00217   // which are worse the given cost and penalty. Used by arrival loop.
00218   void deactivate(const int at, const unsigned int cost,
00219                                 const unsigned char penalty);
00220 
00221 
00222   const_iterator cbegin() const;
00223   const_iterator cend() const;
00224 
00225   // Returns the size of the matrix, which equals to the number of label vectors
00226   // it serves.
00227   int size() const;
00228 
00229   int numLabels() const;
00230 
00231  private:
00232   vector<LabelVec> _matrix;
00233 };
00234 
00235 #endif  // SRC_LABEL_H_
 All Classes