eekenpiet

eekenpiet

Genetic Algorithms in Elixir: Chapter 9/10 ebook-1.0.2 Genealogy not working well

Chapter 9/10 ebook-1.02 Genealogy not working well.

As already mentioned in one of the errata the ID of every chromosome is the same.
So plotting the tree with libgraph gives many problems.
For instance parents are not unique, they are all inserted.

I did change a few things. Nodes are now unique.
Labels are much smaller, because I changed them to fitness.
You now get a nice plot with small nodes.

This is the relevant part of genealogy.ex:

def handle_cast({:add_chromosome, parent, child}, genealogy) do
  new_genealogy =
    genealogy
    |> Graph.add_vertex(child.id, child.fitness)
    |> Graph.add_edge(parent.id, child.id)

  {:noreply, new_genealogy}
end

def handle_cast({:add_chromosome, parent_a, parent_b, child}, genealogy) do
  new_genealogy =
    genealogy
    |> Graph.add_vertex(child.id, child.fitness)
    |> Graph.add_edge(parent_a.id, child.id)
    |> Graph.add_edge(parent_b.id, child.id)

  {:noreply, new_genealogy}
end

The last part of crossover().
ID’s are now unique. Fitness are assigned

def crossover(population, problem, opts \\ []) do
................
................

        c1 = %Chromosome{
          c1
          | id: Base.encode16(:crypto.strong_rand_bytes(64)),
            fitness: problem.fitness_function(c1)
        }

        c2 = %Chromosome{
          c2
          | id: Base.encode16(:crypto.strong_rand_bytes(64)),
            fitness: problem.fitness_function(c2)
        }

        Utilities.Genealogy.add_chromosome(p1, p2, c1)
        Utilities.Genealogy.add_chromosome(p1, p2, c2)
        [c1 | [c2 | acc]]

and of mutation():

def mutation(population, problem, opts \\ []) do
.......
.......
      mutant = %Chromosome{
        mutant
        | id: Base.encode16(:crypto.strong_rand_bytes(64)),
          fitness: problem.fitness_function(mutant)
      }

      Utilities.Genealogy.add_chromosome(c, mutant)
      mutant

I did use the following tiger_simulation, and watch the change in genotype:

defmodule TigerSimulation do
  @behaviour Problem
  alias Types.Chromosome

 @impl true
  def genotype do
    genes = for _ <- 1..8, do: Enum.random(0..1)
    chromo = %Chromosome{genes: genes, size: 8, id: Base.encode16(:crypto.strong_rand_bytes(64))}
    fitness = fitness_function(chromo)
    %Chromosome{chromo | fitness: fitness}
  end

  @impl true
  def fitness_function(chromosome) do
    tropic_scores = [0.0, 3.0, 2.0, 1.0, 0.5, 1.0, -1.0, 0.0]
    #    tundra_scores = [1.0, 3.0, -2.0, -1.0, 0.5, 2.0, 1.0, 0.0]
    traits = chromosome.genes

    traits
    |> Enum.zip(tropic_scores)
    |> Enum.map(fn {t, s} -> t * s end)
    |> Enum.sum()
  end

  @impl true
  def terminate?(_population, generation), do: generation == 10
end

_tiger =
  Genetic.run(TigerSimulation,
    population_size: 8,
    selection_rate: 0.8,
    mutation_rate: 0.1
  )

genealogy = Utilities.Genealogy.get_tree()

{:ok, dot} = Graph.Serializers.DOT.serialize(genealogy)
{:ok, dotfile} = File.open("tiger_simulation.dot", [:write]) #staat in hoofd-directory
:ok = IO.binwrite(dotfile, dot)
:ok = File.close(dotfile)

and in evolve()

 ........
 .......
 children = crossover(parents, problem, opts)
 ......
 mutants = mutation(population, problem, opts)

Tip: In Intellij Idea you have a nice plugin for .dot files: Dot plus!
If selection <1 you wil see also loose nodes. Nice!

And some other suggestions:

 def run(problem, opts \\ []) do
    population = initialize(&problem.genotype/0, opts)
    start_bestfitness = %Chromosome{hd(population) | fitness: 0.0}

    population
    |> evolve(problem, 0, start_bestfitness, bestgeneration = 0, opts)
  end
  
def evolve(population, problem, generation, bestfitness, bestgeneration, opts \\ []) do
    population = evaluate(population, &problem.fitness_function/1, opts)

    best = hd(population)
    best1 = best.fitness
    best2 = bestfitness.fitness

    bestfitness =
      if best1 > best2 do
        best
      else
        bestfitness
      end

    bestgeneration =
      if best1 > best2 do
        generation
      else
        bestgeneration
      end

    IO.inspect(best, label: "\n\ncurrent best:")
    IO.write("Generation: #{generation}")
    statistics(population, generation, opts)

    if problem.terminate?(population, generation) do
............................
.............................
    

Where Next?

Popular Pragmatic Bookshelf topics Top

cro
I am working on the “Your Turn” for chapter one and building out the restart button talked about on page 27. It recommends looking into ...
New
adamwoolhether
When trying to generate the protobuf .go file, I receive this error: Unknown flag: --go_opt libprotoc 3.12.3 MacOS 11.3.1 Googling ...
New
leonW
I ran this command after installing the sample application: $ cards add do something --owner Brian And got a file not found error: Fil...
New
jskubick
I’m running Android Studio “Arctic Fox” 2020.3.1 Patch 2, and I’m embarrassed to admit that I only made it to page 8 before running into ...
New
brunogirin
When running tox for the first time, I got the following error: ERROR: InterpreterNotFound: python3.10 I realised that I was running ...
New
oaklandgit
Hi, I completed chapter 6 but am getting the following error when running: thread 'main' panicked at 'Failed to load texture: IoError(O...
New
adamwoolhether
Is there any place where we can discuss the solutions to some of the exercises? I can figure most of them out, but am having trouble with...
New
taguniversalmachine
Hi, I am getting an error I cannot figure out on my test. I have what I think is the exact code from the book, other than I changed “us...
New
New
SlowburnAZ
Getting an error when installing the dependencies at the start of this chapter: could not compile dependency :exla, "mix compile" failed...
New

Other popular topics Top

Exadra37
Please tell us what is your preferred monitor setup for programming(not gaming) and why you have chosen it. Does your monitor have eye p...
New
PragmaticBookshelf
Rust is an exciting new programming language combining the power of C with memory safety, fearless concurrency, and productivity boosters...
New
AstonJ
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me. I think the Planck and the Preonic (o...
New
AstonJ
If you get Can't find emacs in your PATH when trying to install Doom Emacs on your Mac you… just… need to install Emacs first! :lol: bre...
New
PragmaticBookshelf
Author Spotlight Jamis Buck @jamis This month, we have the pleasure of spotlighting author Jamis Buck, who has written Mazes for Prog...
New
New
New
RobertRichards
Hair Salon Games for Girls Fun Girls Hair Saloon game is mainly developed for kids. This game allows users to select virtual avatars to ...
New
PragmaticBookshelf
Fight complexity and reclaim the original spirit of agility by learning to simplify how you develop software. The result: a more humane a...
New
CommunityNews
Open-source implementation of the classic GTA engine now running directly in your browser. Experience the reVC technology demo on DOS.Zon...
New

Sub Categories: