vrpRouting  0.3
pgr_pickDeliver/pickDeliver.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: pickDeliver.c
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 
29 #include "c_common/debug_macro.h"
30 #include "c_common/e_report.h"
31 #include "c_common/time_msg.h"
32 #include "c_common/orders_input.h"
36 #include "c_types/solution_rt.h"
38 
39 PGDLLEXPORT Datum
40 _vrp_pgr_pickdeliver(PG_FUNCTION_ARGS);
42 
43 
44 static
45 void
47  char* pd_orders_sql,
48  char* vehicles_sql,
49  char* matrix_sql,
50  double factor,
51  int max_cycles,
52  int initial_solution_id,
53 
54  Solution_rt **result_tuples,
55  size_t *result_count) {
56  if (factor <= 0) {
57  ereport(ERROR,
58  (errcode(ERRCODE_INTERNAL_ERROR),
59  errmsg("Illegal value in parameter: factor"),
60  errhint("Value found: %f <= 0", factor)));
61  (*result_count) = 0;
62  (*result_tuples) = NULL;
63  return;
64  }
65 
66  if (max_cycles < 0) {
67  ereport(ERROR,
68  (errcode(ERRCODE_INTERNAL_ERROR),
69  errmsg("Illegal value in parameter: max_cycles"),
70  errhint("Value found: %d <= 0", max_cycles)));
71  (*result_count) = 0;
72  (*result_tuples) = NULL;
73  return;
74  }
75 
76  if (initial_solution_id < 0 || initial_solution_id > 7) {
77  ereport(ERROR,
78  (errcode(ERRCODE_INTERNAL_ERROR),
79  errmsg("Illegal value in parameter: initial"),
80  errhint("Value found: %d <= 0", initial_solution_id)));
81  (*result_count) = 0;
82  (*result_tuples) = NULL;
83  return;
84  }
85 
87 
88  PickDeliveryOrders_t *pd_orders_arr = NULL;
89  size_t total_pd_orders = 0;
90  get_shipments_raw(pd_orders_sql,
91  &pd_orders_arr, &total_pd_orders);
92 
93  if (total_pd_orders == 0) {
94  (*result_count) = 0;
95  (*result_tuples) = NULL;
96 
97  /* freeing memory before return */
98  if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
99 
100  pgr_SPI_finish();
101  ereport(ERROR,
102  (errcode(ERRCODE_INTERNAL_ERROR),
103  errmsg("No orders found")));
104  return;
105  }
106 
107 
108  Vehicle_t *vehicles_arr = NULL;
109  size_t total_vehicles = 0;
110  get_vehicles_raw(vehicles_sql,
111  &vehicles_arr, &total_vehicles,
112  false);
113 
114  if (total_vehicles == 0) {
115  (*result_count) = 0;
116  (*result_tuples) = NULL;
117 
118  /* freeing memory before return */
119  if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
120  if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
121 
122  pgr_SPI_finish();
123  ereport(ERROR,
124  (errcode(ERRCODE_INTERNAL_ERROR),
125  errmsg("No vehicles found")));
126  return;
127  }
128 
129 #if 0
130  PGR_DBG("total orders %ld", total_pd_orders);
131  for (size_t i = 0; i < total_pd_orders; i++) {
132  PGR_DBG("%ld %f pick %ld - %ld %ld %ld"
133  "deliver %ld - %ld %ld %ld ",
134  pd_orders_arr[i].id,
135  pd_orders_arr[i].demand,
136 
137  pd_orders_arr[i].pick_node_id,
138 
139  pd_orders_arr[i].pick_open_t,
140  pd_orders_arr[i].pick_close_t,
141  pd_orders_arr[i].pick_service_t,
142 
143  pd_orders_arr[i].deliver_node_id,
144 
145  pd_orders_arr[i].deliver_open_t,
146  pd_orders_arr[i].deliver_close_t,
147  pd_orders_arr[i].deliver_service_t);
148  }
149 
150 
151 
152  PGR_DBG("total vehicles %ld", total_vehicles);
153  for (size_t i = 0; i < total_vehicles; i++) {
154  PGR_DBG("%ld %f %f , start %ld %ld %ld %ld "
155  "end %ld %ld %ld %ld number %ld ",
156  vehicles_arr[i].id,
157  vehicles_arr[i].capacity,
158  vehicles_arr[i].speed,
159 
160  vehicles_arr[i].start_node_id,
161  vehicles_arr[i].start_open_t,
162  vehicles_arr[i].start_close_t,
163  vehicles_arr[i].start_service_t,
164 
165  vehicles_arr[i].end_node_id,
166  vehicles_arr[i].end_open_t,
167  vehicles_arr[i].end_close_t,
168  vehicles_arr[i].end_service_t,
169 
170  vehicles_arr[i].cant_v);
171  }
172 #endif
173 
174  Matrix_cell_t *matrix_cells_arr = NULL;
175  size_t total_cells = 0;
176  get_matrixRows_plain(matrix_sql, &matrix_cells_arr, &total_cells);
177 
178  PGR_DBG("total matrix rows %ld", total_cells);
179 #if 0
180  for (size_t i = 0; i < total_cells; i++) {
181  PGR_DBG("%ld %ld %f",
182  matrix_cells_arr[i].from_vid,
183  matrix_cells_arr[i].to_vid,
184  matrix_cells_arr[i].cost);
185  }
186 #endif
187 
188  if (total_cells == 0) {
189  (*result_count) = 0;
190  (*result_tuples) = NULL;
191 
192  /* freeing memory before return */
193  if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
194  if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
195  if (matrix_cells_arr) {pfree(matrix_cells_arr); matrix_cells_arr = NULL;}
196 
197  ereport(WARNING,
198  (errcode(ERRCODE_INTERNAL_ERROR),
199  errmsg("No matrix found")));
200  pgr_SPI_finish();
201  return;
202  }
203 
204 
205  PGR_DBG("Total %ld orders in query:", total_pd_orders);
206  PGR_DBG("Total %ld vehicles in query:", total_vehicles);
207  PGR_DBG("Total %ld matrix cells in query:", total_cells);
208 
209 
210  PGR_DBG("Starting processing");
211  clock_t start_t = clock();
212  char *log_msg = NULL;
213  char *notice_msg = NULL;
214  char *err_msg = NULL;
215 
217  pd_orders_arr, total_pd_orders,
218  vehicles_arr, total_vehicles,
219  matrix_cells_arr, total_cells,
220 
221  factor,
222  max_cycles,
223  initial_solution_id,
224 
225  result_tuples,
226  result_count,
227 
228  &log_msg,
229  &notice_msg,
230  &err_msg);
231 
232  time_msg("pgr_pickDeliver", start_t, clock());
233 
234  if (err_msg && (*result_tuples)) {
235  pfree(*result_tuples);
236  (*result_count) = 0;
237  (*result_tuples) = NULL;
238  }
239  pgr_global_report(log_msg, notice_msg, err_msg);
240 
241  /* freeing memory before return */
242  if (log_msg) {pfree(log_msg); log_msg = NULL;}
243  if (notice_msg) {pfree(notice_msg); notice_msg = NULL;}
244  if (err_msg) {pfree(err_msg); err_msg = NULL;}
245  if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
246  if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
247  if (matrix_cells_arr) {pfree(matrix_cells_arr); matrix_cells_arr = NULL;}
248 
249  pgr_SPI_finish();
250 }
251 
252 
253 
254 /******************************************************************************/
255 
256 
257 PGDLLEXPORT Datum
258 _vrp_pgr_pickdeliver(PG_FUNCTION_ARGS) {
259  FuncCallContext *funcctx;
260  TupleDesc tuple_desc;
261 
262  /**************************************************************************/
263  Solution_rt *result_tuples = 0;
264  size_t result_count = 0;
265  /**************************************************************************/
266 
267  if (SRF_IS_FIRSTCALL()) {
268  MemoryContext oldcontext;
269  funcctx = SRF_FIRSTCALL_INIT();
270  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
271 
272  /**********************************************************************
273  orders_sql TEXT,
274  vehicles_sql TEXT,
275  matrix_cell_sql TEXT,
276  factor FLOAT DEFAULT 1,
277  max_cycles INTEGER DEFAULT 10,
278  initial_sol INTEGER DEFAULT 4,
279  **********************************************************************/
280 
281  process(
282  text_to_cstring(PG_GETARG_TEXT_P(0)),
283  text_to_cstring(PG_GETARG_TEXT_P(1)),
284  text_to_cstring(PG_GETARG_TEXT_P(2)),
285  PG_GETARG_FLOAT8(3),
286  PG_GETARG_INT32(4),
287  PG_GETARG_INT32(5),
288  &result_tuples,
289  &result_count);
290 
291  /*********************************************************************/
292 
293  funcctx->max_calls = result_count;
294  funcctx->user_fctx = result_tuples;
295  if (get_call_result_type(fcinfo, NULL, &tuple_desc)
296  != TYPEFUNC_COMPOSITE) {
297  ereport(ERROR,
298  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
299  errmsg("function returning record called in context "
300  "that cannot accept type record")));
301  }
302 
303  funcctx->tuple_desc = tuple_desc;
304  MemoryContextSwitchTo(oldcontext);
305  }
306 
307  funcctx = SRF_PERCALL_SETUP();
308  tuple_desc = funcctx->tuple_desc;
309  result_tuples = (Solution_rt*) funcctx->user_fctx;
310 
311  if (funcctx->call_cntr < funcctx->max_calls) {
312  HeapTuple tuple;
313  Datum result;
314  Datum *values;
315  bool* nulls;
316  size_t call_cntr = funcctx->call_cntr;
317 
318  /*********************************************************************
319 
320  OUT seq INTEGER,
321  OUT vehicle_number INTEGER,
322  OUT vehicle_id BIGINT,
323  OUT vehicle_seq INTEGER,
324  OUT order_id BIGINT,
325  OUT stop_type INT,
326  OUT cargo FLOAT,
327  OUT travel_time FLOAT,
328  OUT arrival_time FLOAT,
329  OUT wait_time FLOAT,
330  OUT service_time FLOAT,
331  OUT departure_time FLOAT
332 
333  *********************************************************************/
334 
335 
336  size_t numb = 13;
337  values = palloc(numb * sizeof(Datum));
338  nulls = palloc(numb * sizeof(bool));
339 
340  size_t i;
341  for (i = 0; i < numb; ++i) {
342  nulls[i] = false;
343  }
344 
345 
346  values[0] = Int32GetDatum(funcctx->call_cntr + 1);
347  values[1] = Int32GetDatum(result_tuples[call_cntr].vehicle_seq);
348  values[2] = Int64GetDatum(result_tuples[call_cntr].vehicle_id);
349  values[3] = Int32GetDatum(result_tuples[call_cntr].stop_seq);
350  values[4] = Int32GetDatum(result_tuples[call_cntr].stop_type + 1);
351  values[5] = Int64GetDatum(result_tuples[call_cntr].stop_id);
352  values[6] = Int64GetDatum(result_tuples[call_cntr].order_id);
353  values[7] = Int64GetDatum(result_tuples[call_cntr].cargo);
354  values[8] = Int64GetDatum(result_tuples[call_cntr].travelTime);
355  values[9] = Int64GetDatum(result_tuples[call_cntr].arrivalTime);
356  values[10] = Int64GetDatum(result_tuples[call_cntr].waitDuration);
357  values[11] = Int64GetDatum(result_tuples[call_cntr].serviceDuration);
358  values[12] = Int64GetDatum(result_tuples[call_cntr].departureTime);
359 
360  /*********************************************************************/
361 
362  tuple = heap_form_tuple(tuple_desc, values, nulls);
363  result = HeapTupleGetDatum(tuple);
364  SRF_RETURN_NEXT(funcctx, result);
365  } else {
366  SRF_RETURN_DONE(funcctx);
367  }
368 }
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
time_msg.h
pickDeliveryOrders_t.h
postgres_connection.h
PickDeliveryOrders_t
order's attributes
Definition: pickDeliveryOrders_t.h:56
pgr_SPI_connect
void pgr_SPI_connect(void)
Definition: postgres_connection.c:79
get_matrixRows_plain
void get_matrixRows_plain(char *sql, Matrix_cell_t **rows, size_t *total_rows)
Get the travel time matrix with numerical types.
Definition: matrixRows_input.c:203
_vrp_pgr_pickdeliver
PGDLLEXPORT Datum _vrp_pgr_pickdeliver(PG_FUNCTION_ARGS)
Definition: pgr_pickDeliver/pickDeliver.c:258
pgr_SPI_finish
void pgr_SPI_finish(void)
Definition: postgres_connection.c:71
e_report.h
matrixRows_input.h
Vehicle_t
vehicles's attributes
Definition: vehicle_t.h:50
orders_input.h
vehicles_input.h
debug_macro.h
pickDeliver_driver.h
get_vehicles_raw
void get_vehicles_raw(char *sql, Vehicle_t **rows, size_t *total_rows, bool with_stops)
Reads the vehicles information.
Definition: vehicles_input.c:522
PGR_DBG
#define PGR_DBG(...)
Definition: debug_macro.h:34
Solution_rt
Solution schedule when twv & cw are hard restrictions.
Definition: solution_rt.h:56
if
if(DOXYGEN_FOUND) configure_file($
Definition: doxygen/CMakeLists.txt:13
Matrix_cell_t
traveling costs
Definition: matrix_cell_t.h:41
time_msg
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
solution_rt.h
PG_FUNCTION_INFO_V1
PG_FUNCTION_INFO_V1(_vrp_pgr_pickdeliver)
pgr_global_report
void pgr_global_report(char *log, char *notice, char *err)
notice & error
Definition: e_report.c:30
get_shipments_raw
void get_shipments_raw(char *sql, PickDeliveryOrders_t **rows, size_t *total_rows)
Reads the pick-Deliver shipments for raw data.
Definition: orders_input.c:376
process
static void process(char *pd_orders_sql, char *vehicles_sql, char *matrix_sql, double factor, int max_cycles, int initial_solution_id, Solution_rt **result_tuples, size_t *result_count)
Definition: pgr_pickDeliver/pickDeliver.c:46