Commit 8f44bf4a by 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, ¤tHeight, &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 ///////////////////////