vrpRouting  0.3
pgr_pickDeliver/pickDeliver_driver.cpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: pickDeliver_driver.cpp
3 
4 Copyright (c) 2015 pgRouting developers
6 
7 Function's developer:
8 Copyright (c) 2015 Celia Virginia Vergara Castillo
9 
10 ------
11 
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21 
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 
26  ********************************************************************PGR-GNU*/
27 
28 
30 
31 #include <string.h>
32 #include <sstream>
33 #include <string>
34 #include <deque>
35 #include <vector>
36 #include <utility>
37 
39 #include "c_types/solution_rt.h"
40 #include "c_common/pgr_alloc.hpp"
41 #include "cpp_common/pgr_assert.h"
42 #include "problem/solution.h"
43 #include "initialsol/simple.h"
44 #include "optimizers/simple.h"
45 
46 #include "problem/pickDeliver.h"
48 #include "problem/matrix.h"
49 
50 namespace {
52 get_initial_solution(vrprouting::problem::PickDeliver* problem_ptr, int m_initial_id) {
53  using Solution = vrprouting::problem::Solution;
54  using Initial_solution = vrprouting::initialsol::simple::Initial_solution;
56  Solution m_solutions(problem_ptr);
57  if (m_initial_id == 0) {
58  for (int i = 1; i < 7; ++i) {
59  if (i == 1) {
60  m_solutions = Initial_solution((Initials_code)i, problem_ptr);
61  } else {
62  auto new_sol = Initial_solution((Initials_code)i, problem_ptr);
63  m_solutions = (new_sol < m_solutions)? new_sol : m_solutions;
64  }
65  }
66  } else {
67  m_solutions = Initial_solution((Initials_code)m_initial_id, problem_ptr);
68  }
69 
70  return m_solutions;
71 }
72 } // namespace
73 
74 void
76  struct PickDeliveryOrders_t customers_arr[],
77  size_t total_customers,
78 
79  Vehicle_t *vehicles_arr,
80  size_t total_vehicles,
81 
82  Matrix_cell_t *matrix_cells_arr,
83  size_t total_cells,
84 
85  double factor,
86  int max_cycles,
87  int initial_solution_id,
88 
89  Solution_rt **return_tuples,
90  size_t *return_count,
91 
92  char **log_msg,
93  char **notice_msg,
94  char **err_msg) {
95  std::ostringstream log;
96  std::ostringstream notice;
97  std::ostringstream err;
98  try {
99  pgassert(!(*log_msg));
100  pgassert(!(*notice_msg));
101  pgassert(!(*err_msg));
102  pgassert(total_customers);
103  pgassert(total_vehicles);
104  pgassert(total_vehicles);
105  pgassert(*return_count == 0);
106  pgassert(!(*return_tuples));
107  log << "do_pgr_pickDeliver\n";
108 
109 
110  *return_tuples = nullptr;
111  *return_count = 0;
112 
113  Identifiers<Id> node_ids;
114  Identifiers<Id> order_ids;
115 
116  for (size_t i = 0; i < total_customers; ++i) {
117  node_ids += customers_arr[i].pick_node_id;
118  node_ids += customers_arr[i].deliver_node_id;
119  order_ids += customers_arr[i].id;
120  }
121 
122  for (size_t i = 0; i < total_vehicles; ++i) {
123  auto vehicle = vehicles_arr[i];
124  node_ids += vehicle.start_node_id;
125  node_ids += vehicle.end_node_id;
126  }
127 
128  log << node_ids;
129 
130  /*
131  * transform to C++ containers
132  */
133  std::vector<Vehicle_t> vehicles(
134  vehicles_arr, vehicles_arr + total_vehicles);
135 
136  vrprouting::problem::Matrix time_matrix(
137  matrix_cells_arr,
138  total_cells,
139  node_ids,
140  static_cast<Multiplier>(factor));
141 
142 #if 0
143  auto depot_node = vehicles[0].start_node_id;
144 
145  /*
146  * This applies to the one depot problem
147  */
148  if ((Initials_code)(initial_solution_id) == Initials_code::OneDepot) {
149  /*
150  * All Vehicles must depart from same location
151  */
152  for (const auto &v : vehicles) {
153  if (v.start_node_id != depot_node && v.end_node_id != depot_node) {
154  err << "All vehicles must depart & arrive to same node";
155  *err_msg = pgr_msg(err.str().c_str());
156  return;
157  }
158  }
159 
160  /*
161  * All Orders must depart from depot
162  */
163  for (size_t i = 0; i < total_customers; ++i) {
164  if (customers_arr[i].pick_node_id != depot_node) {
165  err << "All orders must be picked at depot";
166  *err_msg = pgr_msg(err.str().c_str());
167  return;
168  }
169  }
170  }
171 #endif
172 
173  if (!time_matrix.has_no_infinity()) {
174  err << "An Infinity value was found on the Matrix. Might be missing information of a node";
175  *err_msg = pgr_msg(err.str().c_str());
176  return;
177  }
178 
179  // TODO(vicky) wrap with a try and make a throw???
180  // tried it is already wrapped
181  log << "Initialize problem\n";
183  customers_arr, total_customers,
184  vehicles_arr, total_vehicles,
185  time_matrix);
186 
187  err << pd_problem.msg.get_error();
188  if (!err.str().empty()) {
189  log << pd_problem.msg.get_log();
190  *log_msg = pgr_msg(log.str().c_str());
191  *err_msg = pgr_msg(err.str().c_str());
192  return;
193  }
194  log << pd_problem.msg.get_log();
195  log << "Finish Reading data\n";
196  pd_problem.msg.clear();
197 
198 #if 0
199  try {
200 #endif
202  auto sol = get_initial_solution(&pd_problem, initial_solution_id);
204  sol = Optimize(sol, static_cast<size_t>(max_cycles), (Initials_code)initial_solution_id);
205 #if 0
206  } catch (AssertFailedException &except) {
207  log << pd_problem.msg.get_log();
208  pd_problem.msg.clear();
209  throw;
210  } catch(...) {
211  log << "Caught unknown exception!";
212  throw;
213  }
214 #endif
215 
216  log << pd_problem.msg.get_log();
217  log << "Finish solve\n";
218  pd_problem.msg.clear();
219 
220  auto solution = sol.get_postgres_result();
221  log << pd_problem.msg.get_log();
222  pd_problem.msg.clear();
223  log << "solution size: " << solution.size() << "\n";
224 
225 
226  if (!solution.empty()) {
227  (*return_tuples) = pgr_alloc(solution.size(), (*return_tuples));
228  int seq = 0;
229  for (const auto &row : solution) {
230  (*return_tuples)[seq] = row;
231  ++seq;
232  }
233  }
234  (*return_count) = solution.size();
235 
236  pgassert(*err_msg == NULL);
237  *log_msg = log.str().empty()?
238  nullptr :
239  pgr_msg(log.str().c_str());
240  *notice_msg = notice.str().empty()?
241  nullptr :
242  pgr_msg(notice.str().c_str());
243  } catch (AssertFailedException &except) {
244  if (*return_tuples) free(*return_tuples);
245  (*return_count) = 0;
246  err << except.what();
247  *err_msg = pgr_msg(err.str().c_str());
248  *log_msg = pgr_msg(log.str().c_str());
249  } catch (std::exception& except) {
250  if (*return_tuples) free(*return_tuples);
251  (*return_count) = 0;
252  err << except.what();
253  *err_msg = pgr_msg(err.str().c_str());
254  *log_msg = pgr_msg(log.str().c_str());
255  } catch (const std::pair<std::string, std::string>& ex) {
256  (*return_count) = 0;
257  err << ex.first;
258  log << ex.second;
259  *err_msg = pgr_msg(err.str().c_str());
260  *log_msg = pgr_msg(log.str().c_str());
261  } catch (const std::pair<std::string, int64_t>& ex) {
262  (*return_count) = 0;
263  err << ex.first;
264  log << "FOOOO missing on matrix: id = " << ex.second;
265  *err_msg = pgr_msg(err.str().c_str());
266  *log_msg = pgr_msg(log.str().c_str());
267  } catch(...) {
268  if (*return_tuples) free(*return_tuples);
269  (*return_count) = 0;
270  err << "Caught unknown exception!";
271  *err_msg = pgr_msg(err.str().c_str());
272  *log_msg = pgr_msg(log.str().c_str());
273  }
274 }
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
do_pgr_pickDeliver
void do_pgr_pickDeliver(struct 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, double factor, int max_cycles, int initial_solution_id, Solution_rt **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
Definition: pgr_pickDeliver/pickDeliver_driver.cpp:75
pgr_alloc
T * pgr_alloc(std::size_t size, T *ptr)
allocates memory
Definition: pgr_alloc.hpp:66
pickDeliveryOrders_t.h
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::initialsol::simple::Initials_code
Initials_code
Different kinds to insert an order into the vehicle.
Definition: initialsol/initials_code.h:37
PickDeliveryOrders_t
order's attributes
Definition: pickDeliveryOrders_t.h:56
simple.h
initials_code.h
vrprouting::problem::PickDeliver
the pick deliver problem
Definition: pickDeliver.h:50
Vehicle_t
vehicles's attributes
Definition: vehicle_t.h:50
vrprouting::initialsol::simple::OneDepot
@ OneDepot
Push front order that allows more orders to be inserted at the front.
Definition: initialsol/initials_code.h:45
pgassert
#define pgassert(expr)
Uses the standard assert syntax.
Definition: pgr_assert.h:95
pickDeliver_driver.h
matrix.h
vrprouting::problem::PickDeliver::msg
Pgr_messages msg
message controller for all classes
Definition: pickDeliver.h:99
pgr_alloc.hpp
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
vrprouting::Pgr_messages::get_log
std::string get_log() const
gets the contents of log message
Definition: pgr_messages.cpp:36
pickDeliver.h
Solution_rt
Solution schedule when twv & cw are hard restrictions.
Definition: solution_rt.h:56
pgr_assert.h
An assert functionality that uses C++ throw().
vrprouting::base::Base_Matrix::has_no_infinity
bool has_no_infinity() const
does the matrix values not given by the user?
Definition: base_matrix.cpp:459
vrprouting::initialsol::simple::Initial_solution
Definition: initialsol/simple.h:45
vrprouting::Pgr_messages::get_error
std::string get_error() const
gets the contents of error message
Definition: pgr_messages.cpp:53
Matrix_cell_t
traveling costs
Definition: matrix_cell_t.h:41
vrprouting::Pgr_messages::clear
void clear()
Clears all the messages.
Definition: pgr_messages.cpp:59
solution_rt.h
solution.h
simple.h
Multiplier
double Multiplier
Definition: typedefs.h:77
vrprouting::optimizers::simple::Optimize
Definition: optimizers/simple.h:40
anonymous_namespace{pickDeliver_driver.cpp}::get_initial_solution
vrprouting::problem::Solution get_initial_solution(vrprouting::problem::PickDeliver *problem_ptr, int m_initial_id)
Definition: pgr_pickDeliver/pickDeliver_driver.cpp:52
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