vrpRouting  0.3
optimize.c File Reference
Include dependency graph for optimize.c:

Go to the source code of this file.

Functions

PGDLLEXPORT Datum _vrp_optimize (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (_vrp_optimize)
 
static void process (char *pd_orders_sql, char *vehicles_sql, char *matrix_sql, char *multipliers_sql, double factor, int max_cycles, int64_t execution_date, bool check_triangle_inequality, int subdivision_kind, bool use_timestamps, Short_vehicle_rt **result_tuples, size_t *result_count)
 

Function Documentation

◆ _vrp_optimize()

PGDLLEXPORT Datum _vrp_optimize ( PG_FUNCTION_ARGS  )

Definition at line 241 of file optimize.c.

241  {
242  FuncCallContext *funcctx;
243  TupleDesc tuple_desc;
244 
245  /**************************************************************************/
246  Short_vehicle_rt *result_tuples = 0;
247  size_t result_count = 0;
248  /**************************************************************************/
249 
250  if (SRF_IS_FIRSTCALL()) {
251  MemoryContext oldcontext;
252  funcctx = SRF_FIRSTCALL_INIT();
253  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
254 
255  process(
256  text_to_cstring(PG_GETARG_TEXT_P(0)),
257  text_to_cstring(PG_GETARG_TEXT_P(1)),
258  text_to_cstring(PG_GETARG_TEXT_P(2)),
259  text_to_cstring(PG_GETARG_TEXT_P(3)),
260 
261  PG_GETARG_FLOAT8(4),
262  PG_GETARG_INT32(5),
263  PG_GETARG_INT64(6),
264 
265  PG_GETARG_BOOL(7),
266  PG_GETARG_INT32(8),
267  PG_GETARG_BOOL(9),
268 
269  &result_tuples,
270  &result_count);
271 
272  /*********************************************************************/
273 
274 #if PGSQL_VERSION > 95
275  funcctx->max_calls = result_count;
276 #else
277  funcctx->max_calls = (uint32_t)result_count;
278 #endif
279  funcctx->user_fctx = result_tuples;
280  if (get_call_result_type(fcinfo, NULL, &tuple_desc)
281  != TYPEFUNC_COMPOSITE) {
282  ereport(ERROR,
283  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
284  errmsg("function returning record called in context "
285  "that cannot accept type record")));
286  }
287 
288  funcctx->tuple_desc = tuple_desc;
289  MemoryContextSwitchTo(oldcontext);
290  }
291 
292  funcctx = SRF_PERCALL_SETUP();
293  tuple_desc = funcctx->tuple_desc;
294  result_tuples = (Short_vehicle_rt*) funcctx->user_fctx;
295 
296  if (funcctx->call_cntr < funcctx->max_calls) {
297  HeapTuple tuple;
298  Datum result;
299  Datum *values;
300  bool* nulls;
301  size_t call_cntr = funcctx->call_cntr;
302 
303  size_t numb = 3;
304  values = palloc(numb * sizeof(Datum));
305  nulls = palloc(numb * sizeof(bool));
306 
307  size_t i;
308  for (i = 0; i < numb; ++i) {
309  nulls[i] = false;
310  }
311 
312 
313  values[0] = Int32GetDatum(funcctx->call_cntr + 1);
314  values[1] = Int64GetDatum(result_tuples[call_cntr].vehicle_id);
315  values[2] = Int64GetDatum(result_tuples[call_cntr].order_id);
316 
317  /*********************************************************************/
318 
319  tuple = heap_form_tuple(tuple_desc, values, nulls);
320  result = HeapTupleGetDatum(tuple);
321 
322  pfree(values); values = NULL;
323  pfree(nulls); nulls = NULL;
324 
325  SRF_RETURN_NEXT(funcctx, result);
326  } else {
327  if (result_tuples) {pfree(result_tuples); result_tuples = NULL;}
328  funcctx->user_fctx = NULL;
329  SRF_RETURN_DONE(funcctx);
330  }
331 }

References if(), and process().

◆ PG_FUNCTION_INFO_V1()

PG_FUNCTION_INFO_V1 ( _vrp_optimize  )

◆ process()

static void process ( char *  pd_orders_sql,
char *  vehicles_sql,
char *  matrix_sql,
char *  multipliers_sql,
double  factor,
int  max_cycles,
int64_t  execution_date,
bool  check_triangle_inequality,
int  subdivision_kind,
bool  use_timestamps,
Short_vehicle_rt **  result_tuples,
size_t *  result_count 
)
static

[Factor must be postive]

[max_cycles must be postive]

[subdivision_kind can be: 0, 1, or 2]

Definition at line 49 of file optimize.c.

64  {
66  if (factor <= 0) {
67  ereport(ERROR,
68  (errcode(ERRCODE_INTERNAL_ERROR),
69  errmsg("Illegal value in parameter: factor"),
70  errhint("Value found: %f <= 0", factor)));
71  }
72 
74  if (max_cycles < 0) {
75  ereport(ERROR,
76  (errcode(ERRCODE_INTERNAL_ERROR),
77  errmsg("Illegal value in parameter: max_cycles"),
78  errhint("Value found: %d <= 0", max_cycles)));
79  }
80 
82  if (subdivision_kind < 0 || subdivision_kind > 2) {
83  ereport(ERROR,
84  (errcode(ERRCODE_INTERNAL_ERROR),
85  errmsg("Illegal value in parameter: subdivision_kind"),
86  errhint("Value found: %d", max_cycles)));
87  }
88 
90 
91  PickDeliveryOrders_t *pd_orders_arr = NULL;
92  size_t total_pd_orders = 0;
93  if (use_timestamps) {
94  get_shipments(pd_orders_sql, &pd_orders_arr, &total_pd_orders);
95  } else {
96  get_shipments_raw(pd_orders_sql, &pd_orders_arr, &total_pd_orders);
97  }
98 
99  if (total_pd_orders == 0) {
100  (*result_count) = 0;
101  (*result_tuples) = NULL;
102 
103  /* freeing memory before return */
104  if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
105 
106  pgr_SPI_finish();
107  return;
108  }
109 
110  Vehicle_t *vehicles_arr = NULL;
111  size_t total_vehicles = 0;
112  if (use_timestamps) {
113  get_vehicles(vehicles_sql, &vehicles_arr, &total_vehicles, true);
114  } else {
115  get_vehicles_raw(vehicles_sql, &vehicles_arr, &total_vehicles, true);
116  }
117 
118  if (total_vehicles == 0) {
119  (*result_count) = 0;
120  (*result_tuples) = NULL;
121 
122  /* freeing memory before return */
123  if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
124  if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
125 
126  ereport(WARNING,
127  (errcode(ERRCODE_INTERNAL_ERROR),
128  errmsg("No vehicles found")));
129 
130  pgr_SPI_finish();
131  return;
132  }
133 
134  Time_multipliers_t *multipliers_arr = NULL;
135  size_t total_multipliers_arr = 0;
136  if (use_timestamps) {
137  get_timeMultipliers(multipliers_sql, &multipliers_arr, &total_multipliers_arr);
138  } else {
139  get_timeMultipliers_raw(multipliers_sql, &multipliers_arr, &total_multipliers_arr);
140  }
141 
142  if (total_multipliers_arr == 0) {
143  ereport(WARNING,
144  (errcode(ERRCODE_INTERNAL_ERROR),
145  errmsg("No matrix found")));
146  (*result_count) = 0;
147  (*result_tuples) = NULL;
148 
149  /* freeing memory before return */
150  if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
151  if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
152  if (multipliers_arr) {pfree(multipliers_arr); multipliers_arr = NULL;}
153 
154  pgr_SPI_finish();
155  return;
156  }
157 
158  Matrix_cell_t *matrix_cells_arr = NULL;
159  size_t total_cells = 0;
160  if (use_timestamps) {
161  get_matrixRows(matrix_sql, &matrix_cells_arr, &total_cells);
162  } else {
163  get_matrixRows_plain(matrix_sql, &matrix_cells_arr, &total_cells);
164  }
165 
166  if (total_cells == 0) {
167  (*result_count) = 0;
168  (*result_tuples) = NULL;
169 
170  /* freeing memory before return */
171  if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
172  if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
173  if (multipliers_arr) {pfree(multipliers_arr); multipliers_arr = NULL;}
174  if (matrix_cells_arr) {pfree(matrix_cells_arr); matrix_cells_arr = NULL;}
175 
176  ereport(WARNING,
177  (errcode(ERRCODE_INTERNAL_ERROR),
178  errmsg("No matrix found")));
179  pgr_SPI_finish();
180  return;
181  }
182 
183  PGR_DBG("Total %ld orders in query:", total_pd_orders);
184  PGR_DBG("Total %ld vehicles in query:", total_vehicles);
185  PGR_DBG("Total %ld matrix cells in query:", total_cells);
186  PGR_DBG("Total %ld time dependant multipliers:", total_multipliers_arr);
187 
188  clock_t start_t = clock();
189  char *log_msg = NULL;
190  char *notice_msg = NULL;
191  char *err_msg = NULL;
192 
193  do_optimize(
194  pd_orders_arr, total_pd_orders,
195  vehicles_arr, total_vehicles,
196  matrix_cells_arr, total_cells,
197  multipliers_arr, total_multipliers_arr,
198 
199  factor,
200  max_cycles,
201  execution_date,
202 
203  check_triangle_inequality,
204  subdivision_kind != 0,
205  subdivision_kind == 1,
206 
207  result_tuples,
208  result_count,
209 
210  &log_msg,
211  &notice_msg,
212  &err_msg);
213 
214  time_msg("pgr_pickDeliver", start_t, clock());
215 
216  if (err_msg && (*result_tuples)) {
217  pfree(*result_tuples);
218  (*result_count) = 0;
219  (*result_tuples) = NULL;
220  }
221  pgr_global_report(log_msg, notice_msg, err_msg);
222 
223  /* freeing memory before return */
224  if (log_msg) {pfree(log_msg); log_msg = NULL;}
225  if (notice_msg) {pfree(notice_msg); notice_msg = NULL;}
226  if (err_msg) {pfree(err_msg); err_msg = NULL;}
227  if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
228  if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
229  if (multipliers_arr) {pfree(multipliers_arr); multipliers_arr = NULL;}
230  if (matrix_cells_arr) {pfree(matrix_cells_arr); matrix_cells_arr = NULL;}
231 
232  pgr_SPI_finish();
233 }

References do_optimize(), get_matrixRows(), get_matrixRows_plain(), get_shipments(), get_shipments_raw(), get_timeMultipliers(), get_timeMultipliers_raw(), get_vehicles(), get_vehicles_raw(), PGR_DBG, pgr_global_report(), pgr_SPI_connect(), pgr_SPI_finish(), and time_msg().

Referenced by _vrp_optimize().

get_matrixRows
void get_matrixRows(char *sql, Matrix_cell_t **rows, size_t *total_rows)
Get the travel time matrix.
Definition: matrixRows_input.c:176
PickDeliveryOrders_t
order's attributes
Definition: pickDeliveryOrders_t.h:56
do_optimize
void do_optimize(PickDeliveryOrders_t *shipments_arr, size_t total_shipments, Vehicle_t *vehicles_arr, size_t total_vehicles, Matrix_cell_t *matrix_cells_arr, size_t total_cells, Time_multipliers_t *multipliers_arr, size_t total_multipliers, double factor, int max_cycles, int64_t execution_date, bool check_triangle_inequality, bool subdivide, bool subdivide_by_vehicle, Short_vehicle_rt **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
Definition: optimize_driver.cpp:350
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
Time_multipliers_t
Time Dependant Multipliers.
Definition: time_multipliers_t.h:46
pgr_SPI_finish
void pgr_SPI_finish(void)
Definition: postgres_connection.c:71
Vehicle_t
vehicles's attributes
Definition: vehicle_t.h:50
get_timeMultipliers
void get_timeMultipliers(char *sql, Time_multipliers_t **rows, size_t *total_rows)
Get the time multipliers using interval.
Definition: time_multipliers_input.c:149
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
get_shipments
void get_shipments(char *sql, PickDeliveryOrders_t **rows, size_t *total_rows)
Reads the pick-Deliver shipments for timestams and intervals.
Definition: orders_input.c:331
PGR_DBG
#define PGR_DBG(...)
Definition: debug_macro.h:34
process
static void process(char *pd_orders_sql, char *vehicles_sql, char *matrix_sql, char *multipliers_sql, double factor, int max_cycles, int64_t execution_date, bool check_triangle_inequality, int subdivision_kind, bool use_timestamps, Short_vehicle_rt **result_tuples, size_t *result_count)
Definition: optimize.c:49
Short_vehicle_rt
short_vehicle
Definition: short_vehicle_rt.h:40
if
if(DOXYGEN_FOUND) configure_file($
Definition: doxygen/CMakeLists.txt:13
Matrix_cell_t
traveling costs
Definition: matrix_cell_t.h:41
get_vehicles
void get_vehicles(char *sql, Vehicle_t **rows, size_t *total_rows, bool with_stops)
Reads the vehicles information.
Definition: vehicles_input.c:469
time_msg
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
get_timeMultipliers_raw
void get_timeMultipliers_raw(char *sql, Time_multipliers_t **rows, size_t *total_rows)
Get the time multipliers using bigint.
Definition: time_multipliers_input.c:175
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