How to resolve the algorithm Evolutionary algorithm step by step in the Ruby programming language
How to resolve the algorithm Evolutionary algorithm step by step in the Ruby programming language
Table of Contents
Problem Statement
Starting with:
Note: to aid comparison, try and ensure the variables and functions mentioned in the task description appear in solutions
A cursory examination of a few of the solutions reveals that the instructions have not been followed rigorously in some solutions. Specifically, Note that some of the the solutions given retain characters in the mutated string that are correct in the target string. However, the instruction above does not state to retain any of the characters while performing the mutation. Although some may believe to do so is implied from the use of "converges" Strictly speaking, the new parent should be selected from the new pool of mutations, and then the new parent used to generate the next set of mutations with parent characters getting retained only by not being mutated. It then becomes possible that the new set of mutations has no member that is fitter than the parent! As illustration of this error, the code for 8th has the following remark. NOTE: this has been changed, the 8th version is completely random now Clearly, this algo will be applying the mutation function only to the parent characters that don't match to the target characters! To ensure that the new parent is never less fit than the prior parent, both the parent and all of the latest mutations are subjected to the fitness test to select the next parent.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Evolutionary algorithm step by step in the Ruby programming language
This Ruby program uses a genetic algorithm to evolve a string into a target string. It simulates the process of natural selection, where individuals with higher fitness are more likely to survive and reproduce.
Variables:
@target
: The target string to evolve towards.Charset
: A list of characters that can be used in the evolved string.COPIES
: The number of copies of each parent to create during mutation.
Functions:
random_char
: Randomly selects a character from theCharset
.fitness
: Calculates the fitness of a candidate string. The fitness is based on how close the candidate is to the target string.mutation_rate
: Calculates the mutation rate for a candidate string. The mutation rate is higher for strings with lower fitness.mutate
: Mutates a parent string by randomly changing some of its characters.log
: Logs the progress of the genetic algorithm, including the iteration number, mutation rate, fitness, and the current candidate string.
Algorithm:
- Initialize a random parent string.
- Calculate the fitness of the parent string.
- Calculate the mutation rate for the parent string.
- Create
COPIES
copies of the parent string and mutate each copy. - Select the copy with the highest fitness as the new parent string.
- Repeat steps 2-5 until the parent string matches the target string.
Output:
The program logs the progress of the genetic algorithm, showing the following information for each iteration:
- Iteration number
- Mutation rate
- Fitness of the current parent string
- The current parent string
Once the parent string matches the target string, the program logs the final iteration number, mutation rate, fitness, and the evolved string.
Source code in the ruby programming language
@target = "METHINKS IT IS LIKE A WEASEL"
Charset = [" ", *"A".."Z"]
COPIES = 100
def random_char; Charset.sample end
def fitness(candidate)
sum = 0
candidate.chars.zip(@target.chars) {|x,y| sum += (x[0].ord - y[0].ord).abs}
100.0 * Math.exp(Float(sum) / -10.0)
end
def mutation_rate(candidate)
1.0 - Math.exp( -(100.0 - fitness(candidate)) / 400.0)
end
def mutate(parent, rate)
parent.each_char.collect {|ch| rand <= rate ? random_char : ch}.join
end
def log(iteration, rate, parent)
puts "%4d %.2f %5.1f %s" % [iteration, rate, fitness(parent), parent]
end
iteration = 0
parent = Array.new(@target.length) {random_char}.join
prev = ""
while parent != @target
iteration += 1
rate = mutation_rate(parent)
if prev != parent
log(iteration, rate, parent)
prev = parent
end
copies = [parent] + Array.new(COPIES) {mutate(parent, rate)}
parent = copies.max_by {|c| fitness(c)}
end
log(iteration, rate, parent)
You may also check:How to resolve the algorithm Execute SNUSP step by step in the Nim programming language
You may also check:How to resolve the algorithm CUSIP step by step in the Caché ObjectScript programming language
You may also check:How to resolve the algorithm String interpolation (included) step by step in the Elixir programming language
You may also check:How to resolve the algorithm Increasing gaps between consecutive Niven numbers step by step in the C programming language
You may also check:How to resolve the algorithm Merge and aggregate datasets step by step in the Raku programming language