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(); }
public void calculatePositions() { int correct = 0; GeneticTree _tree = _population[0]; Task t = new Task(() => { StreamReader sr = new StreamReader("./test/testpos"); string line; char[] fenDelim = { ';' }; while ((line = sr.ReadLine()) != null) { string[] FENs = line.Split(fenDelim); string first = FENs[0].Split(null)[0]; string second = FENs[1].Split(null)[0]; Process p = new Process(); p.StartInfo.FileName = "bestmove.exe"; p.StartInfo.Arguments = $"{_evalDepth} \"{FENs[0]}\" \"{_tree._rpn}\""; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.CreateNoWindow = true; p.StartInfo.UseShellExecute = false; p.Start(); string FEN = p.StandardOutput.ReadToEnd().Trim(); if (FEN.Split(null)[0].CompareTo(second) == 0) { correct++; } } }); t.Start(); Task.WaitAll(new Task[] { t }); _statistics._positionsSolved.Add(correct); }
public void beginCrossover() { _successfulCrossover = new List <TreePair>(); _toMutate = new List <GeneticTree>(); foreach (var item in _toCrossover) { if (Rng.Rnd.NextDouble() < _crossoverRate) { GeneticTree t1 = GeneticTree.deepCopy(item._first); GeneticTree t2 = GeneticTree.deepCopy(item._second); crossover(t1, t2); _successfulCrossover.Add(new TreePair(GeneticTree.deepCopy(t1), GeneticTree.deepCopy(t2))); _swapParents(t1, t2, item._first._id, item._second._id); _toMutate.Add(t1); _toMutate.Add(t2); } else { _toMutate.Add(item._first); _toMutate.Add(item._second); } } }
private void _swapParents(GeneticTree first, GeneticTree second, ulong firstParentId, ulong secondParentId) { ulong randomSalt = Rng.randomSparseBits(); first._id = (firstParentId & _RIGHT_PARENT_MASK) | (secondParentId & _LEFT_PARENT_MASK) ^ randomSalt; second._id = (secondParentId & _RIGHT_PARENT_MASK) | (firstParentId & _LEFT_PARENT_MASK) ^ randomSalt; first._firstParentId = second._firstParentId = firstParentId; first._secondParentId = second._secondParentId = secondParentId; }
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(); }
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(); }
public void beginMutation() { _successfulMutation = new List <GeneticTree>(); foreach (var item in _toMutate) { item.setColor(item._nodesColor); item.allNodesStats(item._root, 0, "", 0); if (Rng.Rnd.NextDouble() < _mutationRate) { GeneticTree copy = GeneticTree.deepCopy(item); mutateOpportunistic(copy); _successfulMutation.Add(copy); } else { _newPopulation.Add(item); } } }
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 static GeneticTree deepCopy(GeneticTree other) { GeneticTree res = new GeneticTree(other._maxDepth, other._maxBranching); res._nodesColor = other._nodesColor; res._id = other._id; res._nodeIndices = new List <string>(other._nodeIndices); switch (other._root) { case OperatorNode on: res._root = OperatorNode.deepCopy((OperatorNode)other._root); break; case VariableNode vn: res._root = VariableNode.deepCopy((VariableNode)other._root); break; case ConstNode cn: res._root = ConstNode.deepCopy((ConstNode)other._root); break; case MultipleNode mn: res._root = MultipleNode.deepCopy((MultipleNode)other._root); break; default: break; } res.getRPN(); res._nodeStatsDictionary = other._nodeStatsDictionary; res._firstParentId = other._firstParentId; res._secondParentId = other._secondParentId; //res.setColor(other._nodesColor.r, other._nodesColor.g, other._nodesColor.b); return(res); }
public void beginSelection() { _newPopulation = new List <GeneticTree>(); _toCrossover = new List <TreePair>(); int elitismPassNumber = (int)(_populationSize * _elitismPercentage); if (elitismPassNumber % 2 != 0) { elitismPassNumber++; } for (int i = 0; i < elitismPassNumber; i++) { _newPopulation.Add(GeneticTree.deepCopy(_population[i])); } switch (_selectionType) { case GpSelectionType.RANK: int[] weights = Enumerable.Range(1, (int)_populationSize).Reverse().ToArray(); int[] weightsRev = weights.Reverse().ToArray(); uint[] weightSum = new uint[_populationSize]; weightSum[0] = _populationSize; for (uint i = 1; i < weightSum.Length; i++) { weightSum[i] = _populationSize - i + weightSum[i - 1]; } int sum = ((1 + (int)_populationSize)) * (int)_populationSize / 2; for (int i = 0; i < _populationSize - elitismPassNumber; i += 2) { int centil = Rng.Rnd.Next(0, sum); int resIndex = weightsRev.First(x => weightSum[x - 1] > centil) - 1; GeneticTree first = _population[resIndex]; centil = Rng.Rnd.Next(0, sum); resIndex = weightsRev.First(x => weightSum[x - 1] > centil) - 1; GeneticTree second = _population[resIndex]; _toCrossover.Add(new TreePair(GeneticTree.deepCopy(first), GeneticTree.deepCopy(second))); } break; case GpSelectionType.ROULETTE: weights = Enumerable.Range(0, (int)_populationSize).ToArray(); weightsRev = weights.Reverse().ToArray(); float[] wSum = new float[(int)_populationSize]; wSum[0] = _fitnesses[0]; for (int i = 1; i < wSum.Length; i++) { wSum[i] = _fitnesses[i] + wSum[i - 1]; } float sumF = _fitnesses.Sum(); for (int i = 0; i < _populationSize - elitismPassNumber; i += 2) { double centil = Rng.Rnd.NextDouble() * sumF; int resIndex = weights.First(x => wSum[x] > centil); GeneticTree first = _population[resIndex]; centil = Rng.Rnd.NextDouble() * sumF; resIndex = weights.First(x => wSum[x] > centil); GeneticTree second = _population[resIndex]; _toCrossover.Add(new TreePair(GeneticTree.deepCopy(first), GeneticTree.deepCopy(second))); } break; case GpSelectionType.TOURNAMENT: weights = Enumerable.Range(0, (int)_populationSize).ToArray(); var shuffled = weights.OrderBy(x => Guid.NewGuid()); for (int i = 0; i < _populationSize - elitismPassNumber; i += 2) { var slice = shuffled.Take((int)_tournamentSelectionSize); var firstRandom = _population[slice.OrderByDescending(x => _fitnesses[x]).First()]; shuffled = weights.OrderBy(x => Guid.NewGuid()); slice = shuffled.Take((int)_tournamentSelectionSize); var secondRandom = _population[slice.OrderByDescending(x => _fitnesses[x]).First()]; shuffled = weights.OrderBy(x => Guid.NewGuid()); _toCrossover.Add(new TreePair(GeneticTree.deepCopy(firstRandom), GeneticTree.deepCopy(secondRandom))); } break; } }
public TreePair(GeneticTree first, GeneticTree second) { _first = first; _second = second; }