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

GilWright
Working through the steps (checking that the Info,plist matches exactly), run the demo game and what appears is grey but does not fill th...
New
mikecargal
Title: Hands-On Rust (Chapter 11: prefab) Just played a couple of amulet-less games. With a bit of debugging, I believe that your can_p...
New
gilesdotcodes
In case this helps anyone, I’ve had issues setting up the rails source code. Here were the solutions: In Gemfile, change gem 'rails' t...
New
patoncrispy
I’m new to Rust and am using this book to learn more as well as to feed my interest in game dev. I’ve just finished the flappy dragon exa...
New
jskubick
I think I might have found a problem involving SwitchCompat, thumbTint, and trackTint. As entered, the SwitchCompat changes color to hol...
New
jskubick
I found an issue in Chapter 7 regarding android:backgroundTint vs app:backgroundTint. How to replicate: load chapter-7 from zipfile i...
New
New
hazardco
On page 78 the following code appears: &lt;%= link_to ‘Destroy’, product, class: ‘hover:underline’, method: :delete, data: { confirm...
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
tkhobbes
After some hassle, I was able to finally run bin/setup, now I have started the rails server but I get this error message right when I vis...
New

Other popular topics Top

PragmaticBookshelf
Instantly view the changes you make to an app with stateful hot reload, and define a declarative UI in the same language as the app logic...
New
PragmaticBookshelf
Machine learning can be intimidating, with its reliance on math and algorithms that most programmers don't encounter in their regular wor...
New
PragmaticBookshelf
Rust is an exciting new programming language combining the power of C with memory safety, fearless concurrency, and productivity boosters...
New
Exadra37
Oh just spent so much time on this to discover now that RancherOS is in end of life but Rancher is refusing to mark the Github repo as su...
New
PragmaticBookshelf
Use WebRTC to build web applications that stream media and data in real time directly from one user to another, all in the browser. ...
New
Help
I am trying to crate a game for the Nintendo switch, I wanted to use Java as I am comfortable with that programming language. Can you use...
New
AstonJ
If you want a quick and easy way to block any website on your Mac using Little Snitch simply… File &gt; New Rule: And select Deny, O...
New
AnfaengerAlex
Hello, I’m a beginner in Android development and I’m facing an issue with my project setup. In my build.gradle.kts file, I have the foll...
New
PragmaticBookshelf
Escape callback hell and ship fast, clean code that reads as smoothly as it runs. Squash bugs and stamp out memory leaks with an intuitiv...
New
Fl4m3Ph03n1x
Background Lately I am in a quest to find a good quality TTS ai generation tool to run locally in order to create audio for some videos I...
New

Sub Categories: