PGROUTING  2.5
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
6 Mail: project@pgrouting.org
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 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 > 6) {
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  for (size_t i = 0; i < total_pd_orders; i++) {
97  PGR_DBG("%ld %f pick %f %f %ld - "
98  "%f %f %f deliver %f %f %ld - %f %f %f ",
99  pd_orders_arr[i].id,
100  pd_orders_arr[i].demand,
101 
102  pd_orders_arr[i].pick_x,
103  pd_orders_arr[i].pick_y,
104  pd_orders_arr[i].pick_node_id,
105 
106  pd_orders_arr[i].pick_open_t,
107  pd_orders_arr[i].pick_close_t,
108  pd_orders_arr[i].pick_service_t,
109 
110  pd_orders_arr[i].deliver_x,
111  pd_orders_arr[i].deliver_y,
112  pd_orders_arr[i].deliver_node_id,
113 
114  pd_orders_arr[i].deliver_open_t,
115  pd_orders_arr[i].deliver_close_t,
116  pd_orders_arr[i].deliver_service_t);
117  }
118 
119  for (size_t i = 0; i < total_vehicles; i++) {
120  PGR_DBG("%ld %f %f / %ld %f %f %f %f %f / %ld %f %f %f %f %f / %ld ",
121  vehicles_arr[i].id,
122  vehicles_arr[i].capacity,
123  vehicles_arr[i].speed,
124 
125  vehicles_arr[i].start_node_id,
126  vehicles_arr[i].start_x,
127  vehicles_arr[i].start_y,
128  vehicles_arr[i].start_open_t,
129  vehicles_arr[i].start_close_t,
130  vehicles_arr[i].start_service_t,
131 
132  vehicles_arr[i].end_node_id,
133  vehicles_arr[i].end_x,
134  vehicles_arr[i].end_y,
135  vehicles_arr[i].end_open_t,
136  vehicles_arr[i].end_close_t,
137  vehicles_arr[i].end_service_t,
138 
139  vehicles_arr[i].cant_v);
140  }
141 
142  PGR_DBG("load matrix");
143  Matrix_cell_t *matrix_cells_arr = NULL;
144  size_t total_cells = 0;
145  pgr_get_matrixRows(matrix_sql, &matrix_cells_arr, &total_cells);
146 
147 
148  if (total_pd_orders == 0 || total_vehicles == 0 || total_cells == 0) {
149  (*result_count) = 0;
150  (*result_tuples) = NULL;
151  pgr_SPI_finish();
152  return;
153  }
154  PGR_DBG("Total %ld orders in query:", total_pd_orders);
155  PGR_DBG("Total %ld vehicles in query:", total_vehicles);
156  PGR_DBG("Total %ld matrix cells in query:", total_cells);
157 
158 
159  PGR_DBG("Starting processing");
160  clock_t start_t = clock();
161  char *log_msg = NULL;
162  char *notice_msg = NULL;
163  char *err_msg = NULL;
164 
166  pd_orders_arr, total_pd_orders,
167  vehicles_arr, total_vehicles,
168  matrix_cells_arr, total_cells,
169 
170  factor,
171  max_cycles,
172  initial_solution_id,
173 
174  result_tuples,
175  result_count,
176 
177  &log_msg,
178  &notice_msg,
179  &err_msg);
180 
181  time_msg("pgr_pickDeliver", start_t, clock());
182 
183  if (err_msg && (*result_tuples)) {
184  pfree(*result_tuples);
185  (*result_count) = 0;
186  (*result_tuples) = NULL;
187  }
188 #if 1
189  pgr_global_report(log_msg, notice_msg, err_msg);
190 #else
191  pgr_global_report(notice_msg, log_msg, err_msg);
192 #endif
193 
194  if (log_msg) pfree(log_msg);
195  if (notice_msg) pfree(notice_msg);
196  if (err_msg) pfree(err_msg);
197  if (pd_orders_arr) pfree(pd_orders_arr);
198  if (vehicles_arr) pfree(vehicles_arr);
199  if (matrix_cells_arr) pfree(matrix_cells_arr);
200 
201  pgr_SPI_finish();
202 }
203 
204 
205 
206 /******************************************************************************/
207 
208 
209 PGDLLEXPORT Datum
210 pickDeliver(PG_FUNCTION_ARGS) {
211  FuncCallContext *funcctx;
212  TupleDesc tuple_desc;
213 
214  /**************************************************************************/
215  General_vehicle_orders_t *result_tuples = 0;
216  size_t result_count = 0;
217  /**************************************************************************/
218 
219  if (SRF_IS_FIRSTCALL()) {
220  MemoryContext oldcontext;
221  funcctx = SRF_FIRSTCALL_INIT();
222  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
223 
224  /**********************************************************************
225  orders_sql TEXT,
226  vehicles_sql TEXT,
227  matrix_cell_sql TEXT,
228  factor FLOAT DEFAULT 1,
229  max_cycles INTEGER DEFAULT 10,
230  initial_sol INTEGER DEFAULT 4,
231  **********************************************************************/
232 
233  process(
234  text_to_cstring(PG_GETARG_TEXT_P(0)),
235  text_to_cstring(PG_GETARG_TEXT_P(1)),
236  text_to_cstring(PG_GETARG_TEXT_P(2)),
237  PG_GETARG_FLOAT8(3),
238  PG_GETARG_INT32(4),
239  PG_GETARG_INT32(5),
240  &result_tuples,
241  &result_count);
242 
243  /*********************************************************************/
244 
245 #if PGSQL_VERSION > 95
246  funcctx->max_calls = result_count;
247 #else
248  funcctx->max_calls = (uint32_t)result_count;
249 #endif
250  funcctx->user_fctx = result_tuples;
251  if (get_call_result_type(fcinfo, NULL, &tuple_desc)
252  != TYPEFUNC_COMPOSITE) {
253  ereport(ERROR,
254  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
255  errmsg("function returning record called in context "
256  "that cannot accept type record")));
257  }
258 
259  funcctx->tuple_desc = tuple_desc;
260  MemoryContextSwitchTo(oldcontext);
261  }
262 
263  funcctx = SRF_PERCALL_SETUP();
264  tuple_desc = funcctx->tuple_desc;
265  result_tuples = (General_vehicle_orders_t*) funcctx->user_fctx;
266 
267  if (funcctx->call_cntr < funcctx->max_calls) {
268  HeapTuple tuple;
269  Datum result;
270  Datum *values;
271  bool* nulls;
272  size_t call_cntr = funcctx->call_cntr;
273 
274  /*********************************************************************
275 
276  OUT seq INTEGER,
277  OUT vehicle_number INTEGER,
278  OUT vehicle_id BIGINT,
279  OUT vehicle_seq INTEGER,
280  OUT order_id BIGINT,
281  OUT stop_type INT,
282  OUT cargo FLOAT,
283  OUT travel_time FLOAT,
284  OUT arrival_time FLOAT,
285  OUT wait_time FLOAT,
286  OUT service_time FLOAT,
287  OUT departure_time FLOAT
288 
289  *********************************************************************/
290 
291 
292  size_t numb = 13;
293  values = palloc(numb * sizeof(Datum));
294  nulls = palloc(numb * sizeof(bool));
295 
296  size_t i;
297  for (i = 0; i < numb; ++i) {
298  nulls[i] = false;
299  }
300 
301 
302  values[0] = Int32GetDatum(funcctx->call_cntr + 1);
303  values[1] = Int32GetDatum(result_tuples[call_cntr].vehicle_seq);
304  values[2] = Int64GetDatum(result_tuples[call_cntr].vehicle_id);
305  values[3] = Int32GetDatum(result_tuples[call_cntr].stop_seq);
306  values[4] = Int32GetDatum(result_tuples[call_cntr].stop_type + 1);
307  values[5] = Int64GetDatum(result_tuples[call_cntr].stop_id);
308  values[6] = Int64GetDatum(result_tuples[call_cntr].order_id);
309  values[7] = Float8GetDatum(result_tuples[call_cntr].cargo);
310  values[8] = Float8GetDatum(result_tuples[call_cntr].travelTime);
311  values[9] = Float8GetDatum(result_tuples[call_cntr].arrivalTime);
312  values[10] = Float8GetDatum(result_tuples[call_cntr].waitTime);
313  values[11] = Float8GetDatum(result_tuples[call_cntr].serviceTime);
314  values[12] = Float8GetDatum(result_tuples[call_cntr].departureTime);
315 
316  /*********************************************************************/
317 
318  tuple = heap_form_tuple(tuple_desc, values, nulls);
319  result = HeapTupleGetDatum(tuple);
320  SRF_RETURN_NEXT(funcctx, result);
321  } else {
322  SRF_RETURN_DONE(funcctx);
323  }
324 }
void pgr_get_vehicles_with_id(char *vehicles_sql, Vehicle_t **vehicles, size_t *total_vehicles)
Reads the vehicles orders.
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
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:214
#define PGR_DBG(...)
Definition: debug_macro.h:34
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
void pgr_global_report(char *log, char *notice, char *err)
notice & error
Definition: e_report.c:93
void pgr_SPI_finish(void)
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)
if(DOXYGEN_FOUND) configure_file($
Definition: CMakeLists.txt:13
void pgr_SPI_connect(void)
void pgr_get_matrixRows(char *sql, Matrix_cell_t **rows, size_t *total_rows)
bigint start_vid, bigint end_vid, float agg_cost,
PGDLLEXPORT Datum pickDeliver(PG_FUNCTION_ARGS)
Definition: pickDeliver.c:210
PG_FUNCTION_INFO_V1(pickDeliver)