public static void crossover(GeneticTree current, GeneticTree other) { List <string> currentIndices = current._nodeIndices.Where(x => x.Length != 1).ToList(); List <string> otherIndices = other._nodeIndices.Where(x => x.Length != 1).ToList(); int currentIndexAux = Rng.Rnd.Next(currentIndices.Count); int otherIndexAux = Rng.Rnd.Next(otherIndices.Count); string currentIndex = currentIndices[currentIndexAux]; string otherIndex = otherIndices[otherIndexAux]; GeneticNode iterCurrent = current._root; GeneticNode iterOther = other._root; for (int i = 1; i < currentIndex.Length; i++) { int index = GeneticTree._TREE_NODES_CHAR_TO_INT[currentIndex[i]]; iterCurrent = iterCurrent._children._children[index]; } for (int i = 1; i < otherIndex.Length; i++) { int index = GeneticTree._TREE_NODES_CHAR_TO_INT[otherIndex[i]]; iterOther = iterOther._children._children[index]; } current.attachNode(iterOther, currentIndex); other.attachNode(iterCurrent, otherIndex); current.recalculateIndices(); other.recalculateIndices(); }
private GeneticNode _attachNodeAux(GeneticNode currentNode, int currentDepth, string previousTag, int childOrdinal, GeneticNode toAttach, string targetTag) { string currentTag = previousTag + _TREE_NODES_INT_TO_CHAR[childOrdinal]; if (currentTag.CompareTo(targetTag) == 0) { return(_fixTreeAux(toAttach, currentDepth)); } switch (currentNode) { case ConstNode cn: return(cn); case VariableNode vn: return(vn); case OperatorNode op: for (int i = 0; i < op._childNum; i++) { op._children[i] = _attachNodeAux(op._children[i], currentDepth + 1, currentTag, i, toAttach, targetTag); } return(op); case MultipleNode mn: mn._children[0] = _attachNodeAux(mn._children[0], currentDepth + 1, currentTag, 0, toAttach, targetTag); return(mn); default: return(currentNode); } }
private void _getRPNAux(GeneticNode current, ref StringBuilder res) { switch (current) { case OperatorNode on: res.Append(NodeDictionary.OPERATOR_RPN[on._operatorType]); res.Append("|"); res.Append(current._childNum.ToString()); res.Append(" "); break; case VariableNode vn: res.Append(NodeDictionary.VARIABLE_RPN[vn._variableType]); res.Append(" "); break; case ConstNode cn: res.Append(NodeDictionary.CONST_RPN); res.Append(cn._value.ToString(CultureInfo.InvariantCulture)); res.Append(" "); break; case MultipleNode mn: res.Append(NodeDictionary.MULTIPLE_RPN); res.Append(mn._value.ToString(CultureInfo.InvariantCulture)); res.Append(" "); break; } for (int i = 0; i < current._childNum; i++) { _getRPNAux(current._children[i], ref res); } }
private void _setColorAux(GeneticNode current) { current._color = _nodesColor; foreach (var item in current._children._children) { _setColorAux(item); } }
public static void mutateOpportunistic(GeneticTree current) { NodeStatistics stats = current.allNodesStats(current._root, 0, "", 0); List <NodeStatsPair> opportunities = new List <NodeStatsPair>(); foreach (var item in current._nodeStatsDictionary) { //Debug.WriteLine("Node " + item.Key + " /// Operator variance: " + item.Value._opVariance + " Variable variance: " + item.Value._varVariance + " Avg depth: " + item.Value._avgDepth + " Avg branching: " + item.Value._avgBranching); opportunities.Add(new NodeStatsPair(item.Key, item.Value._avgBranching + item.Value._avgDepth + item.Value._opVariance + item.Value._varVariance)); } float max = opportunities.Max(x => x._mutationValue); foreach (var item in opportunities) { item._mutationValue = max - item._mutationValue + 1; // make less branchy, depthy and variant more likely to be mutated } opportunities = opportunities.OrderByDescending(x => x._mutationValue).ToList(); float[] wSum = new float[opportunities.Count]; wSum[0] = opportunities[0]._mutationValue; for (int i = 1; i < wSum.Length; i++) { wSum[i] = opportunities[i]._mutationValue + wSum[i - 1]; } float sumF = opportunities.Sum(x => x._mutationValue); double centil = Rng.Rnd.NextDouble() * sumF; int index = 0; for (int i = 0; i < opportunities.Count && centil < wSum[i]; i++) { index = i; } string currentIndex = opportunities[index]._node; int newDepth = (int)current._maxDepth - currentIndex.Length + 1; GeneticTree added = new GeneticTree((uint)newDepth, current._maxBranching); GeneticNode tmp = current._root; for (int i = 1; i < currentIndex.Length; i++) // traversing to find proper index { index = GeneticTree._TREE_NODES_CHAR_TO_INT[currentIndex[i]]; tmp = tmp._children._children[index]; } current.attachNode(added._root, currentIndex); current.recalculateIndices(); }
private void _recalculateIndicesAux(GeneticNode current, string previousTag, int childOrdinal) { string currentTag = previousTag + _TREE_NODES_INT_TO_CHAR[childOrdinal]; for (int i = 0; i < current._childNum; i++) { _recalculateIndicesAux(current._children[i], currentTag, i); } _nodeIndices.Add(currentTag); }
private void _branchingAux(GeneticNode current, int currentDepth, ref int count, ref int total) { switch (current) { case OperatorNode on: case MultipleNode mn: count++; total += (int)current._childNum; break; } for (int i = 0; i < current._childNum; i++) { _branchingAux(current._children[i], currentDepth + 1, ref count, ref total); } }
private void _opCountAux(GeneticNode current, ref int[] counter) { switch (current) { case OperatorNode on: counter[(int)on._operatorType]++; break; case MultipleNode mn: counter[OPERATOR_NODES_NUM]++; break; } for (int i = 0; i < current._childNum; i++) { _opCountAux(current._children[i], ref counter); } }
private void _depthAux(GeneticNode current, int currentDepth, ref int count, ref int total) { switch (current) { case ConstNode cn: case VariableNode vn: count++; total += currentDepth; break; default: for (int i = 0; i < current._childNum; i++) { _depthAux(current._children[i], currentDepth + 1, ref count, ref total); } break; } }
public static void mutateSwap(GeneticTree current) { List <string> currentIndices = current._nodeIndices.Where(x => x.Length != 1).ToList(); int currentIndexAux = Rng.Rnd.Next(currentIndices.Count); string currentIndex = currentIndices[currentIndexAux]; List <string> otherIndices = current._nodeIndices. Where(x => x.Length != 1).ToList(); List <string> shorter = otherIndices.Where(x => x.Length <= currentIndex.Length).Where(x => currentIndex.Substring(0, x.Length).CompareTo(x) != 0).ToList(); List <string> longer = otherIndices.Where(x => x.Length > currentIndex.Length).Where(x => x.Substring(0, currentIndex.Length).CompareTo(currentIndex) != 0).ToList(); otherIndices = shorter.Union(longer).ToList(); if (otherIndices == null || otherIndices.Count == 0) { return; } int otherIndexAux = Rng.Rnd.Next(otherIndices.Count); string otherIndex = otherIndices[otherIndexAux]; GeneticNode tmp = current._root; GeneticNode tmp2 = current._root; for (int i = 1; i < currentIndex.Length; i++) { int index = GeneticTree._TREE_NODES_CHAR_TO_INT[currentIndex[i]]; tmp = tmp._children._children[index]; } for (int i = 1; i < otherIndex.Length; i++) { int index = GeneticTree._TREE_NODES_CHAR_TO_INT[otherIndex[i]]; tmp2 = tmp2._children._children[index]; } current.attachNode(tmp2, currentIndex); current.attachNode(tmp, otherIndex); current.recalculateIndices(); }
private GeneticNode _fixTreeAux(GeneticNode current, int currentDepth) { current._childNum = (uint)Math.Min(_maxBranching, current._childNum); current._children.Resize((int)current._childNum); GeneticNode res; if (currentDepth >= _maxDepth) { res = randomNode(0, 4, 1); res._color = current._color; return(res); } switch (current) { case OperatorNode on: res = OperatorNode.shallowCopy(on); break; case VariableNode vn: res = VariableNode.shallowCopy(vn); break; case ConstNode cn: res = ConstNode.shallowCopy(cn); break; case MultipleNode mn: res = MultipleNode.shallowCopy(mn); break; default: res = current; break; } for (int i = 0; i < res._childNum; i++) { res._children[i] = _fixTreeAux(res._children[i], currentDepth + 1); } return(res); }
public static void mutateReplace(GeneticTree current) { List <string> currentIndices = current._nodeIndices.Where(x => x.Length != 1).ToList(); int currentIndexAux = Rng.Rnd.Next(currentIndices.Count); string currentIndex = currentIndices[currentIndexAux]; int newDepth = (int)current._maxDepth - currentIndex.Length + 1; GeneticTree added = new GeneticTree((uint)newDepth, current._maxBranching); GeneticNode tmp = current._root; for (int i = 1; i < currentIndex.Length; i++) // traversing to find proper index { int index = GeneticTree._TREE_NODES_CHAR_TO_INT[currentIndex[i]]; tmp = tmp._children._children[index]; } current.attachNode(added._root, currentIndex); current.recalculateIndices(); }
public void addChild(GeneticNode child) { _children._children.Add(child); }
public NodeStatistics allNodesStats(GeneticNode current, int currentDepth, string previousTag, int childOrdinal) { string currentTag = previousTag + _TREE_NODES_INT_TO_CHAR[childOrdinal]; NodeStatistics ns = new NodeStatistics(); ns._totalCount++; ns._depth += currentDepth; switch (current) { case OperatorNode on: ns._totalOpCount++; ns._branching += (int)current._childNum; ns._opCount[(int)on._operatorType]++; for (int i = 0; i < on._childNum; i++) { NodeStatistics res = allNodesStats(on._children[i], currentDepth + 1, currentTag, i); ns._branching += res._branching; ns._depth += res._depth; ns._totalCount += res._totalCount; ns._totalOpCount += res._totalOpCount; ns._opCount = res._opCount.Zip(ns._opCount, (x, y) => x + y).ToArray(); ns._varCount = res._varCount.Zip(ns._varCount, (x, y) => x + y).ToArray(); } break; case VariableNode vn: ns._varCount[(int)vn._variableType]++; break; case MultipleNode mn: ns._totalOpCount++; ns._opCount[OPERATOR_NODES_NUM + MULTIPLE_NODES_NUM - 1]++; ns._branching += (int)current._childNum; for (int i = 0; i < mn._childNum; i++) { NodeStatistics res = allNodesStats(mn._children[i], currentDepth + 1, currentTag, i); ns._branching += res._branching; ns._totalCount += res._totalCount; ns._totalOpCount += res._totalOpCount; ns._depth += res._depth; ns._opCount = res._opCount.Zip(ns._opCount, (x, y) => x + y).ToArray(); ns._varCount = res._varCount.Zip(ns._varCount, (x, y) => x + y).ToArray(); } break; default: // ConstNode ns._varCount[GeneticTree.VARIABLE_NODES_NUM + GeneticTree.CONST_NODES_NUM - 1]++; break; } if (currentDepth < _maxDepth) { if (ns._branching == 0 || ns._totalOpCount == 0) { ns._avgBranching = 1; } else { ns._avgBranching = ns._branching / (float)ns._totalOpCount; } ns._avgDepth = (float)ns._depth / (float)ns._totalCount; ns._avgDepth -= currentDepth; double opAvg = ns._opCount.Average(); double varAvg = ns._varCount.Average(); double accOp = 0, accVar = 0; accOp = ns._opCount.Aggregate(0.0, (acc, val) => (double)(acc + ((val - opAvg) * (val - opAvg)))); accVar = ns._varCount.Aggregate(0.0, (acc, val) => (double)(acc + ((val - varAvg) * (val - varAvg)))); ns._opVariance = (float)accOp / ns._opCount.Length; ns._varVariance = (float)accVar / ns._varCount.Length; _nodeStatsDictionary[currentTag] = ns; } return(ns); }
public void attachNode(GeneticNode toAttach, string targetTag) { _nodeIndices.Clear(); _root = _attachNodeAux(_root, 0, "", 0, toAttach, targetTag); }