/// <summary> /// Changes the given genome by mutating the gene corresponding to the given <see cref="IParameterNode" />. /// </summary> /// <param name="genome">The genome to mutate. Will be modified.</param> /// <param name="parameterNode">Specification of the parameter / gene to mutate.</param> protected void MutateParameter(Genome genome, IParameterNode parameterNode) { var currentValue = genome.GetGeneValue(parameterNode.Identifier); var mutatedValue = parameterNode.Domain.MutateGeneValue( currentValue, this._mutationVariancePercentage); genome.SetGene(parameterNode.Identifier, mutatedValue); }
/// <summary> /// Checks whether the given genome matches the <see cref="_parameterTree" />. /// </summary> /// <param name="genome">The genome to check.</param> /// <returns>Whether or not the genome matches the parameter tree.</returns> private bool CheckAgainstParameterTree(Genome genome) { // For each parameter: foreach (var parameterNode in this._parameterNodes) { // Check that fitting gene's value is legal. var value = genome.GetGeneValue(parameterNode.Identifier); if (!parameterNode.Domain.ContainsGeneValue(value)) { return(false); } } // All parameters exist in genome and their values are legal. return(true); }
/// <summary> /// Sets the value for the specified gene on the given child, /// respecting its parents and the latest parameter origin. /// </summary> /// <param name="node"> /// Specifies the gene to set the value for. /// Is allowed to be an <see cref="AndNode" />. In this case, nothing happens. /// </param> /// <param name="parent1">The first parent.</param> /// <param name="parent2">The second parent.</param> /// <param name="child">The child. Genome will be modified.</param> /// <param name="lastParameterOrigin"> /// The latest parameter origin. /// Influences the probability which parent's gene the child inherits. /// </param> /// <returns> /// The origin of the inherited gene value. /// For an <see cref="AndNode" />, returns the given parameter origin. /// </returns> private ParameterOrigin SetGeneValue( IParameterTreeNode node, Genome parent1, Genome parent2, Genome child, ParameterOrigin lastParameterOrigin = ParameterOrigin.Open) { // If the node is not a parameter node, we do not have to set a value. // The parameter origin does not change. var nodeAsParameter = node as IParameterNode; if (nodeAsParameter == null) { return(lastParameterOrigin); } // If it is a parameter node, find the parents' gene values. var parameterName = nodeAsParameter.Identifier; var parent1GeneValue = parent1.GetGeneValue(parameterName); var parent2GeneValue = parent2.GetGeneValue(parameterName); // If they are equal and the last parameter's origin is open, set child's parameter value to it // and keep the origin. if (lastParameterOrigin == ParameterOrigin.Open && object.Equals(parent1GeneValue, parent2GeneValue)) { child.SetGene(parameterName, parent1GeneValue); return(lastParameterOrigin); } // Otherwise, randomly decide on one of the two parents. // The probability for the parents is dependent on the last parameter's origin. double probabilityForFirstParent; switch (lastParameterOrigin) { case ParameterOrigin.FirstParent: probabilityForFirstParent = 1 - this._crossoverSwitchProbability; break; case ParameterOrigin.SecondParent: probabilityForFirstParent = this._crossoverSwitchProbability; break; case ParameterOrigin.Open: probabilityForFirstParent = 0.5; break; default: throw new ArgumentException($"Parameter origin {lastParameterOrigin} is unknown."); } // Throw a (biased) coin and decide on one parent to inherit the gene value from. var useFirstParent = Randomizer.Instance.Decide(probabilityForFirstParent); if (useFirstParent) { child.SetGene(parameterName, parent1GeneValue); return(ParameterOrigin.FirstParent); } child.SetGene(parameterName, parent2GeneValue); return(ParameterOrigin.SecondParent); }