geqo_params.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:8k
- /*------------------------------------------------------------------------
- *
- * geqo_params.c
- * routines for determining necessary genetic optimization parameters
- *
- * Copyright (c) 1994, Regents of the University of California
- *
- * $Id: geqo_params.c,v 1.17.2.1 1999/08/02 05:57:06 scrappy Exp $
- *
- *-------------------------------------------------------------------------
- */
- /* contributed by:
- =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
- =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- */
- #include <time.h>
- #include <math.h>
- #include <ctype.h>
- #include "postgres.h"
- #include "miscadmin.h"
- #include "nodes/pg_list.h"
- #include "nodes/primnodes.h"
- #include "nodes/relation.h"
- #include "optimizer/clauses.h"
- #include "optimizer/cost.h"
- #include "optimizer/geqo.h"
- #include "optimizer/geqo_gene.h"
- #include "optimizer/internal.h"
- #include "optimizer/pathnode.h"
- #include "optimizer/paths.h"
- #include "storage/fd.h"
- /*
- * Parameter values read from the config file (or defaulted) are stored here
- * by geqo_params().
- */
- int PoolSize;
- int Generations;
- long RandomSeed;
- double SelectionBias;
- #define POOL_TAG "Pool_Size"
- #define TRIAL_TAG "Generations"
- #define RAND_TAG "Random_Seed"
- #define BIAS_TAG "Selection_Bias"
- #define EFFORT_TAG "Effort"/* optimization effort and */
- #define LOW "low" /* corresponding tags */
- #define MEDIUM "medium"
- #define HIGH "high"
- #define MAX_TOKEN 80 /* Maximum size of one token in the *
- * configuration file */
- static int gimme_pool_size(int string_length);
- static int gimme_number_generations(int pool_size, int effort);
- static int next_token(FILE *, char *, int);
- static double geqo_log(double x, double b);
- /*
- * geqo_param
- * get ga parameters out of "$PGDATA/pg_geqo" file.
- */
- void
- geqo_params(int string_length)
- {
- int i;
- char buf[MAX_TOKEN];
- FILE *file;
- char *conf_file;
- /* these flag variables signal that a value has been set from the file */
- int pool_size = 0;
- int number_trials = 0;
- int random_seed = 0;
- int selection_bias = 0;
- int effort = 0;
- /* put together the full pathname to the config file */
- conf_file = (char *) palloc((strlen(DataDir) + strlen(GEQO_FILE) + 2) * sizeof(char));
- sprintf(conf_file, "%s/%s", DataDir, GEQO_FILE);
- /* open the config file */
- #ifndef __CYGWIN32__
- file = AllocateFile(conf_file, "r");
- #else
- file = AllocateFile(conf_file, "rb");
- #endif
- if (file)
- {
- /*
- * empty and comment line stuff
- */
- while ((i = next_token(file, buf, sizeof(buf))) != EOF)
- {
- /* If only token on the line, ignore */
- if (i == 'n')
- continue;
- /* Comment -- read until end of line then next line */
- if (buf[0] == '#')
- {
- while (next_token(file, buf, sizeof(buf)) == 0);
- continue;
- }
- /*
- * get ga parameters by parsing
- */
- /*------------------------------------------------- pool size */
- if (strcmp(buf, POOL_TAG) == 0)
- {
- i = next_token(file, buf, sizeof(buf)); /* get next token */
- if (i != EOF) /* only ignore if we got no text at all */
- {
- if (sscanf(buf, "%d", &PoolSize) == 1)
- pool_size = 1;
- }
- }
- /*------------------------------------------------- number of trials */
- else if (strcmp(buf, TRIAL_TAG) == 0)
- {
- i = next_token(file, buf, sizeof(buf));
- if (i != EOF)
- {
- if (sscanf(buf, "%d", &Generations) == 1)
- number_trials = 1;
- }
- }
- /*------------------------------------------------- optimization effort */
- else if (strcmp(buf, EFFORT_TAG) == 0)
- {
- i = next_token(file, buf, sizeof(buf));
- if (i != EOF)
- {
- if (strcmp(buf, LOW) == 0)
- effort = LOW_EFFORT;
- else if (strcmp(buf, MEDIUM) == 0)
- effort = MEDIUM_EFFORT;
- else if (strcmp(buf, HIGH) == 0)
- effort = HIGH_EFFORT;
- /* undocumented extension: specify effort numerically */
- else if (isdigit(buf[0]))
- effort = atoi(buf);
- }
- }
- /*------------------------------------------- random seed */
- else if (strcmp(buf, RAND_TAG) == 0)
- {
- i = next_token(file, buf, sizeof(buf));
- if (i != EOF)
- {
- if (sscanf(buf, "%ld", &RandomSeed) == 1)
- random_seed = 1;
- }
- }
- /*------------------------------------------- selection bias */
- else if (strcmp(buf, BIAS_TAG) == 0)
- {
- i = next_token(file, buf, sizeof(buf));
- if (i != EOF)
- {
- if (sscanf(buf, "%lf", &SelectionBias) == 1)
- selection_bias = 1;
- }
- }
- /* unrecognized tags */
- else
- {
- if (i != EOF)
- {
- }
- elog(DEBUG, "geqo_params: unknown parameter type "%s"nin file '%s'", buf, conf_file);
- /* if not at end-of-line, keep reading til we are */
- while (i == 0)
- i = next_token(file, buf, sizeof(buf));
- }
- }
- FreeFile(file);
- pfree(conf_file);
- }
- else
- elog(DEBUG, "geqo_params: ga parameter filen'%s'ndoes not exist or permissions are not setup correctly", conf_file);
- /*
- * parameter checkings follow
- */
- /**************** PoolSize: essential ****************/
- if (!(pool_size))
- {
- PoolSize = gimme_pool_size(string_length);
- elog(DEBUG, "geqo_params: no pool size specified;nusing computed value of %d", PoolSize);
- }
- /**************** Effort: essential ****************/
- if (!(effort))
- {
- effort = MEDIUM_EFFORT;
- elog(DEBUG, "geqo_params: no optimization effort specified;nusing value of %d", effort);
- }
- /**************** Generations: essential ****************/
- if (!(number_trials))
- {
- Generations = gimme_number_generations(PoolSize, effort);
- elog(DEBUG, "geqo_params: no number of trials specified;nusing computed value of %d", Generations);
- }
- /* RandomSeed: */
- if (!(random_seed))
- {
- RandomSeed = (long) time(NULL);
- elog(DEBUG, "geqo_params: no random seed specified;nusing computed value of %ld", RandomSeed);
- }
- /* SelectionBias: */
- if (!(selection_bias))
- {
- SelectionBias = SELECTION_BIAS;
- elog(DEBUG, "geqo_params: no selection bias specified;nusing default value of %f", SelectionBias);
- }
- }
- /*
- * Grab one token out of fp. Defined as the next string of non-whitespace
- * in the file. After we get the token, continue reading until EOF, end of
- * line or the next token. If it's the last token on the line, return 'n'
- * for the value. If we get EOF before reading a token, return EOF. In all
- * other cases return 0.
- */
- static int
- next_token(FILE *fp, char *buf, int bufsz)
- {
- int c;
- char *eb = buf + (bufsz - 1);
- /* Discard inital whitespace */
- while (isspace(c = getc(fp)));
- /* EOF seen before any token so return EOF */
- if (c == EOF)
- return -1;
- /* Form a token in buf */
- do
- {
- if (buf < eb)
- *buf++ = c;
- c = getc(fp);
- } while (!isspace(c) && c != EOF);
- *buf = ' ';
- /* Discard trailing tabs and spaces */
- while (c == ' ' || c == 't')
- c = getc(fp);
- /* Put back the char that was non-whitespace (putting back EOF is ok) */
- ungetc(c, fp);
- /* If we ended with a newline, return that, otherwise return 0 */
- return c == 'n' ? 'n' : 0;
- }
- /* gimme_pool_size
- * compute good estimation for pool size
- * according to number of involved rels in a query
- */
- static int
- gimme_pool_size(int string_length)
- {
- double exponent;
- double size;
- exponent = (double) string_length + 1.0;
- size = pow(2.0, exponent);
- if (size < MIN_POOL)
- return MIN_POOL;
- else if (size > MAX_POOL)
- return MAX_POOL;
- else
- return (int) ceil(size);
- }
- /* gimme_number_generations
- * compute good estimation for number of generations size
- * for convergence
- */
- static int
- gimme_number_generations(int pool_size, int effort)
- {
- int number_gens;
- number_gens = (int) ceil(geqo_log((double) pool_size, 2.0));
- return effort * number_gens;
- }
- static double
- geqo_log(double x, double b)
- {
- return (log(x) / log(b));
- }