Transit Planner
1.0
An experiment on transfer patterns robustness
|
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_