vrpRouting  0.3
pickDeliver/pickDeliver_driver.cpp File Reference
#include "drivers/pickDeliver_driver.h"
#include <cstring>
#include <sstream>
#include <string>
#include <deque>
#include "problem/pickDeliver.h"
#include "c_types/pickDeliveryOrders_t.h"
#include "c_types/solution_rt.h"
#include "c_types/vehicle_t.h"
#include "problem/matrix.h"
#include "cpp_common/pgr_assert.h"
#include "initialsol/tabu.h"
#include "optimizers/tabu.h"
#include "c_common/pgr_alloc.hpp"
Include dependency graph for pickDeliver/pickDeliver_driver.cpp:

Go to the source code of this file.

Functions

void do_pickDeliver (PickDeliveryOrders_t *customers_arr, size_t total_customers, Vehicle_t *vehicles_arr, size_t total_vehicles, Matrix_cell_t *matrix_cells_arr, size_t total_cells, Time_multipliers_t *multipliers_arr, size_t total_multipliers, bool optimize, double factor, int max_cycles, bool stop_on_all_served, int64_t execution_date, Solution_rt **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
 

Function Documentation

◆ do_pickDeliver()

void do_pickDeliver ( PickDeliveryOrders_t customers_arr,
size_t  total_customers,
Vehicle_t vehicles_arr,
size_t  total_vehicles,
Matrix_cell_t matrix_cells_arr,
size_t  total_cells,
Time_multipliers_t multipliers_arr,
size_t  total_multipliers,
bool  optimize,
double  factor,
int  max_cycles,
bool  stop_on_all_served,
int64_t  execution_date,
Solution_rt **  return_tuples,
size_t *  return_count,
char **  log_msg,
char **  notice_msg,
char **  err_msg 
)
Parameters
[in]customers_arrA C Array of pickup and dropoff orders
[in]total_customerssize of the customers_arr
[in]vehicles_arrA C Array of vehicles
[in]total_vehiclessize of the vehicles_arr
[in]matrix_cells_arrA C Array of the (time) matrix cells
[in]total_cellssize of the matrix_cells_arr
[in]multipliers_arrA C Array of the multipliers
[in]total_multiplierssize of the multipliers_arr
[in]optimizeflag to control optimization
[in]factorA global multiplier for the (time) matrix cells
[in]max_cyclesnumber of cycles to perform during the optimization phase
[in]stop_on_all_servedIndicator to stop optimization when all orders are served
[in]execution_dateValue used for not moving orders that are before this date
[out]return_tuplesC array of contents to be returned to postgres
[out]return_countnumber of tuples returned
[out]log_msgspecial log message pointer
[out]notice_msgspecial message pointer to be returned as NOTICE
[out]err_msgspecial message pointer to be returned as ERROR
Returns
void
Precondition
The messages: log_msg, notice_msg, err_msg must be empty (=nullptr)
The C arrays: customers_arr, vehicles_arr, matrix_cells_arr must not be empty
The C array: return_tuples must be empty
Only matrix cells (i, i) can be missing and are considered as 0 (time units)
Postcondition
The C arrays: customers_arr, vehicles_arr, matrix_cells_arr Do not change
The C array: return_tuples contains the result for the problem given
The return_tuples array size is return_count
err_msg is empty if no throw from the process is catched
log_msg contains some logging
notice_msg is empty
dot_inline_dotgraph_4.png

Definition at line 108 of file pickDeliver/pickDeliver_driver.cpp.

126  {
127  std::ostringstream log;
128  std::ostringstream notice;
129  std::ostringstream err;
130  try {
131  /*
132  * verify preconditions
133  */
134  pgassert(!(*log_msg));
135  pgassert(!(*notice_msg));
136  pgassert(!(*err_msg));
137  pgassert(total_customers);
138  pgassert(total_vehicles);
139  pgassert(total_cells);
140  pgassert(*return_count == 0);
141  pgassert(!(*return_tuples));
142  log << "do_pickDeliver\n";
143 
144  *return_tuples = nullptr;
145  *return_count = 0;
146 
147  Identifiers<Id> node_ids;
148  Identifiers<Id> order_ids;
149 
150  for (size_t i = 0; i < total_customers; ++i) {
151  node_ids += customers_arr[i].pick_node_id;
152  node_ids += customers_arr[i].deliver_node_id;
153  order_ids += customers_arr[i].id;
154  }
155 
156  bool missing = false;
157  for (size_t i = 0; i < total_vehicles; ++i) {
158  auto vehicle = vehicles_arr[i];
159  node_ids += vehicle.start_node_id;
160  node_ids += vehicle.end_node_id;
161  for (size_t j = 0; j < vehicle.stops_size; ++j) {
162  if (!order_ids.has(vehicle.stops[j])) {
163  if (!missing) err << "Order in 'stops' information missing";
164  missing = true;
165  err << "Missing information of order " << vehicle.stops[j] << "\n";
166  }
167  }
168  if (missing) {
169  *err_msg = pgr_msg(err.str());
170  return;
171  }
172  }
173 
174  vrprouting::problem::Matrix cost_matrix(
175  matrix_cells_arr, total_cells,
176  multipliers_arr, total_multipliers,
177  node_ids, static_cast<Multiplier>(factor));
178 #if 1
179  /*
180  * Verify matrix triangle inequality
181  */
182  if (!cost_matrix.obeys_triangle_inequality()) {
183  log << "[PickDeliver] Fixing Matrix that does not obey triangle inequality ";
184  log << cost_matrix.fix_triangle_inequality() << " cycles used";
185 
186  if (!cost_matrix.obeys_triangle_inequality()) {
187  log << "[pickDeliver] Matrix Still does not obey triangle inequality ";
188  }
189  }
190 #endif
191  /*
192  * Verify matrix cells preconditions
193  */
194  if (!cost_matrix.has_no_infinity()) {
195  err << "An Infinity value was found on the Matrix";
196  *err_msg = pgr_msg(err.str());
197  return;
198  }
199 
200 
201  log << "stop_on_all_served" << stop_on_all_served << "\n";
202  log << "execution_date" << execution_date << "\n";
203  log << "Initialize problem\n";
204  /*
205  * Construct problem
206  */
208  customers_arr, total_customers,
209  vehicles_arr, total_vehicles,
210  cost_matrix);
211 
212  err << pd_problem.msg.get_error();
213  if (!err.str().empty()) {
214  log << pd_problem.msg.get_error();
215  log << pd_problem.msg.get_log();
216  *log_msg = pgr_msg(log.str());
217  *err_msg = pgr_msg(err.str());
218  return;
219  }
220  log << pd_problem.msg.get_log();
221  pd_problem.msg.clear();
222 
223  log << "Finish Initialize problem\n";
224 
225 #if 0
226  try {
227 #endif
228  /*
229  * get initial solutions
230  */
231  using Initial_solution = vrprouting::initialsol::tabu::Initial_solution;
232  using Solution = vrprouting::problem::Solution;
233  auto sol = static_cast<Solution>(Initial_solution(execution_date, optimize, &pd_problem));
234  /*
235  * Solve (optimize)
236  */
238  sol = Optimize(sol, static_cast<size_t>(max_cycles), stop_on_all_served, optimize);
239 #if 0
240  } catch (AssertFailedException &except) {
241  log << pd_problem.msg.get_log();
242  throw;
243  } catch(...) {
244  log << "Caught unknown exception!";
245  throw;
246  }
247 #endif
248 
249  log << pd_problem.msg.get_log();
250  pd_problem.msg.clear();
251  log << "Finish solve\n";
252 
253  /*
254  * Prepare results
255  */
256  auto solution = sol.get_postgres_result();
257  log << pd_problem.msg.get_log();
258  pd_problem.msg.clear();
259  log << "solution size: " << solution.size() << "\n";
260 
261 
262  if (!solution.empty()) {
263  (*return_tuples) = pgr_alloc(solution.size(), (*return_tuples));
264  int seq = 0;
265  for (const auto &row : solution) {
266  (*return_tuples)[seq] = row;
267  ++seq;
268  }
269  }
270  (*return_count) = solution.size();
271 
272  log << pd_problem.msg.get_log();
273 
274  pgassert(*err_msg == nullptr);
275  *log_msg = log.str().empty()?
276  nullptr :
277  pgr_msg(log.str());
278  *notice_msg = notice.str().empty()?
279  nullptr :
280  pgr_msg(notice.str());
281  } catch (AssertFailedException &except) {
282  if (*return_tuples) free(*return_tuples);
283  (*return_count) = 0;
284  err << except.what() << log.str();
285  *err_msg = pgr_msg(err.str());
286  } catch (std::exception& except) {
287  if (*return_tuples) free(*return_tuples);
288  (*return_count) = 0;
289  err << except.what() << log.str();
290  *err_msg = pgr_msg(err.str());
291  } catch(...) {
292  if (*return_tuples) free(*return_tuples);
293  (*return_count) = 0;
294  err << "Caught unknown exception!" << log.str();
295  *err_msg = pgr_msg(err.str());
296  }
297 }

References vrprouting::Pgr_messages::clear(), PickDeliveryOrders_t::deliver_node_id, vrprouting::base::Base_Matrix::fix_triangle_inequality(), vrprouting::Pgr_messages::get_error(), vrprouting::Pgr_messages::get_log(), Identifiers< T >::has(), vrprouting::base::Base_Matrix::has_no_infinity(), PickDeliveryOrders_t::id, vrprouting::problem::PickDeliver::msg, vrprouting::base::Base_Matrix::obeys_triangle_inequality(), pgassert, pgr_alloc(), pgr_msg(), PickDeliveryOrders_t::pick_node_id, and AssertFailedException::what().

Referenced by process().

PickDeliveryOrders_t::deliver_node_id
Id deliver_node_id
Deliver y coordinate: used in stand alone program for benchmarks.
Definition: pickDeliveryOrders_t.h:72
vrprouting::problem::Solution
Definition: solution.h:50
pgr_alloc
T * pgr_alloc(std::size_t size, T *ptr)
allocates memory
Definition: pgr_alloc.hpp:66
pgr_msg
char * pgr_msg(const std::string &msg)
Definition: pgr_alloc.cpp:33
AssertFailedException::what
virtual const char * what() const
Definition: pgr_assert.cpp:67
vrprouting::problem::PickDeliver
the pick deliver problem
Definition: pickDeliver.h:50
vrprouting::optimizers::tabu::Optimize
Class that optimizes a solution.
Definition: optimizers/tabu.h:51
vrprouting::initialsol::tabu::Initial_solution
Definition: initialsol/tabu.h:45
pgassert
#define pgassert(expr)
Uses the standard assert syntax.
Definition: pgr_assert.h:95
vrprouting::problem::Matrix
Definition: matrix.h:46
PickDeliveryOrders_t::id
Id id
Definition: pickDeliveryOrders_t.h:59
PickDeliveryOrders_t::pick_node_id
Id pick_node_id
Pick y coordinate: used in stand alone program for benchmarks.
Definition: pickDeliveryOrders_t.h:64
Identifiers::has
bool has(const T other) const
true ids() has element
Definition: identifiers.hpp:100
Multiplier
double Multiplier
Definition: typedefs.h:77
Identifiers
Definition: identifiers.hpp:51
AssertFailedException
Extends std::exception and is the exception that we throw if an assert fails.
Definition: pgr_assert.h:140