PGROUTING  3.2
pickDeliver.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: pickDeliver.c
3 
4 Generated with Template by:
5 Copyright (c) 2015 pgRouting developers
7 
8 Function's developer:
9 Copyright (c) 2015 Celia Virginia Vergara Castillo
10 Mail:
11 
12 ------
13 
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18 
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23 
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 
28  ********************************************************************PGR-GNU*/
29 
31 #include "c_common/debug_macro.h"
32 #include "c_common/e_report.h"
33 #include "c_common/time_msg.h"
34 #include "c_common/orders_input.h"
38 
39 PGDLLEXPORT Datum
40 _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  General_vehicle_orders_t **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  elog(ERROR, "Illegal value in parameter: max_cycles");
68  (*result_count) = 0;
69  (*result_tuples) = NULL;
70  return;
71  }
72 
73  if (initial_solution_id < 0 || initial_solution_id > 7) {
74  elog(ERROR, "Illegal value in parameter: initial");
75  (*result_count) = 0;
76  (*result_tuples) = NULL;
77  return;
78  }
79 
81 
82  PGR_DBG("Load orders");
83  PickDeliveryOrders_t *pd_orders_arr = NULL;
84  size_t total_pd_orders = 0;
85  pgr_get_pd_orders_with_id(pd_orders_sql,
86  &pd_orders_arr, &total_pd_orders);
87 
88  PGR_DBG("Load vehicles");
89  Vehicle_t *vehicles_arr = NULL;
90  size_t total_vehicles = 0;
91  pgr_get_vehicles_with_id(vehicles_sql,
92  &vehicles_arr, &total_vehicles);
93  PGR_DBG("total vehicles %ld", total_vehicles);
94 
95 
96 #if 0
97  for (size_t i = 0; i < total_pd_orders; i++) {
98  PGR_DBG("%ld %f pick %f %f %ld - "
99  "%f %f %f deliver %f %f %ld - %f %f %f ",
100  pd_orders_arr[i].id,
101  pd_orders_arr[i].demand,
102 
103  pd_orders_arr[i].pick_x,
104  pd_orders_arr[i].pick_y,
105  pd_orders_arr[i].pick_node_id,
106 
107  pd_orders_arr[i].pick_open_t,
108  pd_orders_arr[i].pick_close_t,
109  pd_orders_arr[i].pick_service_t,
110 
111  pd_orders_arr[i].deliver_x,
112  pd_orders_arr[i].deliver_y,
113  pd_orders_arr[i].deliver_node_id,
114 
115  pd_orders_arr[i].deliver_open_t,
116  pd_orders_arr[i].deliver_close_t,
117  pd_orders_arr[i].deliver_service_t);
118  }
119 
120  for (size_t i = 0; i < total_vehicles; i++) {
121  PGR_DBG("%ld %f %f / %ld %f %f %f %f %f / %ld %f %f %f %f %f / %ld ",
122  vehicles_arr[i].id,
123  vehicles_arr[i].capacity,
124  vehicles_arr[i].speed,
125 
126  vehicles_arr[i].start_node_id,
127  vehicles_arr[i].start_x,
128  vehicles_arr[i].start_y,
129  vehicles_arr[i].start_open_t,
130  vehicles_arr[i].start_close_t,
131  vehicles_arr[i].start_service_t,
132 
133  vehicles_arr[i].end_node_id,
134  vehicles_arr[i].end_x,
135  vehicles_arr[i].end_y,
136  vehicles_arr[i].end_open_t,
137  vehicles_arr[i].end_close_t,
138  vehicles_arr[i].end_service_t,
139 
140  vehicles_arr[i].cant_v);
141  }
142 #endif
143  PGR_DBG("load matrix");
144  Matrix_cell_t *matrix_cells_arr = NULL;
145  size_t total_cells = 0;
146  pgr_get_matrixRows(matrix_sql, &matrix_cells_arr, &total_cells);
147 
148 
149  if (total_pd_orders == 0 || total_vehicles == 0 || total_cells == 0) {
150  (*result_count) = 0;
151  (*result_tuples) = NULL;
152  pgr_SPI_finish();
153  return;
154  }
155  PGR_DBG("Total %ld orders in query:", total_pd_orders);
156  PGR_DBG("Total %ld vehicles in query:", total_vehicles);
157  PGR_DBG("Total %ld matrix cells in query:", total_cells);
158 
159 
160  PGR_DBG("Starting processing");
161  clock_t start_t = clock();
162  char *log_msg = NULL;
163  char *notice_msg = NULL;
164  char *err_msg = NULL;
165 
167  pd_orders_arr, total_pd_orders,
168  vehicles_arr, total_vehicles,
169  matrix_cells_arr, total_cells,
170 
171  factor,
172  max_cycles,
173  initial_solution_id,
174 
175  result_tuples,
176  result_count,
177 
178  &log_msg,
179  &notice_msg,
180  &err_msg);
181 
182  time_msg("pgr_pickDeliver", start_t, clock());
183 
184  if (err_msg && (*result_tuples)) {
185  pfree(*result_tuples);
186  (*result_count) = 0;
187  (*result_tuples) = NULL;
188  }
189 #if 1
190  pgr_global_report(log_msg, notice_msg, err_msg);
191 #else
192  pgr_global_report(notice_msg, log_msg, err_msg);
193 #endif
194 
195  if (log_msg) pfree(log_msg);
196  if (notice_msg) pfree(notice_msg);
197  if (err_msg) pfree(err_msg);
198  if (pd_orders_arr) pfree(pd_orders_arr);
199  if (vehicles_arr) pfree(vehicles_arr);
200  if (matrix_cells_arr) pfree(matrix_cells_arr);
201 
202  pgr_SPI_finish();
203 }
204 
205 
206 
207 /******************************************************************************/
208 
209 
210 PGDLLEXPORT Datum
211 _pgr_pickdeliver(PG_FUNCTION_ARGS) {
212  FuncCallContext *funcctx;
213  TupleDesc tuple_desc;
214 
215  /**************************************************************************/
216  General_vehicle_orders_t *result_tuples = 0;
217  size_t result_count = 0;
218  /**************************************************************************/
219 
220  if (SRF_IS_FIRSTCALL()) {
221  MemoryContext oldcontext;
222  funcctx = SRF_FIRSTCALL_INIT();
223  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
224 
225  /**********************************************************************
226  orders_sql TEXT,
227  vehicles_sql TEXT,
228  matrix_cell_sql TEXT,
229  factor FLOAT DEFAULT 1,
230  max_cycles INTEGER DEFAULT 10,
231  initial_sol INTEGER DEFAULT 4,
232  **********************************************************************/
233 
234  process(
235  text_to_cstring(PG_GETARG_TEXT_P(0)),
236  text_to_cstring(PG_GETARG_TEXT_P(1)),
237  text_to_cstring(PG_GETARG_TEXT_P(2)),
238  PG_GETARG_FLOAT8(3),
239  PG_GETARG_INT32(4),
240  PG_GETARG_INT32(5),
241  &result_tuples,
242  &result_count);
243 
244  /*********************************************************************/
245 
246 #if PGSQL_VERSION > 95
247  funcctx->max_calls = result_count;
248 #else
249  funcctx->max_calls = (uint32_t)result_count;
250 #endif
251  funcctx->user_fctx = result_tuples;
252  if (get_call_result_type(fcinfo, NULL, &tuple_desc)
253  != TYPEFUNC_COMPOSITE) {
254  ereport(ERROR,
255  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
256  errmsg("function returning record called in context "
257  "that cannot accept type record")));
258  }
259 
260  funcctx->tuple_desc = tuple_desc;
261  MemoryContextSwitchTo(oldcontext);
262  }
263 
264  funcctx = SRF_PERCALL_SETUP();
265  tuple_desc = funcctx->tuple_desc;
266  result_tuples = (General_vehicle_orders_t*) funcctx->user_fctx;
267 
268  if (funcctx->call_cntr < funcctx->max_calls) {
269  HeapTuple tuple;
270  Datum result;
271  Datum *values;
272  bool* nulls;
273  size_t call_cntr = funcctx->call_cntr;
274 
275  /*********************************************************************
276 
277  OUT seq INTEGER,
278  OUT vehicle_number INTEGER,
279  OUT vehicle_id BIGINT,
280  OUT vehicle_seq INTEGER,
281  OUT order_id BIGINT,
282  OUT stop_type INT,
283  OUT cargo FLOAT,
284  OUT travel_time FLOAT,
285  OUT arrival_time FLOAT,
286  OUT wait_time FLOAT,
287  OUT service_time FLOAT,
288  OUT departure_time FLOAT
289 
290  *********************************************************************/
291 
292 
293  size_t numb = 13;
294  values = palloc(numb * sizeof(Datum));
295  nulls = palloc(numb * sizeof(bool));
296 
297  size_t i;
298  for (i = 0; i < numb; ++i) {
299  nulls[i] = false;
300  }
301 
302 
303  values[0] = Int32GetDatum(funcctx->call_cntr + 1);
304  values[1] = Int32GetDatum(result_tuples[call_cntr].vehicle_seq);
305  values[2] = Int64GetDatum(result_tuples[call_cntr].vehicle_id);
306  values[3] = Int32GetDatum(result_tuples[call_cntr].stop_seq);
307  values[4] = Int32GetDatum(result_tuples[call_cntr].stop_type + 1);
308  values[5] = Int64GetDatum(result_tuples[call_cntr].stop_id);
309  values[6] = Int64GetDatum(result_tuples[call_cntr].order_id);
310  values[7] = Float8GetDatum(result_tuples[call_cntr].cargo);
311  values[8] = Float8GetDatum(result_tuples[call_cntr].travelTime);
312  values[9] = Float8GetDatum(result_tuples[call_cntr].arrivalTime);
313  values[10] = Float8GetDatum(result_tuples[call_cntr].waitTime);
314  values[11] = Float8GetDatum(result_tuples[call_cntr].serviceTime);
315  values[12] = Float8GetDatum(result_tuples[call_cntr].departureTime);
316 
317  /*********************************************************************/
318 
319  tuple = heap_form_tuple(tuple_desc, values, nulls);
320  result = HeapTupleGetDatum(tuple);
321  SRF_RETURN_NEXT(funcctx, result);
322  } else {
323  SRF_RETURN_DONE(funcctx);
324  }
325 }
pgr_get_pd_orders_with_id
void pgr_get_pd_orders_with_id(char *pd_orders_sql, PickDeliveryOrders_t **pd_orders, size_t *total_pd_orders)
Reads the pick-Deliver orders.
Definition: orders_input.c:213
pgr_get_matrixRows
void pgr_get_matrixRows(char *sql, Matrix_cell_t **rows, size_t *total_rows)
bigint start_vid, bigint end_vid, float agg_cost,
Definition: matrixRows_input.c:56
time_msg.h
postgres_connection.h
PickDeliveryOrders_t
Definition: pickDeliveryOrders_t.h:43
pgr_SPI_connect
void pgr_SPI_connect(void)
Definition: postgres_connection.c:82
pgr_SPI_finish
void pgr_SPI_finish(void)
Definition: postgres_connection.c:71
e_report.h
matrixRows_input.h
Vehicle_t
Definition: vehicle_t.h:40
process
static void process(char *pd_orders_sql, char *vehicles_sql, char *matrix_sql, double factor, int max_cycles, int initial_solution_id, General_vehicle_orders_t **result_tuples, size_t *result_count)
Definition: pickDeliver.c:46
orders_input.h
vehicles_input.h
debug_macro.h
pickDeliver_driver.h
PGR_DBG
#define PGR_DBG(...)
Definition: debug_macro.h:34
PG_FUNCTION_INFO_V1
PG_FUNCTION_INFO_V1(_pgr_pickdeliver)
if
if(DOXYGEN_FOUND) configure_file($
Definition: doxygen/CMakeLists.txt:13
do_pgr_pickDeliver
void do_pgr_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, double factor, int max_cycles, int initial_solution_id, General_vehicle_orders_t **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
Definition: pickDeliver_driver.cpp:47
General_vehicle_orders_t
Definition: general_vehicle_orders_t.h:49
time_msg
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
matrix_cell
Definition: matrix_cell_t.h:37
pgr_global_report
void pgr_global_report(char *log, char *notice, char *err)
notice & error
Definition: e_report.c:93
pgr_get_vehicles_with_id
void pgr_get_vehicles_with_id(char *vehicles_sql, Vehicle_t **vehicles, size_t *total_vehicles)
Reads the vehicles orders.
Definition: vehicles_input.c:267
_pgr_pickdeliver
PGDLLEXPORT Datum _pgr_pickdeliver(PG_FUNCTION_ARGS)
Definition: pickDeliver.c:211