PGROUTING  2.6
pickDeliverEuclidean.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: pickDeliverEuclidean.c
3 
4 Generated with Template by:
5 Copyright (c) 2017 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 "utils/array.h"
32 
33 #include "c_common/debug_macro.h"
34 #include "c_common/e_report.h"
35 #include "c_common/time_msg.h"
36 #include "c_common/orders_input.h"
38 
40 
41 PGDLLEXPORT Datum
42 pickDeliverEuclidean(PG_FUNCTION_ARGS);
44 
45 
46 static
47 void
49  char* pd_orders_sql,
50  char* vehicles_sql,
51  double factor,
52  int max_cycles,
53  int initial_solution_id,
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  ereport(ERROR,
68  (errcode(ERRCODE_INTERNAL_ERROR),
69  errmsg("Illegal value in parameter: max_cycles"),
70  errhint("Negative value found: max_cycles: %d ", max_cycles)));
71  (*result_count) = 0;
72  (*result_tuples) = NULL;
73  return;
74  }
75 
76  if (initial_solution_id <= 0 || initial_solution_id > 6) {
77  elog(ERROR, "Illegal value in parameter: initial_sol");
78  (*result_count) = 0;
79  (*result_tuples) = NULL;
80  return;
81  }
82 
84 
85  PGR_DBG("Load orders");
86  PickDeliveryOrders_t *pd_orders_arr = NULL;
87  size_t total_pd_orders = 0;
88  pgr_get_pd_orders(pd_orders_sql,
89  &pd_orders_arr, &total_pd_orders);
90 
91  PGR_DBG("Load vehicles");
92  Vehicle_t *vehicles_arr = NULL;
93  size_t total_vehicles = 0;
94  pgr_get_vehicles(vehicles_sql,
95  &vehicles_arr, &total_vehicles);
96  PGR_DBG("total vehicles %ld", total_vehicles);
97 
98  for (size_t i = 0; i < total_pd_orders; i++) {
99  PGR_DBG("%ld %f pick %f %f %ld - "
100  "%f %f %f deliver %f %f %ld - %f %f %f ",
101  pd_orders_arr[i].id,
102  pd_orders_arr[i].demand,
103 
104  pd_orders_arr[i].pick_x,
105  pd_orders_arr[i].pick_y,
106  pd_orders_arr[i].pick_node_id,
107 
108  pd_orders_arr[i].pick_open_t,
109  pd_orders_arr[i].pick_close_t,
110  pd_orders_arr[i].pick_service_t,
111 
112  pd_orders_arr[i].deliver_x,
113  pd_orders_arr[i].deliver_y,
114  pd_orders_arr[i].deliver_node_id,
115 
116  pd_orders_arr[i].deliver_open_t,
117  pd_orders_arr[i].deliver_close_t,
118  pd_orders_arr[i].deliver_service_t);
119  }
120 
121 
122 
123  for (size_t i = 0; i < total_vehicles; i++) {
124  PGR_DBG("%ld %f %f , start %f %f %f %f %f "
125  "end %f %f %f %f %f number %ld ",
126  vehicles_arr[i].id,
127  vehicles_arr[i].capacity,
128  vehicles_arr[i].speed,
129 
130  vehicles_arr[i].start_x,
131  vehicles_arr[i].start_y,
132  vehicles_arr[i].start_open_t,
133  vehicles_arr[i].start_close_t,
134  vehicles_arr[i].start_service_t,
135 
136  vehicles_arr[i].end_x,
137  vehicles_arr[i].end_y,
138  vehicles_arr[i].end_open_t,
139  vehicles_arr[i].end_close_t,
140  vehicles_arr[i].end_service_t,
141 
142  vehicles_arr[i].cant_v);
143  }
144 
145  if (total_pd_orders == 0 || total_vehicles == 0) {
146  (*result_count) = 0;
147  (*result_tuples) = NULL;
148  pgr_SPI_finish();
149  return;
150  }
151  PGR_DBG("Total %ld orders in query:", total_pd_orders);
152 
153  PGR_DBG("Starting processing");
154  clock_t start_t = clock();
155  char *log_msg = NULL;
156  char *notice_msg = NULL;
157  char *err_msg = NULL;
159  pd_orders_arr, total_pd_orders,
160  vehicles_arr, total_vehicles,
161 
162  factor,
163  max_cycles,
164  initial_solution_id,
165 
166  result_tuples,
167  result_count,
168 
169  &log_msg,
170  &notice_msg,
171  &err_msg);
172  time_msg("_pgr_pickDeliverEuclidean", start_t, clock());
173 
174  if (err_msg && (*result_tuples)) {
175  pfree(*result_tuples);
176  (*result_count) = 0;
177  (*result_tuples) = NULL;
178  }
179 
180  pgr_global_report(log_msg, notice_msg, err_msg);
181 
182  if (log_msg) pfree(log_msg);
183  if (notice_msg) pfree(notice_msg);
184  if (err_msg) pfree(err_msg);
185  if (pd_orders_arr) pfree(pd_orders_arr);
186  if (vehicles_arr) pfree(vehicles_arr);
187 
188  pgr_SPI_finish();
189 }
190 /* */
191 /******************************************************************************/
192 
193 PGDLLEXPORT Datum
194 pickDeliverEuclidean(PG_FUNCTION_ARGS) {
195  FuncCallContext *funcctx;
196  TupleDesc tuple_desc;
197 
198  /**************************************************************************/
199  /* MODIFY AS NEEDED */
200  /* */
201  General_vehicle_orders_t *result_tuples = 0;
202  size_t result_count = 0;
203  /* */
204  /**************************************************************************/
205 
206  if (SRF_IS_FIRSTCALL()) {
207  MemoryContext oldcontext;
208  funcctx = SRF_FIRSTCALL_INIT();
209  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
210 
211  /**********************************************************************/
212  /* MODIFY AS NEEDED */
213  /*
214  orders_sql TEXT,
215  vehicles_sql INTEGER,
216  max_cycles INTEGER,
217  initial_id INTEGER,
218  **********************************************************************/
219 
220  PGR_DBG("Calling process");
221  process(
222  text_to_cstring(PG_GETARG_TEXT_P(0)),
223  text_to_cstring(PG_GETARG_TEXT_P(1)),
224  PG_GETARG_FLOAT8(2),
225  PG_GETARG_INT32(3),
226  PG_GETARG_INT32(4),
227  &result_tuples,
228  &result_count);
229 
230  /* */
231  /*********************************************************************/
232 
233 #if PGSQL_VERSION > 95
234  funcctx->max_calls = result_count;
235 #else
236  funcctx->max_calls = (uint32_t)result_count;
237 #endif
238  funcctx->user_fctx = result_tuples;
239  if (get_call_result_type(fcinfo, NULL, &tuple_desc)
240  != TYPEFUNC_COMPOSITE) {
241  ereport(ERROR,
242  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
243  errmsg("function returning record called in context "
244  "that cannot accept type record")));
245  }
246 
247  funcctx->tuple_desc = tuple_desc;
248  MemoryContextSwitchTo(oldcontext);
249  }
250 
251  funcctx = SRF_PERCALL_SETUP();
252  tuple_desc = funcctx->tuple_desc;
253  result_tuples = (General_vehicle_orders_t*) funcctx->user_fctx;
254 
255  if (funcctx->call_cntr < funcctx->max_calls) {
256  HeapTuple tuple;
257  Datum result;
258  Datum *values;
259  bool* nulls;
260  size_t call_cntr = funcctx->call_cntr;
261 
262  /*********************************************************************/
263  /* MODIFY!!!!! */
264  /* This has to match you output otherwise the server crashes */
265  /*
266  OUT seq INTEGER,
267  OUT vehicle_id INTEGER,
268  OUT vehicle_seq INTEGER,
269  OUT order_id BIGINT,
270  OUT cost FLOAT,
271  OUT agg_cost FLOAT
272  *********************************************************************/
273 
274 
275  size_t numb = 12;
276  values = palloc(numb * sizeof(Datum));
277  nulls = palloc(numb * sizeof(bool));
278 
279  size_t i;
280  for (i = 0; i < numb; ++i) {
281  nulls[i] = false;
282  }
283 
284 
285  // postgres starts counting from 1
286  values[0] = Int32GetDatum(funcctx->call_cntr + 1);
287  values[1] = Int32GetDatum(result_tuples[call_cntr].vehicle_seq);
288  values[2] = Int64GetDatum(result_tuples[call_cntr].vehicle_id);
289  values[3] = Int32GetDatum(result_tuples[call_cntr].stop_seq);
290  values[4] = Int32GetDatum(result_tuples[call_cntr].stop_type + 1);
291  values[5] = Int64GetDatum(result_tuples[call_cntr].order_id);
292  values[6] = Float8GetDatum(result_tuples[call_cntr].cargo);
293  values[7] = Float8GetDatum(result_tuples[call_cntr].travelTime);
294  values[8] = Float8GetDatum(result_tuples[call_cntr].arrivalTime);
295  values[9] = Float8GetDatum(result_tuples[call_cntr].waitTime);
296  values[10] = Float8GetDatum(result_tuples[call_cntr].serviceTime);
297  values[11] = Float8GetDatum(result_tuples[call_cntr].departureTime);
298 
299  /*********************************************************************/
300 
301  tuple = heap_form_tuple(tuple_desc, values, nulls);
302  result = HeapTupleGetDatum(tuple);
303  SRF_RETURN_NEXT(funcctx, result);
304  } else {
305  SRF_RETURN_DONE(funcctx);
306  }
307 }
void pgr_get_pd_orders(char *pd_orders_sql, PickDeliveryOrders_t **pd_orders, size_t *total_pd_orders)
Reads the pick-Deliver orders.
Definition: orders_input.c:206
#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)
PGDLLEXPORT Datum pickDeliverEuclidean(PG_FUNCTION_ARGS)
if(DOXYGEN_FOUND) configure_file($
Definition: CMakeLists.txt:13
void pgr_SPI_connect(void)
static void process(char *pd_orders_sql, char *vehicles_sql, double factor, int max_cycles, int initial_solution_id, General_vehicle_orders_t **result_tuples, size_t *result_count)
PG_FUNCTION_INFO_V1(pickDeliverEuclidean)
void do_pgr_pickDeliverEuclidean(PickDeliveryOrders_t *customers_arr, size_t total_customers, Vehicle_t *vehicles_arr, size_t total_vehicles, 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)
void pgr_get_vehicles(char *vehicles_sql, Vehicle_t **vehicles, size_t *total_vehicles)
Reads the vehicles orders.