Commit 8f44bf4a authored by Cancino Waldo's avatar Cancino Waldo

Add examples from Ogier, Pierre and Jean-Luc

parent 00c45f4b
/////////////////// BEGIN TREE COMPARE /////////////////////
// Cette fonction n'est pas au point, elle ne traite pas la division.
bool GPNodeCompare(GPNode* root1, GPNode* root2, const unsigned* opArity) {
char code1 = root1->opCode;
char code2 = root2->opCode;
int arity1 = opArity[(int)code1];
int arity2 = opArity[(int)code2];
if (code1 != code2) return false;
// Compare terminal nodes
// They can be equal if they have the same opCode and if they the same value in case of the opCode is OP_ERC
if (!arity1) {
if (code1 == OP_ERC && root1->erc_value != root2->erc_value) return false;
return true;
}
// Compare non-terminal nodes.
// They can be equal if the children of the first node are a permutation of those of second node.
int length = arity2;
int index[length];
// Initialization of the index array.
for (int i = 0; i < length; i++) {
index[i] = i;
}
for (int i = 0; i < arity1; i++) {
int j = 0;
while (!GPNodeCompare(root1->children[i], root2->children[index[j]], opArity)) {
if (++j >= length) return false; // If at the end of the index array we didn't found an equal children, we return false.
}
// The children are equal, so the current index is discarded from the research.
index[j] = index[--length];
}
return true;
}
////////////////// END TREE COMPARE ////////////////////////
\ No newline at end of file
/////////////////////// BEGIN DEPTH OF TREE ///////////////////////
// Returns the depth of a tree
int depthOfTree1(GPNode* root) {
int sonsDepth = 0;
for (int i = 0; i < (int)opArity[(int)root->opCode]; i++) {
int d = depthOfTree1(root->children[i]);
if (d > sonsDepth) sonsDepth = d;
}
return 1+sonsDepth;
}
//////////////////////// END DEPTH OF TREE ////////////////////////
/////////////////////// BEGIN NUMBER OF NODES TREE ////////////////////
int nbOfNodes(GPNode* root) {
int nbNodes = 1;
for (int i = 0; i < (int)opArity[(int)root->opCode]; i++) {
nbNodes += nbOfNodes(root->children[i]);
}
return nbNodes;
}
//////////////////////// END NUMBER OF NODES TREE /////////////////////
///////////////////// BEGIN DEPTH OF NODE IN TREE ///////////////////
int depthOfNodeInTreeR(GPNode* root, GPNode* node, const int currentDepth) {
if (root == node) return currentDepth;
for (int i = 0; i < (int)opArity[(int)root->opCode]; i++) {
int depth = depthOfNodeInTreeR(root->children[i], node, currentDepth+1);
if (depth) return depth;
}
return 0;
}
/* Returns the depth of the node "node" in the tree "root".
Reurns 0 if the node hasn't been found.
*/
int depthOfNodeInTree(GPNode* root, GPNode* node) {
return depthOfNodeInTreeR(root, node, 1);
}
////////////////////// END DEPTH OF NODE IN TREE ////////////////////
/////////////////// BEGIN TREE COMPARE /////////////////////
bool GPNodeCompare(GPNode* root1, GPNode* root2) {
char code1 = root1->opCode;
char code2 = root2->opCode;
int arity1 = opArity[(int)code1];
if (code1 != code2) return false;
// Compare terminal nodes
// They can be equal if they have the same opCode and if they the same value in case of the opCode is OP_ERC
if (!arity1) {
if (code1 == OP_ERC && root1->erc_value != root2->erc_value) return false;
return true;
}
// Compare non-terminal nodes.
// If arity is one, the children must be equals.
if (arity1 == 1 && GPNodeCompare(root1->children[0], root2->children[0]))
return true;
// This arity is an error.
if (arity1 != 2) return false; // Should not happen
// If the opCode is a substraction, the two children must be the same and can't be permuted.
if (code1 == OP_SUB) {
if (GPNodeCompare(root1->children[0], root2->children[0])
&& GPNodeCompare(root1->children[1], root2->children[1]))
return true;
else return false;
}
// They can be equal if the children of the first node are a permutation of those of second node.
if ((GPNodeCompare(root1->children[0], root2->children[0])
&& GPNodeCompare(root1->children[1], root2->children[1]))
|| (GPNodeCompare(root1->children[0], root2->children[1])
&& GPNodeCompare(root1->children[1], root2->children[0])))
return true;
return false;
}
////////////////// END TREE COMPARE ////////////////////////
/////////////////////// BEGIN COLLECT ALL NODES //////////////////////
// Recursively collect all nodes in the tree. Puts collected nodes in
// collection and the number of collected nodes in collected.
void collectAllNodes(GPNode* root, GPNode*** collection, int* collected) {
for (int i = 0; i < (int)opArity[(int)root->opCode]; i++) {
collectAllNodes(root->children[i], collection, collected);
}
(*collection)[(*collected)++] = root;
}
//////////////////////// END COLLECT ALL NODES ///////////////////////
/////////////////////// BEGIN COLLECT NODES HEIGHT ///////////////////
// Recursively collects the nodes which height is "height", puts them
// into "collection" and keep the number of collected nodes in "collected"
void collectNodesHeightR(GPNode* root, const int height, int* currentHeight, GPNode*** collection, int* collected) {
char code = root->opCode;
if (!opArity[(int)code]) {
*currentHeight = 0;
}
else {
int sonsHeight = 0;
for (int i = 0; i < (int)opArity[(int)code]; i++) {
int sh;
collectNodesHeightR(root->children[i], height, &sh, collection, collected);
if (sh > sonsHeight) sonsHeight = sh;
}
*currentHeight = sonsHeight+1;
}
if (*currentHeight == height) (*collection)[(*collected)++] = root;
}
GPNode** collectNodesHeight(GPNode* root, const int height, const int rootDepth, int* nbNodes) {
// It is assumed that the maximum arity is 2, thus the maximum
// number of node is two to the power of DEPTH where DEPTH
// is the maximum depth reachable for nodes with a height of "height".
GPNode** collection = (GPNode**)malloc((1<<(rootDepth-1-height))*sizeof(GPNode*));
int collected = 0;
int currentHeight;
// The nodes at height "height" are put in collection and the total of
// collected nodes is put in "collected".
collectNodesHeightR(root, height, &currentHeight, &collection, &collected);
GPNode** ret = (GPNode**)malloc(collected*sizeof(GPNode*));
for (int i = 0; i < collected; i++) {
ret[i] = collection[i];
}
free(collection);
*nbNodes = collected;
return ret;
}
//////////////////////// END COLLECT NODES HEIGHT ////////////////////
/////////////////////// BEGIN SELECT NODE HEIGHT ///////////////////////
GPNode* selectNode1(GPNode* root) {
int depth = depthOfTree1(root);
// The height of the node is selected first.
int height = globalRandomGenerator->random(0, depth);
GPNode** collectedNodes;
int nbNodes;
// The nodes which height are at the good height are put in collectedNodes.
collectedNodes = collectNodesHeight(root, height, depth, &nbNodes);
// A node is choosen among collected nodes.
int index = globalRandomGenerator->random(0, nbNodes);
GPNode* ret = collectedNodes[index];
free(collectedNodes);
return ret;
}
GPNode* selectNode1(GPNode* root, const int minHeight, const int maxHeight) {
int depth = depthOfTree1(root);
// The height of the node is selected first.
int maxH = max(1, min(depth, maxHeight));
int minH = max(0, min(maxH-1, minHeight));
int height = globalRandomGenerator->random(minH, maxH);
GPNode** collectedNodes;
int nbNodes;
// The nodes which height are at the good height are put in collectedNodes.
collectedNodes = collectNodesHeight(root, height, depth, &nbNodes);
// A node is choosen among collected nodes.
int index = globalRandomGenerator->random(0, nbNodes);
GPNode* ret = collectedNodes[index];
free(collectedNodes);
return ret;
}
/////////////////////// END SELECT NODE HEIGHT ////////////////////////
////////////////////// BEGIN COLLECT ERC NODE //////////////////////
// Recursively collects the ERC nodes into "collection" and keep the
// number of collected nodes in "collected"
void collectERCNodesR(GPNode* root, GPNode*** collection, int* collected) {
char code = root->opCode;
if (code == OP_ERC) {
(*collection)[(*collected)++] = root;
return;
}
for (int i = 0; i < (int)opArity[(int)code]; i++) {
collectERCNodesR(root->children[i], collection, collected);
}
}
GPNode** collectERCNodes(GPNode* root, const int rootDepth, int* nbNodes) {
// It is assumed that the maximum arity is 2, thus the maximum
// number of node is two to the power of DEPTH where DEPTH
// is the depth of the tree.
GPNode** collection = (GPNode**)malloc((1<<(rootDepth-1))*sizeof(GPNode*));
int collected = 0;
// The ERC nodes are put in collection and the total of
// collected nodes is put in "collected".
collectERCNodesR(root, &collection, &collected);
GPNode** ret = (GPNode**)malloc(collected*sizeof(GPNode*));
for (int i = 0; i < collected; i++) {
ret[i] = collection[i];
}
free(collection);
*nbNodes = collected;
return ret;
}
/////////////////////// END COLLECT ERC NODE //////////////////////
/////////////////////// BEGIN SELECT ERC NODE //////////////////////
GPNode* selectERCNode(GPNode* root) {
int depth = depthOfTree1(root);
GPNode** collectedNodes;
int nbNodes;
// The ERC nodes are put in collectedNodes. Their number is put
// nbNodes.
collectedNodes = collectERCNodes(root, depth, &nbNodes);
// Case of a tree with no ERC node.
if (!nbNodes) return NULL;
// A node is choosen among collected nodes.
int index = globalRandomGenerator->random(0, nbNodes);
GPNode* ret = collectedNodes[index];
free(collectedNodes);
return ret;
}
//////////////////////// END SELECT ERC NODE ///////////////////////
This diff is collapsed.
#define PI 3.14159265358979
//Creates the perfect tree
GPNode* best() {
GPNode* root = new GPNode();
root->opCode = OP_ADD;
GPNode* root1 = new GPNode();
root1->opCode = OP_SUB;
root->children[0] = root1;
GPNode* root2 = new GPNode();
root2->opCode = OP_MUL;
root->children[1] = root2;
// ROOT1
GPNode* root11 = new GPNode();
root11->opCode = OP_MUL;
root1->children[0] = root11;
GPNode* root12 = new GPNode();
root12->opCode = OP_MUL;
root1->children[1] = root12;
// ROOT11
GPNode* root111 = new GPNode();
root111->opCode = OP_MUL;
root11->children[0] = root111;
GPNode* root112 = new GPNode();
root112->opCode = OP_ERC;
root112->erc_value = (0.08-0.14)/0.08;
root112->children[0] = NULL;
root112->children[1] = NULL;
root11->children[1] = root112;
// ROOT111
GPNode* root1111 = new GPNode();
root1111->opCode = OP_DTETA;
root1111->children[0] = NULL;
root1111->children[1] = NULL;
root111->children[0] = root1111;
GPNode* root1112 = new GPNode();
root1112->opCode = OP_DPSI;
root1112->children[0] = NULL;
root1112->children[1] = NULL;
root111->children[1] = root1112;
// ROOT12
GPNode* root121 = new GPNode();
root121->opCode = OP_ERC;
root121->erc_value = 0.00005*2*777/0.08;
root121->children[0] = NULL;
root121->children[1] = NULL;
root12->children[0] = root121;
GPNode* root122 = new GPNode();
root122->opCode = OP_MUL;
root12->children[1] = root122;
// ROOT122
GPNode* root1221 = new GPNode();
root1221->opCode = OP_DTETA;
root1221->children[0] = NULL;
root1221->children[1] = NULL;
root122->children[0] = root1221;
GPNode* root1222 = new GPNode();
root1222->opCode = OP_SUB;
root122->children[1] = root1222;
// ROOT1222
GPNode* root12221 = new GPNode();
root12221->opCode = OP_ADD;
root1222->children[0] = root12221;
GPNode* root12222 = new GPNode();
root12222->opCode = OP_ADD;
root1222->children[1] = root12222;
// ROOT12221
GPNode* root122211 = new GPNode();
root122211->opCode = OP_U2;
root122211->children[0] = NULL;
root122211->children[1] = NULL;
root12221->children[0] = root122211;
GPNode* root122212 = new GPNode();
root122212->opCode = OP_U4;
root122212->children[0] = NULL;
root122212->children[1] = NULL;
root12221->children[1] = root122212;
// ROOT12222
GPNode* root122221 = new GPNode();
root122221->opCode = OP_U1;
root122221->children[0] = NULL;
root122221->children[1] = NULL;
root12222->children[0] = root122221;
GPNode* root122222 = new GPNode();
root122222->opCode = OP_U3;
root122222->children[0] = NULL;
root122222->children[1] = NULL;
root12222->children[1] = root122222;
// ROOT2
GPNode* root21 = new GPNode();
root21->opCode = OP_ERC;
root21->erc_value = 0.00000593*777*777/0.08;
root21->children[0] = NULL;
root21->children[1] = NULL;
root2->children[0] = root21;
GPNode* root22 = new GPNode();
root22->opCode = OP_ADD;
root2->children[1] = root22;
// ROOT22
GPNode* root221 = new GPNode();
root221->opCode = OP_ADD;
root22->children[0] = root221;
GPNode* root222 = new GPNode();
root222->opCode = OP_ADD;
root22->children[1] = root222;
// ROOT221
GPNode* root2211 = new GPNode();
root2211->opCode = OP_MUL;
root221->children[0] = root2211;
GPNode* root2212 = new GPNode();
root2212->opCode = OP_MUL;
root221->children[1] = root2212;
// ROOT222
GPNode* root2221 = new GPNode();
root2221->opCode = OP_MUL;
root222->children[0] = root2221;
GPNode* root2222 = new GPNode();
root2222->opCode = OP_MUL;
root222->children[1] = root2222;
// ROOT2211
GPNode* root22111 = new GPNode();
root22111->opCode = OP_ERC;
root22111->erc_value = sin(-3*PI/8)+sin(-PI/8);
root22111->children[0] = NULL;
root22111->children[1] = NULL;
root2211->children[0] = root22111;
GPNode* root22112 = new GPNode();
root22112->opCode = OP_MUL;
root2211->children[1] = root22112;
// ROOT2212
GPNode* root22121 = new GPNode();
root22121->opCode = OP_ERC;
root22121->erc_value = sin(3*PI/8)+sin(PI/8);
root22121->children[0] = NULL;
root22121->children[1] = NULL;
root2212->children[0] = root22121;
GPNode* root22122 = new GPNode();
root22122->opCode = OP_MUL;
root2212->children[1] = root22122;
// ROOT2221
GPNode* root22211 = new GPNode();
root22211->opCode = OP_ERC;
root22211->erc_value = sin(7*PI/8)+sin(5*PI/8);
root22211->children[0] = NULL;
root22211->children[1] = NULL;
root2221->children[0] = root22211;
GPNode* root22212 = new GPNode();
root22212->opCode = OP_MUL;
root2221->children[1] = root22212;
//ROOT2222
GPNode* root22221 = new GPNode();
root22221->opCode = OP_ERC;
root22221->erc_value = sin(-7*PI/8)+sin(-5*PI/8);
root22221->children[0] = NULL;
root22221->children[1] = NULL;
root2222->children[1] = root22221;
GPNode* root22222 = new GPNode();
root22222->opCode = OP_MUL;
root2222->children[0] = root22222;
// ROOT22112
GPNode* root221121 = new GPNode();
root221121->opCode = OP_U1;
root221121->children[0] = NULL;
root221121->children[1] = NULL;
root22112->children[0] = root221121;
GPNode* root221122 = new GPNode();
root221122->opCode = OP_U1;
root221122->children[0] = NULL;
root221122->children[1] = NULL;
root22112->children[1] = root221122;
// ROOT22122
GPNode* root221221 = new GPNode();
root221221->opCode = OP_U2;
root221221->children[0] = NULL;
root221221->children[1] = NULL;
root22122->children[0] = root221221;
GPNode* root221222 = new GPNode();
root221222->opCode = OP_U2;
root221222->children[0] = NULL;
root221222->children[1] = NULL;
root22122->children[1] = root221222;
// ROOT22212
GPNode* root222121 = new GPNode();
root222121->opCode = OP_U3;
root222121->children[0] = NULL;
root222121->children[1] = NULL;
root22212->children[0] = root222121;
GPNode* root222122 = new GPNode();
root222122->opCode = OP_U3;
root222122->children[0] = NULL;
root222122->children[1] = NULL;
root22212->children[1] = root222122;
// ROOT22222
GPNode* root222221 = new GPNode();
root222221->opCode = OP_U4;
root222221->children[0] = NULL;
root222221->children[1] = NULL;
root22222->children[0] = root222221;
GPNode* root222222 = new GPNode();
root222222->opCode = OP_U4;
root222222->children[0] = NULL;
root222222->children[1] = NULL;
root22222->children[1] = root222222;
return root;
}
/////////////////////// BEGIN CROSSOVER 1 ////////////////////////
void crossOver1(IndividualImpl& p1, IndividualImpl& p2, IndividualImpl& c){
GPNode* parent1Node = selectNode1(c.root);
int depthOfP1Node = depthOfNodeInTree(c.root, parent1Node);
if (depthOfP1Node <= 0 || depthOfP1Node > TREE_DEPTH_MAX) return; // error
GPNode* parent2Node = selectNode1(p2.root, 0, TREE_DEPTH_MAX-depthOfP1Node+1);
delete parent1Node->children[0];
delete parent1Node->children[1];
parent1Node->opCode = parent2Node->opCode;
parent1Node->erc_value = parent2Node->erc_value;
parent1Node->children[0] = parent2Node->children[0];
parent1Node->children[1] = parent2Node->children[1];
parent2Node->children[0] = NULL;
parent2Node->children[1] = NULL;
}
/////////////////////// END CROSSOVER 1 //////////////////////////
////////////////////// BEGIN CROSSOVER ///////////////////////
void crossOver(IndividualImpl& p1, IndividualImpl& p2, IndividualImpl& c){
//GPNode* c1 = new GPNode(*(c.root));
crossOver1(p1, p2, c);
//cross++;
//if (GPNodeCompare(c.root, c1)) crossClone++;
//delete c1;
}
////////////////////// END CROSSOVER ////////////////////////
This diff is collapsed.
////////////////////////// BEGIN NORMALIZATION //////////////////
#ifdef NORMALIZATION
float* normalizationCoeff;
#endif
/////////////////////////// END NORMALIZATION ///////////////////
////////////////////////// BEGIN PMUT //////////////////////////
#if defined PMUTVAR
std::ostringstream pMutVarDesc;
#if PMUTVAR==1
float previousFitness = 0.;
#if defined MUTATOR && MUTATOR==3
float pMutInit = 0.02; // Initial probability.
#else
float pMutInit = 0.5; // Initial probability.
#endif
float pMutUp = 1.1; // Coefficient by witch the mutation probability
// is multiply when the population does not progress.
// Should be greater than 1.
float pMutDown = 0.9; // Coefficient by witch the mutation probability
// is multiply when the population progresses.
// Should be lower than 1.
int flatGenMax = 5; // Number of generation with no progression
// before increasing mutation probablility.
float pMutThreshold = 0.0005; // Relative threshold to determine whether or
// not the finess is flat.
int nbFlatGen = 0;
#else
#if defined MUTATOR && MUTATOR==3
float pMutInit = 0.02; // Initial probability.
#else
float pMutInit = 0.5; // Initial probability.
#endif
float pMutRatio = 1.; // pMutInit is divided by pMutRatio*nbGen.
#endif
#endif
/////////////////////////// END PMUT /////////////////////////
////////////////////// BEGIN DIVISION PENALTY ////////////////////
#ifdef DIVPENALTY
std::ostringstream divPenaltyDesc;
int genWithoutDivTest = 0; // Remaining number of generation without
// performing the test for division.
int maxGenWithoutDivTest = 5; // Maximum generation without test.
float nbInvalidTreeTestThreshold = 0.005; // Relative number of maximum invalids
// individuals to avoid test
#if DIVPENALTY==1
float divPenaltyInc = 1.;
#elif DIVPENALTY==2
float divPenaltyMult = 2.;
#elif DIVPENALTY==3 || DIVPENALTY==4
float divPenaltyProgInit = 2.;
float divPenaltyProgFinal = 10.;
#if DIVPENALTY==4
int previousNbPenalizedTree;
float nbInvalidTreePenaltyThreshold = 0.05;
#endif
#elif DIVPENALTY==5
#else
float divPenaltyKill = 1000.;
#endif
#endif
////////////////////////// END DIVISION PENALTY //////////////////
///////////////////////// BEGIN FILES2 ////////////////////////
#ifdef FILES2
float** inputs1;
float** inputs2;
float* output1;
float* output2;
#endif
///////////////////////// END FILES2 //////////////////////////
///////////////////////// BEGIN FITNESS ///////////////////////
std::ostringstream fitnessDesc;
////////////////////////// END FITNESS ////////////////////////
//////////////////////// BEGIN MUTATOR ///////////////////////
std::ostringstream mutatorDesc;
///////////////////////// END MUTATOR ////////////////////////
/////////////////////// BEGIN SET PARAMETERS //////////////////////
void setParam() {
#ifdef PMUTVAR
EA->population->pMutation = pMutInit;
#endif
#if MUTATOR==3
EA->population->pMutation = 1.;
EA->population->pMutationPerGene = 0.0005;
#endif
}
//////////////////////// END SET PARAMETERS ///////////////////////
//////////////////////// BEGIN STATS //////////////////////////
int mut = 0;
int cross = 0;
int mutClone = 0;
int crossClone = 0;
///////////////////////// END STATS ///////////////////////////
//////////////////////// BEGIN CREATE TREE ///////////////////////
GPNode* createTree(const int depth, const bool full) {
if (depth <= 0) return NULL;
GPNode* root = new GPNode();
if (depth == 1) {
root->opCode = globalRandomGenerator->random(0, VAR_LEN);
if (root->opCode == OP_ERC)
root->erc_value = globalRandomGenerator->random(-10.f, 10.f);
} else {
if (full) root->opCode = globalRandomGenerator->random(VAR_LEN, OPCODE_SIZE);
else {
if (globalRandomGenerator->tossCoin(0.1)) return createTree(1, full);
root->opCode = globalRandomGenerator->random(VAR_LEN, OPCODE_SIZE);
}
}
//printf("code: %d\n", root->opCode);
//if (root->opCode == OP_ERC) printf("erc: %f\n", root->erc_value);
root->children[0] = createTree(depth-1, full);