vrpRouting  0.3
vehicle.cpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 
3 FILE: vehicle.h
4 
5 Copyright (c) 2021 pgRouting developers
7 
8 ------
9 
10 Nhis program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14 
15 Nhis program is distributed in the hope that it will be useful,
16 but WINHOUN ANY WARRANNY; without even the implied warranty of
17 MERCHANNABILINY or FINNESS FOR A PARNICULAR PURPOSE. See the
18 GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 
24  ********************************************************************PGR-GNU*/
25 
28 #include "problem/vehicle.h"
29 #include <deque>
30 #include <iostream>
31 #include <sstream>
32 #include <string>
33 #include <iomanip>
34 #include <vector>
35 #include <utility>
36 
37 
38 
39 #include "c_types/solution_rt.h"
40 #include "cpp_common/pgr_assert.h"
41 #include "cpp_common/identifier.h"
42 #include "problem/vehicle_node.h"
43 
44 namespace vrprouting {
45 namespace problem {
46 
63 Speed Vehicle::speed() const {return m_speed;}
64 
67 
72 TInterval Vehicle::duration() const {return is_phony()? 0 : back().arrival_time() - front().departure_time();}
73 
78 TInterval Vehicle::total_wait_time() const {return is_phony()? 0 : back().total_wait_time(); }
79 
84 TInterval Vehicle::total_travel_time() const {return is_phony()? 0 : back().total_travel_time();}
85 
90 TInterval Vehicle::total_service_time() const {return is_phony()? 0 : back().total_service_time();}
91 
92 int Vehicle::twvTot() const {return back().twvTot();}
93 
94 int Vehicle::cvTot() const {return back().cvTot();}
95 
96 bool Vehicle::has_twv() const {return twvTot() > m_user_twv;}
97 
98 bool Vehicle::has_cv() const {return cvTot() > m_user_cv;}
99 
100 void Vehicle::invariant() const {
101  pgassert(size() >= 2);
102  pgassert(front().is_start());
103  pgassert(back().is_end());
104 }
105 
106 bool Vehicle::is_ok() const {
107  return (start_site().opens() <= start_site().closes())
108  && (end_site().opens() <= end_site().closes())
109  && (m_capacity > 0);
110 }
111 
112 bool Vehicle::empty() const {return size() <= 2;}
113 
114 size_t Vehicle::length() const {return size() - 2;}
115 
116 bool Vehicle::is_phony() const {return id() < 0;}
117 
118 bool Vehicle::is_real() const {return !is_phony();}
119 
120 bool Vehicle::is_feasible() const {return !(has_twv() || has_cv());}
121 
122 const Vehicle_node& Vehicle::start_site() const {return front();}
123 
124 const Vehicle_node& Vehicle::end_site() const {return back();}
125 
127 
131 void Vehicle::evaluate(size_t from) {
132  invariant();
133  // preconditions
134  pgassert(from < size());
135 
136  using difference_type = std::vector<Vehicle_node>::difference_type;
137  auto node = begin() + static_cast<difference_type>(from);
138 
139  while (node != end()) {
140  if (node == begin()) {
141  node->evaluate(capacity());
142  } else {
143  node->evaluate(*(node - 1), capacity(), speed());
144  }
145 
146  ++node;
147  }
148  invariant();
149 }
150 
151 
152 void Vehicle::erase_node(size_t pos) {
153  using difference_type = std::vector<double>::difference_type;
154  pgassert(pos < size() - 1 && static_cast<difference_type>(pos) > 0);
155  std::deque<Vehicle_node>::erase(std::deque<Vehicle_node>::begin() + static_cast<difference_type>(pos));
156 }
157 
158 void Vehicle::insert_node(size_t pos, const Vehicle_node &node) {
159  using difference_type = std::vector<double>::difference_type;
160  pgassert(pos < size() && static_cast<difference_type>(pos) > 0);
161  std::deque<Vehicle_node>::insert(std::deque<Vehicle_node>::begin() + static_cast<difference_type>(pos), node);
162 }
163 
165  insert_node(1, node);
166 }
167 
169  insert_node(size() - 1, node);
170 }
171 
172 void Vehicle::erase(size_t pos) {
173  erase_node(pos);
174  evaluate(pos);
175 }
176 
184 void Vehicle::erase(const Vehicle_node &node) {
185  pgassert(!node.is_start() && !node.is_end());
186 #if 0
187  /* TODO this works, but somehow gives docqueries give different results */
188  std::deque<Vehicle_node>::erase(
189  std::remove_if(begin(), end(),
190  [&](const Vehicle_node& n) {return n.idx() == idx();}), end());
191  evaluate();
192 #else
193  for (size_t pos = 0 ; pos < size() ; ++pos) {
194  if (node.idx() == at(pos).idx()) {
195  erase(pos);
196  break;
197  }
198  }
199 #endif
200 }
201 
202 void Vehicle::insert(size_t pos, const Vehicle_node &node) {
203  insert_node(pos, node);
204  evaluate(pos);
205 }
206 
207 
208 void Vehicle::push_back(const Vehicle_node &node) {
209  insert_node(size() - 1, node);
210  evaluate(size() - 2);
211 }
212 
214  insert_node(1, node);
215  evaluate();
216 }
217 
219  erase_node(size() - 2);
220  evaluate(size() - 1);
221 }
222 
224  erase_node(1);
225  evaluate();
226 }
227 
228 void Vehicle::swap(size_t i, size_t j) {
229  pgassert(i < size() - 1 && i > 0);
230  pgassert(j < size() - 1 && j > 0);
231  std::swap(at(i), at(j));
232  i < j ? evaluate(i) : evaluate(j);
233 }
234 
236  Idx idx,
237  Id id,
238  const Vehicle_node &p_starting_site,
239  const Vehicle_node &p_ending_site,
240  PAmount p_capacity,
241  Speed p_speed) :
242  Identifier(idx, id),
243  m_capacity(p_capacity),
244  m_speed(p_speed) {
245  std::deque<Vehicle_node>::push_back(p_starting_site);
246  std::deque<Vehicle_node>::push_back(p_ending_site);
247  evaluate();
248  }
249 
250 std::string
251 Vehicle::tau() const {
252  invariant();
253  std::ostringstream log;
254  log << "truck " << id() << "(" << idx() << ")" << " (";
255  for (const auto &p_stop : *this) {
256  if (!(p_stop == front())) log << ", ";
257  p_stop.is_start() || p_stop.is_end()?
258  log << p_stop.type_str() << id() :
259  log << p_stop.type_str() << p_stop.order();
260  }
261  log << std::fixed << std::setprecision(4) << ")\t"
262  << "twv=" << twvTot()
263  << " cv=" << cvTot()
264  << " wait=" << total_wait_time()
265  << " duration=" << duration()
266  << " tt=" << total_travel_time()
267  << "\t";
268  return log.str();
269 }
270 
271 std::string
273  std::ostringstream key;
274 
275  for (const auto &p_stop : *this) {
276  if (!(p_stop == front())) key << ",";
277 
278  if (p_stop.is_start() || p_stop.is_end()) {
279  key << p_stop.type_str();
280  } else {
281  key << p_stop.type_str() << p_stop.order();
282  }
283  }
284  return key.str();
285 }
286 
291 std::vector<Solution_rt>
293  std::vector<Solution_rt> result;
294  int stop_seq(1);
295  for (const auto &p_stop : *this) {
296  result.push_back(p_stop.get_postgres_result(vid, id(), stop_seq));
297  ++stop_seq;
298  }
299  return result;
300 }
301 
305 std::vector<Id>
307  if (is_phony()) return std::vector<Id>();
308  std::vector<Id> result;
309  for (const auto &p_stop : *this) {
310  if (p_stop.is_start() || p_stop.is_end()) continue;
311  result.push_back(p_stop.order());
312  }
313  return result;
314 }
315 
316 /*
317  * start searching from postition low = pos(E)
318  *
319  * S 1 2 3 4 5 6 7 ..... E
320  * node -> E
321  * node -> ...
322  * node -> 7
323  * node -> 6
324  * node -> 5
325  * node /-> 4
326  *
327  * return low_limit = 5
328  *
329  */
330 size_t
332  invariant();
333 
334  size_t low = 0;
335  size_t high = size();
336  size_t low_limit = high;
337 
338  /* J == m_path[low_limit - 1] */
339  while (low_limit > low
340  && at(low_limit - 1).is_compatible_IJ(nodeI, speed())
341  && !at(low_limit - 1).is_pickup()) {
342  --low_limit;
343  }
344 
345  invariant();
346  return low_limit;
347 }
348 
365 size_t
367  invariant();
368 
369  size_t low = 0;
370  size_t high = size();
371  size_t low_limit = high;
372 
373  /* J == m_path[low_limit - 1] */
374  while (low_limit > low
375  && at(low_limit - 1).is_compatible_IJ(nodeI)) {
376  --low_limit;
377  }
378 
379  invariant();
380  return low_limit;
381 }
382 
383 /*
384  * start searching from postition low = pos(S)
385  *
386  * S 1 2 3 4 5 6 7 ..... E
387  * S -> node
388  * 1 -> node
389  * 2 -> node
390  * ...
391  * 6 -> node
392  * 7 /-> node
393  *
394  * returns high_limit = 7
395  */
396 size_t
398  invariant();
399 
400  size_t low = 0;
401  size_t high = size();
402  size_t high_limit = low;
403 
404  /* I == m_path[high_limit] */
405  while (high_limit < high
406  && nodeJ.is_compatible_IJ(at(high_limit), speed())) {
407  ++high_limit;
408  }
409 
410  invariant();
411  return high_limit;
412 }
413 
418 std::pair<size_t, size_t>
420  size_t high = getPosHighLimit(node);
421  size_t low = getPosLowLimit(node);
422  return std::make_pair(low, high);
423 }
424 
425 std::pair<size_t, size_t>
427  size_t high = getPosHighLimit(node);
428  size_t low = getDropPosLowLimit(node);
429  return std::make_pair(low, high);
430 }
431 
432 bool
433 operator<(const Vehicle &lhs, const Vehicle &rhs) {
434  /*
435  * capacity violations
436  */
437  if (lhs.cvTot() < rhs.cvTot()) return true;
438  if (lhs.cvTot() > rhs.cvTot()) return false;
439 
440  /*
441  * time window violations
442  */
443  if (lhs.twvTot() < rhs.twvTot()) return true;
444  if (lhs.twvTot() > rhs.twvTot()) return false;
445 
446  /*
447  * waiting time
448  */
449  if (lhs.total_wait_time() < rhs.total_wait_time()) return true;
450  if (lhs.total_wait_time() > rhs.total_wait_time()) return false;
451 
452  /*
453  * travel time
454  */
455  if (lhs.total_travel_time() < rhs.total_travel_time()) return true;
456  if (lhs.total_travel_time() > rhs.total_travel_time()) return false;
457 
458  /*
459  * duration
460  */
461  if (lhs.duration() < rhs.duration()) return true;
462  if (lhs.duration() > rhs.duration()) return false;
463 
464  /*
465  * truck size
466  */
467  if (lhs.size() < rhs.size()) return true;
468  return false;
469 }
470 
471 } // namespace problem
472 } // namespace vrprouting
473 
vrprouting::problem::Vehicle::m_speed
Speed m_speed
Definition: vehicle.h:183
vrprouting::problem::Vehicle::twvTot
int twvTot() const
Definition: vehicle.cpp:92
vrprouting::problem::Vehicle::evaluate
void evaluate()
Definition: vehicle.cpp:126
vrprouting::problem::Vehicle::invariant
void invariant() const
Definition: vehicle.cpp:100
vrprouting::problem::Vehicle::start_site
const Vehicle_node & start_site() const
Definition: vehicle.cpp:122
vrprouting::problem::Vehicle
Vehicle with time windows.
Definition: vehicle.h:61
vrprouting::problem::Vehicle::pop_front
void pop_front()
Definition: vehicle.cpp:223
vrprouting::Identifier::id
int64_t id() const
get the original id
Definition: identifier.cpp:42
vrprouting::problem::Vehicle::push_front
void push_front(const Vehicle_node &node)
Definition: vehicle.cpp:213
vehicle_node.h
vrprouting::problem::Vehicle::has_twv
bool has_twv() const
Definition: vehicle.cpp:96
vrprouting::problem::Tw_node::closes
TTimestamp closes() const
Returns the closing time.
Definition: tw_node.h:81
vrprouting::problem::Vehicle::m_user_cv
int m_user_cv
Time window violations on solution.
Definition: vehicle.h:179
vrprouting::problem::operator<
bool operator<(const Vehicle &lhs, const Vehicle &rhs)
Definition: vehicle.cpp:433
vrprouting::problem::Vehicle::is_real
bool is_real() const
Definition: vehicle.cpp:118
vrprouting::problem::Vehicle::push_front_node
void push_front_node(const Vehicle_node &node)
Definition: vehicle.cpp:168
vrprouting::problem::Vehicle::getDropPosLowLimit
size_t getDropPosLowLimit(const Vehicle_node &node) const
Definition: vehicle.cpp:331
vrprouting::problem::Vehicle::is_phony
bool is_phony() const
Definition: vehicle.cpp:116
vrprouting::problem::Vehicle::is_feasible
bool is_feasible() const
Definition: vehicle.cpp:120
pgassert
#define pgassert(expr)
Uses the standard assert syntax.
Definition: pgr_assert.h:95
vrprouting::problem::Vehicle::push_back
void push_back(const Vehicle_node &node)
Definition: vehicle.cpp:208
Speed
double Speed
Definition: typedefs.h:76
vrprouting::problem::Vehicle::end_site
const Vehicle_node & end_site() const
Definition: vehicle.cpp:124
vrprouting::problem::Vehicle::is_ok
bool is_ok() const
Definition: vehicle.cpp:106
vrprouting::problem::Vehicle::m_user_twv
int m_user_twv
Time window violations on solution.
Definition: vehicle.h:173
Id
int64_t Id
Definition: typedefs.h:78
vrprouting::problem::Vehicle::get_stops
std::vector< Id > get_stops() const
Definition: vehicle.cpp:306
vrprouting::problem::Vehicle::getPosHighLimit
size_t getPosHighLimit(const Vehicle_node &node) const
Get the highest position on the path where node can be placed.
Definition: vehicle.cpp:397
vrprouting::Identifier::idx
size_t idx() const
get the internal index
Definition: identifier.cpp:37
vrprouting::problem::Vehicle_node
Extend Tw_node to evaluate the vehicle at node level.
Definition: vehicle_node.h:49
identifier.h
vrprouting::problem::Vehicle::m_capacity
PAmount m_capacity
Definition: vehicle.h:182
vrprouting::problem::Vehicle::swap
void swap(size_t i, size_t j)
Definition: vehicle.cpp:228
vrprouting::problem::Tw_node::is_compatible_IJ
bool is_compatible_IJ(const Tw_node &I, Speed=1.0) const
is possible to arrive to this after visiting other?
Definition: tw_node.cpp:94
vrprouting::problem::Vehicle::path_str
std::string path_str() const
Definition: vehicle.cpp:272
vrprouting::problem::Vehicle::cvTot
int cvTot() const
Definition: vehicle.cpp:94
pgr_assert.h
An assert functionality that uses C++ throw().
vrprouting::problem::Vehicle::total_wait_time
TInterval total_wait_time() const
duration of vehicle while waiting for a node to open
Definition: vehicle.cpp:78
vrprouting::problem::Vehicle::duration
TInterval duration() const
duration of vehicle while not in a "depot"
Definition: vehicle.cpp:72
vrprouting::problem::Vehicle::pop_back
void pop_back()
Definition: vehicle.cpp:218
Idx
uint64_t Idx
Definition: typedefs.h:79
vrprouting::problem::Vehicle::erase
void erase(size_t pos)
Definition: vehicle.cpp:172
vrprouting::problem::Vehicle::get_postgres_result
std::vector< Solution_rt > get_postgres_result(int vid) const
Definition: vehicle.cpp:292
vehicle.h
vrprouting::problem::Tw_node::is_end
bool is_end() const
Is the node a valid vehicle's ending node.
Definition: tw_node.cpp:245
solution_rt.h
vrprouting::problem::Vehicle::total_travel_time
TInterval total_travel_time() const
total time spent moving from one node to another
Definition: vehicle.cpp:84
vrprouting::problem::Vehicle::erase_node
void erase_node(size_t pos)
Definition: vehicle.cpp:152
vrprouting::problem::Vehicle::Vehicle
Vehicle()=delete
vrprouting::problem::Vehicle::insert_node
void insert_node(size_t pos, const Vehicle_node &node)
Definition: vehicle.cpp:158
PAmount
uint32_t PAmount
Definition: typedefs.h:75
TInterval
int64_t TInterval
Definition: typedefs.h:72
vrprouting::problem::Vehicle::getPosLowLimit
size_t getPosLowLimit(const Vehicle_node &node) const
Get the lowest position on the path where node can be placed.
Definition: vehicle.cpp:366
vrprouting::problem::Vehicle::tau
std::string tau() const
Definition: vehicle.cpp:251
vrprouting::problem::Vehicle::push_back_node
void push_back_node(const Vehicle_node &node)
Definition: vehicle.cpp:164
vrprouting::problem::Vehicle::capacity
PAmount capacity() const
returns the capacity of the vehicle
Definition: vehicle.cpp:66
vrprouting::Identifier
Class that stores the information about identifiers.
Definition: identifier.h:65
vrprouting::problem::Vehicle::has_cv
bool has_cv() const
Definition: vehicle.cpp:98
vrprouting::problem::Vehicle::drop_position_limits
std::pair< size_t, size_t > drop_position_limits(const Vehicle_node &node) const
Definition: vehicle.cpp:426
vrprouting::problem::Vehicle::speed
Speed speed() const
the speed of the vehicle
Definition: vehicle.cpp:63
vrprouting::problem::Tw_node::opens
TTimestamp opens() const
Returns the opening time.
Definition: tw_node.h:78
vrprouting::problem::Vehicle::total_service_time
TInterval total_service_time() const
total time spent moving from one node to another
Definition: vehicle.cpp:90
vrprouting::problem::Vehicle::position_limits
std::pair< size_t, size_t > position_limits(const Vehicle_node &node) const
Get the limits to insert the node.
Definition: vehicle.cpp:419
vrprouting::problem::Tw_node::is_start
bool is_start() const
Is the node a valid vehicle's starting node.
Definition: tw_node.cpp:187
vrprouting::problem::Vehicle::insert
void insert(size_t pos, const Vehicle_node &node)
Definition: vehicle.cpp:202
vrprouting::problem::Vehicle::length
size_t length() const
Definition: vehicle.cpp:114
vrprouting::problem::Vehicle::empty
bool empty() const
Definition: vehicle.cpp:112
vrprouting
Definition: base_matrix.cpp:46