genealogy.ex (1404B)
1 defmodule Utilities.Genealogy do 2 use GenServer 3 # client 4 def start_link(opts) do 5 GenServer.start_link(__MODULE__, opts, name: __MODULE__) 6 end 7 8 def add_chromosomes(chromosomes) do 9 GenServer.cast(__MODULE__, {:add_chromosomes, chromosomes}) 10 end 11 12 def add_chromosome(parent, child) do 13 GenServer.cast(__MODULE__, {:add_chromosome, parent, child}) 14 end 15 16 def add_chromosome(parent_a, parent_b, child) do 17 GenServer.cast(__MODULE__, {:add_chromosome, parent_a, parent_b, child}) 18 end 19 20 def get_tree do 21 GenServer.call(__MODULE__, :get_tree) 22 end 23 24 # server 25 def init(_opts) do 26 {:ok, Graph.new()} 27 end 28 29 def handle_cast({:add_chromosomes, chromosomes}, genealogy) do 30 {:noreply, Graph.add_vertices(genealogy, Enum.map(chromosomes, fn c -> c.genes end))} 31 end 32 33 # child is mutant of parent 34 def handle_cast({:add_chromosome, parent, child}, genealogy) do 35 new_genealogy = 36 genealogy 37 |> Graph.add_edge(parent.genes, child.genes) 38 39 {:noreply, new_genealogy} 40 end 41 42 # child is crossover of parents 43 def handle_cast({:add_chromosome, parent_a, parent_b, child}, genealogy) do 44 new_genealogy = 45 genealogy 46 |> Graph.add_edge(parent_a.genes, child.genes) 47 |> Graph.add_edge(parent_b.genes, child.genes) 48 49 {:noreply, new_genealogy} 50 end 51 52 def handle_call(:get_tree, _, genealogy) do 53 {:reply, genealogy, genealogy} 54 end 55 end