module Operator # Common functionality for MutationBitNodal, MutationBitStructural, MutationNodal and # MutationStructural classes. # class MutationAlteringCore # See a subclass description. def initialize( grammar ) @grammar = grammar @random = Kernel @offset = 0 end # See a subclass description. def mutation( orig, track ) mutant = orig.clone filtered_track = track.find_all { |node| @grammar[ node.symbol ].sn_altering == filter } return mutant if filtered_track.empty? where = @random.rand( filtered_track.size ) index = ( filtered_track[where].from + @offset ).divmod( mutant.size ).last mutant[ index ] = get_codon_value( mutant, index ) mutant end # Offset which is added to the index of the mutated codon's position. # This is useful for Mapper::*Locus mappers where the odd codons encode a location choices and # even codons encode rule choices. attr_accessor :offset end # Common functionality for MutationBitNodal and MutationBitStructural classes. # # Select the random (nodal/structural filtered) position within the orig vector and mutate it. # The resultant value (of a mutated codon) is bit-mutated by self.codon.mutate_bit method. # Return the mutated copy of the orig. genotype. # track argument is the hint (symbols attached to positions) obtained from Mapper::Base#track_support # class MutationBitAltering < MutationAlteringCore # Create the mutation operator. # grammar is the valid grammar for distinguishing :structural and :nodal symbols def initialize( grammar ) super @codon = CodonMod.new # standard 8-bit codons end # Codon encoding scheme. By default the instance of the CodonMod class is used (ie. standard GE 8-bit codons) # See CodonMod for details. attr_accessor :codon # The source of randomness, used for calling "random.rand( limit )", defaulting to 'Kernel' class. attr_reader :random # Set the source of randomness (for testing purposes). def random= rnd @random = rnd @codon.random = rnd end protected def get_codon_value( mutant, index ) @codon.mutate_bit( mutant.at(index) ) end end # Structural bit-level mutation (see http://portal.acm.org/citation.cfm?id=1570215). # It assumes the source genotype has the form of the Array of numbers. # Select codons with Token#sn_altering == :structural for mutation. # Structural change means the length of genotype->phenotype transformation process CAN change for mutated genotype. # class MutationBitStructural < MutationBitAltering protected def filter :structural end end # Nodal bit-level mutation (see http://portal.acm.org/citation.cfm?id=1570215). # It assumes the source genotype has the form of the Array of numbers. # Select codons with Token#sn_altering == :nodal for mutation. # Nodal change means the length of genotype->phenotype transformation process CANNOT change for mutated genotype. # class MutationBitNodal < MutationBitAltering protected def filter :nodal end end # Common functionality for MutationNodal and MutationStructural classes. # Select the random (nodal/structural filtered) position within the orig vector and mutate it. # The resultant value (of a mutated codon) is a random number in the range 0..magnitude. # Return the mutated copy of the orig. genotype. # track argument is the hint (symbols atteched to positions) obtained from Mapper::Base#track_support # class MutationAltering < MutationAlteringCore # Create the mutation operator. # grammar is the valid grammar for distinguishing :structural and :nodal symbols # magnitude is the initial value of the MutationAltering#magnitude attribute def initialize( grammar, magnitude=nil ) super(grammar) @magnitude = magnitude end # The source of randomness, used for calling "random.rand( limit )", defaulting to 'Kernel' class. attr_accessor :random # The maximal possible value of the mutaton plus 1. If not specified, the maximal value over the original # genotype values is used. attr_accessor :magnitude protected def get_codon_value( mutant, index ) max = @magnitude.nil? ? mutant.max+1 : @magnitude @random.rand( max ) end end # Structural codon-level mutation (see http://portal.acm.org/citation.cfm?id=1570215). # It assumes the source genotype has the form of the Array of numbers. # Select codons with Token#sn_altering == :structural for mutation. # Structural change means the length of genotype->phenotype transformation process CAN change for mutated genotype. # class MutationStructural < MutationAltering protected def filter :structural end end # Nodal codon-level mutation (see http://portal.acm.org/citation.cfm?id=1570215). # It assumes the source genotype has the form of the Array of numbers. # Select codons with Token#sn_altering == :nodal for mutation. # Nodal change means the length of genotype->phenotype transformation process CANNOT change for mutated genotype. # class MutationNodal < MutationAltering protected def filter :nodal end end end # Operator