geqo_params.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:8k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*------------------------------------------------------------------------
  2. *
  3. * geqo_params.c
  4. *  routines for determining necessary genetic optimization parameters
  5. *
  6. * Copyright (c) 1994, Regents of the University of California
  7. *
  8. * $Id: geqo_params.c,v 1.17.2.1 1999/08/02 05:57:06 scrappy Exp $
  9. *
  10. *-------------------------------------------------------------------------
  11. */
  12. /* contributed by:
  13.    =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  14.    *  Martin Utesch  * Institute of Automatic Control    *
  15.    =  = University of Mining and Technology =
  16.    *  utesch@aut.tu-freiberg.de  * Freiberg, Germany    *
  17.    =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  18.  */
  19. #include <time.h>
  20. #include <math.h>
  21. #include <ctype.h>
  22. #include "postgres.h"
  23. #include "miscadmin.h"
  24. #include "nodes/pg_list.h"
  25. #include "nodes/primnodes.h"
  26. #include "nodes/relation.h"
  27. #include "optimizer/clauses.h"
  28. #include "optimizer/cost.h"
  29. #include "optimizer/geqo.h"
  30. #include "optimizer/geqo_gene.h"
  31. #include "optimizer/internal.h"
  32. #include "optimizer/pathnode.h"
  33. #include "optimizer/paths.h"
  34. #include "storage/fd.h"
  35. /*
  36.  * Parameter values read from the config file (or defaulted) are stored here
  37.  * by geqo_params().
  38.  */
  39. int PoolSize;
  40. int Generations;
  41. long RandomSeed;
  42. double SelectionBias;
  43. #define POOL_TAG "Pool_Size"
  44. #define TRIAL_TAG "Generations"
  45. #define RAND_TAG "Random_Seed"
  46. #define BIAS_TAG "Selection_Bias"
  47. #define EFFORT_TAG "Effort"/* optimization effort and */
  48. #define LOW  "low" /* corresponding tags */
  49. #define MEDIUM   "medium"
  50. #define HIGH   "high"
  51. #define MAX_TOKEN 80 /* Maximum size of one token in the  *
  52.  * configuration file  */
  53. static int gimme_pool_size(int string_length);
  54. static int gimme_number_generations(int pool_size, int effort);
  55. static int next_token(FILE *, char *, int);
  56. static double geqo_log(double x, double b);
  57. /*
  58.  * geqo_param
  59.  *  get ga parameters out of "$PGDATA/pg_geqo" file.
  60.  */
  61. void
  62. geqo_params(int string_length)
  63. {
  64. int i;
  65. char buf[MAX_TOKEN];
  66. FILE    *file;
  67. char    *conf_file;
  68. /* these flag variables signal that a value has been set from the file */
  69. int pool_size = 0;
  70. int number_trials = 0;
  71. int random_seed = 0;
  72. int selection_bias = 0;
  73. int effort = 0;
  74. /* put together the full pathname to the config file */
  75. conf_file = (char *) palloc((strlen(DataDir) + strlen(GEQO_FILE) + 2) * sizeof(char));
  76. sprintf(conf_file, "%s/%s", DataDir, GEQO_FILE);
  77. /* open the config file */
  78. #ifndef __CYGWIN32__
  79. file = AllocateFile(conf_file, "r");
  80. #else
  81. file = AllocateFile(conf_file, "rb");
  82. #endif
  83. if (file)
  84. {
  85. /*
  86.  * empty and comment line stuff
  87.  */
  88. while ((i = next_token(file, buf, sizeof(buf))) != EOF)
  89. {
  90. /* If only token on the line, ignore */
  91. if (i == 'n')
  92. continue;
  93. /* Comment -- read until end of line then next line */
  94. if (buf[0] == '#')
  95. {
  96. while (next_token(file, buf, sizeof(buf)) == 0);
  97. continue;
  98. }
  99. /*
  100.  * get ga parameters by parsing
  101.  */
  102. /*------------------------------------------------- pool size */
  103. if (strcmp(buf, POOL_TAG) == 0)
  104. {
  105. i = next_token(file, buf, sizeof(buf)); /* get next token */
  106. if (i != EOF) /* only ignore if we got no text at all */
  107. {
  108. if (sscanf(buf, "%d", &PoolSize) == 1)
  109. pool_size = 1;
  110. }
  111. }
  112. /*------------------------------------------------- number of trials */
  113. else if (strcmp(buf, TRIAL_TAG) == 0)
  114. {
  115. i = next_token(file, buf, sizeof(buf));
  116. if (i != EOF)
  117. {
  118. if (sscanf(buf, "%d", &Generations) == 1)
  119. number_trials = 1;
  120. }
  121. }
  122. /*------------------------------------------------- optimization effort */
  123. else if (strcmp(buf, EFFORT_TAG) == 0)
  124. {
  125. i = next_token(file, buf, sizeof(buf));
  126. if (i != EOF)
  127. {
  128. if (strcmp(buf, LOW) == 0)
  129. effort = LOW_EFFORT;
  130. else if (strcmp(buf, MEDIUM) == 0)
  131. effort = MEDIUM_EFFORT;
  132. else if (strcmp(buf, HIGH) == 0)
  133. effort = HIGH_EFFORT;
  134. /* undocumented extension: specify effort numerically */
  135. else if (isdigit(buf[0]))
  136. effort = atoi(buf);
  137. }
  138. }
  139. /*------------------------------------------- random seed */
  140. else if (strcmp(buf, RAND_TAG) == 0)
  141. {
  142. i = next_token(file, buf, sizeof(buf));
  143. if (i != EOF)
  144. {
  145. if (sscanf(buf, "%ld", &RandomSeed) == 1)
  146. random_seed = 1;
  147. }
  148. }
  149. /*------------------------------------------- selection bias */
  150. else if (strcmp(buf, BIAS_TAG) == 0)
  151. {
  152. i = next_token(file, buf, sizeof(buf));
  153. if (i != EOF)
  154. {
  155. if (sscanf(buf, "%lf", &SelectionBias) == 1)
  156. selection_bias = 1;
  157. }
  158. }
  159. /* unrecognized tags */
  160. else
  161. {
  162. if (i != EOF)
  163. {
  164. }
  165. elog(DEBUG, "geqo_params: unknown parameter type "%s"nin file '%s'", buf, conf_file);
  166. /* if not at end-of-line, keep reading til we are */
  167. while (i == 0)
  168. i = next_token(file, buf, sizeof(buf));
  169. }
  170. }
  171. FreeFile(file);
  172. pfree(conf_file);
  173. }
  174. else
  175. elog(DEBUG, "geqo_params: ga parameter filen'%s'ndoes not exist or permissions are not setup correctly", conf_file);
  176. /*
  177.  * parameter checkings follow
  178.  */
  179. /**************** PoolSize: essential ****************/
  180. if (!(pool_size))
  181. {
  182. PoolSize = gimme_pool_size(string_length);
  183. elog(DEBUG, "geqo_params: no pool size specified;nusing computed value of %d", PoolSize);
  184. }
  185. /**************** Effort: essential ****************/
  186. if (!(effort))
  187. {
  188. effort = MEDIUM_EFFORT;
  189. elog(DEBUG, "geqo_params: no optimization effort specified;nusing value of %d", effort);
  190. }
  191. /**************** Generations: essential ****************/
  192. if (!(number_trials))
  193. {
  194. Generations = gimme_number_generations(PoolSize, effort);
  195. elog(DEBUG, "geqo_params: no number of trials specified;nusing computed value of %d", Generations);
  196. }
  197. /* RandomSeed: */
  198. if (!(random_seed))
  199. {
  200. RandomSeed = (long) time(NULL);
  201. elog(DEBUG, "geqo_params: no random seed specified;nusing computed value of %ld", RandomSeed);
  202. }
  203. /* SelectionBias: */
  204. if (!(selection_bias))
  205. {
  206. SelectionBias = SELECTION_BIAS;
  207. elog(DEBUG, "geqo_params: no selection bias specified;nusing default value of %f", SelectionBias);
  208. }
  209. }
  210. /*
  211.  * Grab one token out of fp.  Defined as the next string of non-whitespace
  212.  * in the file.  After we get the token, continue reading until EOF, end of
  213.  * line or the next token. If it's the last token on the line, return 'n'
  214.  * for the value.  If we get EOF before reading a token, return EOF.  In all
  215.  * other cases return 0.
  216.  */
  217. static int
  218. next_token(FILE *fp, char *buf, int bufsz)
  219. {
  220. int c;
  221. char    *eb = buf + (bufsz - 1);
  222. /* Discard inital whitespace */
  223. while (isspace(c = getc(fp)));
  224. /* EOF seen before any token so return EOF */
  225. if (c == EOF)
  226. return -1;
  227. /* Form a token in buf */
  228. do
  229. {
  230. if (buf < eb)
  231. *buf++ = c;
  232. c = getc(fp);
  233. } while (!isspace(c) && c != EOF);
  234. *buf = '';
  235. /* Discard trailing tabs and spaces */
  236. while (c == ' ' || c == 't')
  237. c = getc(fp);
  238. /* Put back the char that was non-whitespace (putting back EOF is ok) */
  239. ungetc(c, fp);
  240. /* If we ended with a newline, return that, otherwise return 0 */
  241. return c == 'n' ? 'n' : 0;
  242. }
  243. /* gimme_pool_size
  244.  *  compute good estimation for pool size
  245.  *  according to number of involved rels in a query
  246.  */
  247. static int
  248. gimme_pool_size(int string_length)
  249. {
  250. double exponent;
  251. double size;
  252. exponent = (double) string_length + 1.0;
  253. size = pow(2.0, exponent);
  254. if (size < MIN_POOL)
  255. return MIN_POOL;
  256. else if (size > MAX_POOL)
  257. return MAX_POOL;
  258. else
  259. return (int) ceil(size);
  260. }
  261. /* gimme_number_generations
  262.  *  compute good estimation for number of generations size
  263.  *  for convergence
  264.  */
  265. static int
  266. gimme_number_generations(int pool_size, int effort)
  267. {
  268. int number_gens;
  269. number_gens = (int) ceil(geqo_log((double) pool_size, 2.0));
  270. return effort * number_gens;
  271. }
  272. static double
  273. geqo_log(double x, double b)
  274. {
  275. return (log(x) / log(b));
  276. }