PGROUTING  3.2
euclideanTSP.c File Reference
Include dependency graph for euclideanTSP.c:

Go to the source code of this file.

Functions

PGDLLEXPORT Datum _pgr_tspeuclidean (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (_pgr_tspeuclidean)
 
static void process (char *coordinates_sql, int64_t start_vid, int64_t end_vid, double time_limit, int64_t tries_per_temperature, int64_t max_changes_per_temperature, int64_t max_consecutive_non_changes, double initial_temperature, double final_temperature, double cooling_factor, bool randomize, General_path_element_t **result_tuples, size_t *result_count)
 

Function Documentation

◆ _pgr_tspeuclidean()

PGDLLEXPORT Datum _pgr_tspeuclidean ( PG_FUNCTION_ARGS  )

Definition at line 154 of file euclideanTSP.c.

154  {
155  FuncCallContext *funcctx;
156  TupleDesc tuple_desc;
157 
158  /**************************************************************************/
159  /* MODIFY AS NEEDED */
160  /* */
161  General_path_element_t *result_tuples = NULL;
162  size_t result_count = 0;
163  /* */
164  /**************************************************************************/
165 
166  if (SRF_IS_FIRSTCALL()) {
167  MemoryContext oldcontext;
168  funcctx = SRF_FIRSTCALL_INIT();
169  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
170 
171 
172  /**********************************************************************/
173  /* MODIFY AS NEEDED */
174  /*
175 
176  CREATE OR REPLACE FUNCTION pgr_euclideanTSP(
177  coordinates_sql TEXT,
178  start_id BIGINT DEFAULT 0,
179  end_id BIGINT DEFAULT 0,
180 
181  max_processing_time FLOAT DEFAULT '+infinity'::FLOAT,
182 
183  tries_per_temperature INTEGER DEFAULT 500,
184  max_changes_per_temperature INTEGER DEFAULT 60,
185  max_consecutive_non_changes INTEGER DEFAULT 200,
186 
187  initial_temperature FLOAT DEFAULT 100,
188  final_temperature FLOAT DEFAULT 0.1,
189  cooling_factor FLOAT DEFAULT 0.9,
190 
191  randomize BOOLEAN DEFAULT true,
192  */
193 
194  process(
195  text_to_cstring(PG_GETARG_TEXT_P(0)),
196  PG_GETARG_INT64(1),
197  PG_GETARG_INT64(2),
198 
199  PG_GETARG_FLOAT8(3),
200 
201  PG_GETARG_INT32(4),
202  PG_GETARG_INT32(5),
203  PG_GETARG_INT32(6),
204 
205  PG_GETARG_FLOAT8(7),
206  PG_GETARG_FLOAT8(8),
207  PG_GETARG_FLOAT8(9),
208 
209  PG_GETARG_BOOL(10),
210  &result_tuples,
211  &result_count);
212  /* */
213  /**********************************************************************/
214 
215 #if PGSQL_VERSION > 95
216  funcctx->max_calls = result_count;
217 #else
218  funcctx->max_calls = (uint32_t)result_count;
219 #endif
220 
221  funcctx->user_fctx = result_tuples;
222  if (get_call_result_type(fcinfo, NULL, &tuple_desc)
223  != TYPEFUNC_COMPOSITE) {
224  ereport(ERROR,
225  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
226  errmsg("function returning record called in context "
227  "that cannot accept type record")));
228  }
229 
230  funcctx->tuple_desc = tuple_desc;
231  MemoryContextSwitchTo(oldcontext);
232  }
233 
234  funcctx = SRF_PERCALL_SETUP();
235  tuple_desc = funcctx->tuple_desc;
236  result_tuples = (General_path_element_t*) funcctx->user_fctx;
237 
238  if (funcctx->call_cntr < funcctx->max_calls) {
239  HeapTuple tuple;
240  Datum result;
241  Datum *values;
242  bool* nulls;
243 
244  /**********************************************************************/
245  /* MODIFY AS NEEDED */
246  // OUT seq INTEGER,
247  // OUT node BIGINT,
248  // OUT cost FLOAT,
249  // OUT agg_cost FLOAT
250 
251  values = palloc(4 * sizeof(Datum));
252  nulls = palloc(4 * sizeof(bool));
253 
254 
255  size_t i;
256  for (i = 0; i < 4; ++i) {
257  nulls[i] = false;
258  }
259 
260  // postgres starts counting from 1
261  values[0] = Int32GetDatum(funcctx->call_cntr + 1);
262  values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr].node);
263  values[2] = Float8GetDatum(result_tuples[funcctx->call_cntr].cost);
264  values[3] = Float8GetDatum(result_tuples[funcctx->call_cntr].agg_cost);
265  /**********************************************************************/
266 
267  tuple = heap_form_tuple(tuple_desc, values, nulls);
268  result = HeapTupleGetDatum(tuple);
269  SRF_RETURN_NEXT(funcctx, result);
270  } else {
271  SRF_RETURN_DONE(funcctx);
272  }
273 }

References General_path_element_t::agg_cost, General_path_element_t::cost, if(), General_path_element_t::node, and process().

◆ PG_FUNCTION_INFO_V1()

PG_FUNCTION_INFO_V1 ( _pgr_tspeuclidean  )

◆ process()

static void process ( char *  coordinates_sql,
int64_t  start_vid,
int64_t  end_vid,
double  time_limit,
int64_t  tries_per_temperature,
int64_t  max_changes_per_temperature,
int64_t  max_consecutive_non_changes,
double  initial_temperature,
double  final_temperature,
double  cooling_factor,
bool  randomize,
General_path_element_t **  result_tuples,
size_t *  result_count 
)
static

Definition at line 48 of file euclideanTSP.c.

66  {
68 
69  /*
70  * errors in parameters
71  */
72  if (initial_temperature < final_temperature) {
73  elog(ERROR, "Condition not met: initial_temperature"
74  " > final_temperature");
75  }
76  if (final_temperature <= 0) {
77  elog(ERROR, "Condition not met: final_temperature > 0");
78  }
79  if (cooling_factor <=0 || cooling_factor >=1) {
80  elog(ERROR, "Condition not met: 0 < cooling_factor < 1");
81  }
82  if (tries_per_temperature < 0) {
83  elog(ERROR, "Condition not met: tries_per_temperature >= 0");
84  }
85  if (max_changes_per_temperature < 1) {
86  elog(ERROR, "Condition not met: max_changes_per_temperature > 0");
87  }
88  if (max_consecutive_non_changes < 1) {
89  elog(ERROR, "Condition not met: max_consecutive_non_changes > 0");
90  }
91  if (time_limit < 0) {
92  elog(ERROR, "Condition not met: max_processing_time >= 0");
93  }
94 
95 
96  Coordinate_t *coordinates = NULL;
97  size_t total_coordinates = 0;
98  pgr_get_coordinates(coordinates_sql, &coordinates, &total_coordinates);
99 
100  if (total_coordinates == 0) {
101  PGR_DBG("No coordinates found");
102  (*result_count) = 0;
103  (*result_tuples) = NULL;
104  pgr_SPI_finish();
105  return;
106  }
107 
108  PGR_DBG("Starting timer");
109  clock_t start_t = clock();
110  char* log_msg = NULL;
111  char* notice_msg = NULL;
112  char* err_msg = NULL;
113 
115  coordinates, total_coordinates,
116  start_vid,
117  end_vid,
118  initial_temperature,
119  final_temperature,
120  cooling_factor,
121  tries_per_temperature,
122  max_changes_per_temperature,
123  max_consecutive_non_changes,
124  randomize,
125  time_limit,
126  result_tuples,
127  result_count,
128  &log_msg,
129  &notice_msg,
130  &err_msg);
131 
132  time_msg("euclideanTSP", start_t, clock());
133 
134  if (err_msg && (*result_tuples)) {
135  pfree(*result_tuples);
136  (*result_tuples) = NULL;
137  (*result_count) = 0;
138  }
139 
140  pgr_global_report(log_msg, notice_msg, err_msg);
141 
142  if (log_msg) pfree(log_msg);
143  if (notice_msg) pfree(notice_msg);
144  if (err_msg) pfree(err_msg);
145  if (coordinates) pfree(coordinates);
146 
147  pgr_SPI_finish();
148 }

References do_pgr_euclideanTSP(), PGR_DBG, pgr_get_coordinates(), pgr_global_report(), pgr_SPI_connect(), pgr_SPI_finish(), and time_msg().

Referenced by _pgr_tspeuclidean().

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
pgr_get_coordinates
void pgr_get_coordinates(char *sql, Coordinate_t **coordinates, size_t *total_coordinates)
bigint id, float x, float y,
Definition: coordinates_input.c:57
Coordinate_t
Definition: coordinate_t.h:37
PGR_DBG
#define PGR_DBG(...)
Definition: debug_macro.h:34
process
static void process(char *coordinates_sql, int64_t start_vid, int64_t end_vid, double time_limit, int64_t tries_per_temperature, int64_t max_changes_per_temperature, int64_t max_consecutive_non_changes, double initial_temperature, double final_temperature, double cooling_factor, bool randomize, General_path_element_t **result_tuples, size_t *result_count)
Definition: euclideanTSP.c:48
General_path_element_t
Definition: general_path_element_t.h:37
if
if(DOXYGEN_FOUND) configure_file($
Definition: doxygen/CMakeLists.txt:13
do_pgr_euclideanTSP
void do_pgr_euclideanTSP(Coordinate_t *coordinates_data, size_t total_coordinates, int64_t start_vid, int64_t end_vid, double initial_temperature, double final_temperature, double cooling_factor, int64_t tries_per_temperature, int64_t max_changes_per_temperature, int64_t max_consecutive_non_changes, bool randomize, double time_limit, General_path_element_t **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
Definition: euclideanTSP_driver.cpp:45
time_msg
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
pgr_global_report
void pgr_global_report(char *log, char *notice, char *err)
notice & error
Definition: e_report.c:93