29 #define GP_NUM_FUNC (4)
35 #define STRING_ADD ("+\0")
36 #define STRING_SUB ("-\0")
37 #define STRING_MUL ("*\0")
38 #define STRING_DIV ("/\0")
41 #define RET_MIN (-1000)
42 #define RET_MAX (1000)
78 const int max,
const int depth)
83 if (depth == 0 || (pos != 0 &&
rand_uniform(0, 1) < 0.5)) {
89 const int child =
tree_grow(args, tree, pos + 1, max, depth - 1);
93 return tree_grow(args, tree, child, max, depth - 1);
106 while (gp->
len < 1) {
109 gp->
tree = realloc(gp->
tree,
sizeof(
int) * gp->
len);
110 gp->
mu = malloc(
sizeof(
double) *
N_MU);
135 const int node = gp->
tree[gp->
pos];
153 return (b != 0) ? (a / b) : a;
155 printf(
"tree_eval() invalid function: %d\n", node);
178 printf(
"tree_function_string() invalid function: %d\n", node);
218 const int node = gp->
tree[pos];
223 snprintf(buff, 256,
"feature_%d", val);
224 cJSON *input = cJSON_CreateString(buff);
225 cJSON_AddItemToArray(json, input);
228 cJSON *constant = cJSON_CreateNumber(val);
229 cJSON_AddItemToArray(json, constant);
234 cJSON *leftp = cJSON_CreateString(
"(");
235 cJSON_AddItemToArray(json, leftp);
239 cJSON_AddItemToArray(json, func);
241 cJSON *rightp = cJSON_CreateString(
")");
242 cJSON_AddItemToArray(json, rightp);
255 cJSON *json = cJSON_CreateObject();
256 cJSON *tree = cJSON_CreateArray();
257 cJSON_AddItemToObject(json,
"array", tree);
259 cJSON *mutation = cJSON_CreateDoubleArray(gp->
mu,
N_MU);
260 cJSON_AddItemToObject(json,
"mutation", mutation);
261 char *
string = cJSON_Print(json);
279 printf(
"Import error: GP trees not yet implemented\n");
292 printf(
"%s\n", json_str);
305 dest->
tree = malloc(
sizeof(
int) * src->
len);
306 memcpy(dest->
tree, src->
tree,
sizeof(
int) * src->
len);
308 dest->
mu = malloc(
sizeof(
double) *
N_MU);
309 memcpy(dest->
mu, src->
mu,
sizeof(
double) *
N_MU);
320 const int len1 = p1->
len;
321 const int len2 = p2->
len;
326 const int nlen1 = start1 + (end2 - start2) + (len1 - end1);
327 int *new1 = malloc(
sizeof(
int) * nlen1);
328 memcpy(&new1[0], &p1->
tree[0],
sizeof(
int) * start1);
329 memcpy(&new1[start1], &p2->
tree[start2],
sizeof(
int) * (end2 - start2));
330 memcpy(&new1[start1 + (end2 - start2)], &p1->
tree[end1],
331 sizeof(
int) * (len1 - end1));
332 const int nlen2 = start2 + (end1 - start1) + (len2 - end2);
333 int *new2 = malloc(
sizeof(
int) * nlen2);
334 memcpy(&new2[0], &p2->
tree[0],
sizeof(
int) * start2);
335 memcpy(&new2[start2], &p1->
tree[start1],
sizeof(
int) * (end1 - start1));
336 memcpy(&new2[start2 + (end1 - start1)], &p2->
tree[end2],
337 sizeof(
int) * (len2 - end2));
357 bool changed =
false;
360 for (
int i = 0; i < gp->
len; ++i) {
362 const int orig = gp->
tree[i];
368 if (gp->
tree[i] != orig) {
386 s += fwrite(&gp->
pos,
sizeof(
int), 1, fp);
387 s += fwrite(&gp->
len,
sizeof(
int), 1, fp);
388 s += fwrite(gp->
tree,
sizeof(
int), gp->
len, fp);
389 s += fwrite(gp->
mu,
sizeof(
double),
N_MU, fp);
403 s += fread(&gp->
pos,
sizeof(
int), 1, fp);
404 s += fread(&gp->
len,
sizeof(
int), 1, fp);
406 printf(
"tree_load(): read error\n");
410 gp->
tree = malloc(
sizeof(
int) * gp->
len);
411 gp->
mu = malloc(
sizeof(
double) *
N_MU);
412 s += fread(gp->
tree,
sizeof(
int), gp->
len, fp);
413 s += fread(gp->
mu,
sizeof(
double),
N_MU, fp);
451 cJSON *json = cJSON_CreateObject();
452 cJSON_AddNumberToObject(json,
"min_constant", args->
min);
453 cJSON_AddNumberToObject(json,
"max_constant", args->
max);
454 cJSON_AddNumberToObject(json,
"n_constants", args->
n_constants);
455 cJSON_AddNumberToObject(json,
"init_depth", args->
init_depth);
456 cJSON_AddNumberToObject(json,
"max_len", args->
max_len);
457 char *
string = cJSON_Print(json);
471 for (cJSON *iter = json; iter != NULL; iter = iter->next) {
472 if (strncmp(iter->string,
"min_constant\0", 13) == 0 &&
473 cJSON_IsNumber(iter)) {
475 }
else if (strncmp(iter->string,
"max_constant\0", 13) == 0 &&
476 cJSON_IsNumber(iter)) {
478 }
else if (strncmp(iter->string,
"n_constants\0", 12) == 0 &&
479 cJSON_IsNumber(iter)) {
481 }
else if (strncmp(iter->string,
"init_depth\0", 11) == 0 &&
482 cJSON_IsNumber(iter)) {
484 }
else if (strncmp(iter->string,
"max_len\0", 8) == 0 &&
485 cJSON_IsNumber(iter)) {
504 s += fwrite(&args->
max,
sizeof(
double), 1, fp);
505 s += fwrite(&args->
min,
sizeof(
double), 1, fp);
506 s += fwrite(&args->
n_inputs,
sizeof(
int), 1, fp);
507 s += fwrite(&args->
n_constants,
sizeof(
int), 1, fp);
508 s += fwrite(&args->
init_depth,
sizeof(
int), 1, fp);
509 s += fwrite(&args->
max_len,
sizeof(
int), 1, fp);
524 s += fread(&args->
max,
sizeof(
double), 1, fp);
525 s += fread(&args->
min,
sizeof(
double), 1, fp);
526 s += fread(&args->
n_inputs,
sizeof(
int), 1, fp);
527 s += fread(&args->
n_constants,
sizeof(
int), 1, fp);
528 s += fread(&args->
init_depth,
sizeof(
int), 1, fp);
529 s += fread(&args->
max_len,
sizeof(
int), 1, fp);
568 printf(
"Warning: tried to set GP N_INPUTS too small\n");
579 printf(
"Warning: tried to set GP N_CONSTANTS too small\n");
590 printf(
"Warning: tried to set GP INIT_DEPTH too small\n");
601 printf(
"Warning: tried to set GP MAX_LEN too small\n");
void tree_json_import(struct GPTree *gp, const struct ArgsGPTree *args, const cJSON *json)
Creates a GP tree from a cJSON object.
#define STRING_SUB
Subtraction.
static const int MU_TYPE[(1)]
Self-adaptation method for mutating GP trees.
void tree_args_free(struct ArgsGPTree *args)
Frees memory used by GP tree parameters.
static const char * tree_function_string(const int node)
Returns a string representation of a node function.
size_t tree_load(struct GPTree *gp, FILE *fp)
Reads a GP tree from a file.
void tree_param_set_max_len(struct ArgsGPTree *args, const int a)
static int tree_grow(const struct ArgsGPTree *args, int *tree, const int pos, const int max, const int depth)
Grows a random GP tree of specified max length and depth.
#define RET_MAX
Maximum tree return value.
#define SUB
Subtraction function.
#define STRING_ADD
Addition.
void tree_crossover(struct GPTree *p1, struct GPTree *p2)
Performs sub-tree crossover.
size_t tree_save(const struct GPTree *gp, FILE *fp)
Writes the GP tree to a file.
#define RET_MIN
Minimum tree return value.
void tree_print(const struct GPTree *gp, const struct ArgsGPTree *args)
Prints a GP tree.
#define N_MU
Number of tree-GP mutation rates.
void tree_param_set_max(struct ArgsGPTree *args, const double a)
void tree_param_set_n_inputs(struct ArgsGPTree *args, const int a)
static int tree_string(const struct GPTree *gp, const struct ArgsGPTree *args, int pos, cJSON *json)
Returns a json formatted string representation of a GP tree.
char * tree_args_json_import(struct ArgsGPTree *args, cJSON *json)
Sets the GP tree parameters from a cJSON object.
#define DIV
Division function.
double tree_eval(struct GPTree *gp, const struct ArgsGPTree *args, const double *x)
Evaluates a GP tree.
#define ADD
Addition function.
void tree_param_set_n_constants(struct ArgsGPTree *args, const int a)
static int tree_traverse(int *tree, int pos)
Traverses a GP tree.
#define STRING_DIV
Division.
void tree_args_init_constants(struct ArgsGPTree *args)
Builds global constants used by GP trees.
#define MUL
Multiplication function.
void tree_param_set_init_depth(struct ArgsGPTree *args, const int a)
#define STRING_MUL
Multiplication.
bool tree_mutate(struct GPTree *gp, const struct ArgsGPTree *args)
Performs point mutation on a GP tree.
void tree_args_init(struct ArgsGPTree *args)
Sets tree GP parameters to default values.
size_t tree_args_load(struct ArgsGPTree *args, FILE *fp)
Loads Tree GP parameters.
void tree_param_set_min(struct ArgsGPTree *args, const double a)
char * tree_args_json_export(const struct ArgsGPTree *args)
Returns a json formatted string of the GP tree parameters.
char * tree_json_export(const struct GPTree *gp, const struct ArgsGPTree *args)
Returns a json formatted string representation of a GP tree.
static int tree_function_int(const char *node)
Returns an integer representation of a node function.
#define GP_NUM_FUNC
Number of selectable GP functions.
void tree_copy(struct GPTree *dest, const struct GPTree *src)
Copies a GP tree.
void tree_free(const struct GPTree *gp)
Frees a GP tree.
size_t tree_args_save(const struct ArgsGPTree *args, FILE *fp)
Saves Tree GP parameters.
void tree_rand(struct GPTree *gp, const struct ArgsGPTree *args)
Creates a random GP tree.
An implementation of GP trees based upon TinyGP.
void sam_init(double *mu, const int N, const int *type)
Initialises self-adaptive mutation rates.
void sam_adapt(double *mu, const int N, const int *type)
Self-adapts mutation rates.
Self-adaptive mutation functions.
#define SAM_RATE_SELECT
Ten normally distributed rates.
Parameters for initialising GP trees.
double * constants
Constants available for GP trees.
int n_constants
Number of constants available.
int init_depth
Initial depth.
int max_len
Maximum initial length.
double min
Minimum value of a constant.
int n_inputs
Number of inputs.
double max
Maximum value of a constant.
int * tree
Flattened tree representation of functions and terminals.
int pos
Current position in the tree.
double * mu
Mutation rates.
int rand_uniform_int(const int min, const int max)
Returns a uniform random integer [min,max] not inclusive of max.
double rand_uniform(const double min, const double max)
Returns a uniform random float [min,max].
Utility functions for random number handling, etc.
static double clamp(const double a, const double min, const double max)
Returns a float clamped within the specified range.