123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- #include "rpn_mutate.h"
-
- const rnd_t rnd_t_max = -1;
-
- rpn_mutation_params_t rpn_mutation_params_default = {
- .min_len = 3,
- .w_add = 1.25,
- .w_del = 1.0,
- .w_mut = 2.0,
- .w_mut_soft = 4.0,
- .w_add_elt = {1,1,1},
- .w_mut_elt={1,1,1},
- };
-
- int rpn_mutation_init_params(rpn_mutation_params_t *params)
- {
- float mut_weights[4] = {params->w_add, params->w_del,
- params->w_mut, params->w_mut_soft};
- if(rpnifs_fast_rnd_weights(4, mut_weights, params->_weights)<0)
- {
- return -1;
- }
- /*
- #ifdef DEBUG
- dprintf(2, "summed weights : %d %d %d %d\n",
- params->_weights[0],
- params->_weights[1],
- params->_weights[2],
- params->_weights[3]);
- #endif
- */
- /**@todo test this */
- if(rpnifs_fast_rnd_weights(3, params->w_add_elt,
- &(params->_weights[4])) < 0)
- {
- return -1;
- }
-
- if(rpnifs_fast_rnd_weights(3, params->w_mut_elt,
- &(params->_weights[7])) < 0)
- {
- return -1;
- }
-
- return 0;
- }
-
- int rpn_mutation(rpn_tokenized_t *toks, rpn_mutation_params_t *params)
- {
- //_print_params(2, params);
- assert(toks->argc < rnd_t_max);
-
- if(toks->tokens_sz <= params->min_len)
- {
- return rpn_mutation_add(toks, params);
- }
- size_t choice;
- if(_rpn_random_choice(4, params->_weights, &choice) < 0)
- {
- return -1;
- }
- switch(choice)
- {
- case 0:
- return rpn_mutation_add(toks, params);
- case 1:
- return rpn_mutation_del(toks, params);
- case 2:
- return rpn_mutation_mut(toks, params);
- case 3:
- return rpn_mutation_mut_soft(toks, params);
- default:
- dprintf(2, "Random error that should never occurs");
- return -1;
- }
-
- }
- int rpn_mutation_add(rpn_tokenized_t *toks, rpn_mutation_params_t *params)
- {
- rpn_token_t *new_toks, new_token;
- size_t position;
-
- if(toks->tokens_sz == 0)
- {
- position = 0;
- }
- else if(rpn_rand_limit(toks->tokens_sz, &position) < 0)
- {
- return -1;
- }
-
- if(rpn_random_token_type(&(new_token.type), ¶ms->_weights[4]) < 0)
- {
- return -1;
- }
- if(rpn_mutation_random_token(&new_token, toks, params) < 0)
- {
- return -1;
- }
-
- toks->tokens_sz++;
- new_toks = realloc(toks->tokens, sizeof(rpn_token_t) * toks->tokens_sz);
- if(!new_toks)
- {
- toks->tokens_sz--;
- return -1;
- }
- toks->tokens = new_toks;
-
- if(position < toks->tokens_sz - 1)
- {
- memmove(&(toks->tokens[position+1]), &(toks->tokens[position]),
- sizeof(rpn_token_t) * ((toks->tokens_sz-1) - position));
- }
- memcpy(&toks->tokens[position], &new_token, sizeof(rpn_token_t));
-
- return 0;
- }
- int rpn_mutation_del(rpn_tokenized_t *toks, rpn_mutation_params_t *params)
- {
- rpn_token_t *new_toks;
- size_t position;
-
- if(rpn_rand_limit(toks->tokens_sz-1, &position) < 0)
- {
- return -1;
- }
-
- if(position != toks->tokens_sz - 1)
- {
- memmove(&(toks->tokens[position]), &(toks->tokens[position+1]),
- sizeof(rpn_token_t) * ((toks->tokens_sz - 1) - position));
- }
- toks->tokens_sz--;
- new_toks = realloc(toks->tokens, sizeof(rpn_token_t) * toks->tokens_sz);
- if(!new_toks)
- {
- toks->tokens_sz = 0;
- toks->tokens = NULL;
- return -1;
- }
- toks->tokens = new_toks;
- return 0;
- }
- int rpn_mutation_mut(rpn_tokenized_t *toks, rpn_mutation_params_t *params)
- {
- rpn_token_t *tok;
- size_t position;
-
- if(rpn_rand_limit(toks->tokens_sz-1, &position) < 0)
- {
- return -1;
- }
-
- tok = &toks->tokens[position];
-
- if(rpn_random_token_type(&(tok->type), &(params->_weights[7])) < 0)
- {
- return -1;
- }
- if(rpn_mutation_random_token(tok, toks, params) < 0)
- {
- return -1;
- }
-
- return 0;
- }
- int rpn_mutation_mut_soft(rpn_tokenized_t *toks, rpn_mutation_params_t *params)
- {
- rpn_token_t *tok;
- size_t position;
-
- if(rpn_rand_limit(toks->tokens_sz-1, &position) < 0)
- {
- return -1;
- }
-
- tok = &(toks->tokens[position]);
-
- if(rpn_mutation_random_token(tok, toks, params) < 0)
- {
- return -1;
- }
-
- return 0;
- }
-
-
- int rpn_mutation_random_token(rpn_token_t *tok,
- rpn_tokenized_t *toks, rpn_mutation_params_t *params)
- {
- rnd_t rand;
-
- if(rpn_getrandom(&rand) < 0)
- {
- return -1;
- }
-
- unsigned char op_n;
- unsigned char *val;
- size_t left;
- switch(tok->type)
- {
- case RPN_op:
- op_n = rand / (rnd_t_max/RPN_OP_SZ);
- op_n %= RPN_OP_SZ;
- tok->op_n = op_n;
- tok->op = &(rpn_ops[op_n]);
- break;
-
- case RPN_arg:
- tok->arg_n = rand / (rnd_t_max/toks->argc);
- tok->arg_n %= toks->argc;
- break;
- case RPN_val:
- val =(unsigned char*)&(tok->value);
- left = sizeof(tok->value);
- do
- {
- ssize_t ret = getrandom(val, left, GRND_NONBLOCK);
- if(ret == -1)
- {
- if(errno == EAGAIN || errno == EINTR)
- {
- continue;
- }
- return -1;
- }
- left -= ret;
- val += ret;
- }while(left);
- break;
- default:
- dprintf(2, "Another random error that shouldn't occur\n");
- return -1;
- }
- return 0;
- }
-
-
- int rpn_random_token_type(rpn_token_type_t *type, rnd_t *weights)
- {
- const rpn_token_type_t types[3] = { RPN_op, RPN_arg, RPN_val };
- size_t choice;
-
- if(_rpn_random_choice(3, weights, &choice) < 0)
- {
- return -1;
- }
- *type = types[choice];
- return 0;
- }
-
- int rpn_getrandom(rnd_t *rand)
- {
- rnd_t seed;
- char *seed_ptr = (char*)&seed;
- size_t buflen = sizeof(seed);
-
- do
- {
- ssize_t ret = getrandom(seed_ptr, buflen, GRND_NONBLOCK);
- if(ret == -1)
- {
- if(errno == EAGAIN || errno == EINTR)
- {
- continue;
- }
- return -1;
- }
- buflen -= ret;
- seed_ptr += ret;
- }while(buflen);
- *rand = seed;
- return 0;
- }
-
- int rpnifs_fast_rnd_weights(size_t sz, const float *weights,
- rnd_t *fast_weights)
- {
- long double total = 0;
- for(size_t i=0; i<sz; i++)
- {
- if(weights[i] < 0)
- {
- errno = EDOM;
- return -1;
- }
- total += weights[i];
- }
- for(size_t i=0; i<sz; i++)
- {
- rnd_t w;
- if(total == 0)
- {
- w = (rnd_t)((rnd_t_max / sz)*(i+1));
- }
- else
- {
- w = ((((long double)weights[i]) * rnd_t_max)/total);
- if(i>0)
- {
- w += fast_weights[i-1];
- }
- }
- fast_weights[i] = w;
- }
- return 0;
- }
-
- int rpnifs_rnd_float(float range[2], float *res)
- {
- #if DEBUG
- if(range[0] >= range[1])
- {
- errno = EINVAL;
- return -1;
- }
- #endif
- const rnd_t mid = rnd_t_max / 2;
- rnd_t rand;
- short neg;
-
- if(rpn_getrandom(&rand) < 0) { return -1; }
- if(rand >= mid)
- {
- neg = 1;
- rand -= mid;
- }
- else
- {
- neg = 0;
- }
- *res = ((rand*(range[1]-range[0]))/mid) + range[0];
- *res *= neg?-1:1;
- return 0;
- }
-
- int _rpn_random_choice(size_t sz, rnd_t *weights, size_t *res)
- {
- if(weights)
- {
- rnd_t rand;
- if(rpn_getrandom(&rand) < 0) { return -1; }
- __rpn_random_choice(sz, weights, rand, res);
- return 0;
- }
- // unweighted choice
- rnd_t rand;
- unsigned long long div = rnd_t_max;
- div++;
- div /= sz;
- if(rpn_getrandom(&rand) < 0) { return -1; }
- *res = (rnd_t)(((unsigned long long)rand)/div);
- return 0;
- }
-
- void __rpn_random_choice(size_t sz, rnd_t *weights, rnd_t rand, size_t *res)
- {
- for(*res=0; *res<sz; (*res)++)
- {
- if(weights[*res] >= rand)
- {
- return;
- }
- }
- *res = sz-1;
- }
-
- int rpn_rand_limit(size_t max, size_t *res)
- {
- unsigned long int step = rnd_t_max / max;
- rnd_t rnd;
-
- if(rpn_getrandom(&rnd) < 0)
- {
- return -1;
- }
- for(*res=0; *res<max; (*res)++)
- {
- if(*res * step >= rnd)
- {
- return 0;
- }
- }
- //*res = max - 1;
- return 0;
- }
-
- void _print_params(int fd, rpn_mutation_params_t *params)
- {
- dprintf(fd, "Minlen = %ld w[add=%.2f del=%.2f mut=%.2f msf=%.2f]\n",
- params->min_len, params->w_add, params->w_del,
- params->w_mut, params->w_mut_soft);
- dprintf(fd, "w_add_elt [op=%.2f const=%.2f var=%.2f]\n",
- params->w_add_elt[0], params->w_add_elt[1],
- params->w_add_elt[2]);
- dprintf(fd, "w_mut_elt [op=%.2f const=%.2f var=%.2f]\n",
- params->w_mut_elt[0], params->w_mut_elt[1],
- params->w_mut_elt[2]);
- }
|