Logo
Section 1 / 4

可视化虎的演化谱系

学习如何可视化您老虎演化框架中的谱系关系。

导入

可视化虎的演化谱系

学习如何可视化您老虎演化框架中的谱系关系。

老虎进化框架

在上一章中,我们已将一些基本的追踪机制完整集成到遗传算法框架中。这些机制使我们能够追踪年龄、适应度以及遗传算法的几乎所有其他方面。我们还创建了一个用于追踪进化谱系的机制。

记住:谱系是整个进化过程的家族树。

在本课中,我们将学习如何导出谱系树,并使用第三方工具进行可视化。首先,打开 tiger_simulation.exs 文件。目前它的内容如下:

1defmodule TigerSimulation do 2 @behaviour Problem 3 alias Types.Chromosome 4 5 @impl true 6 def genotype do 7 genes = for _ <- 1..8, do: Enum.random(0..1) 8 %Chromosome{genes: genes, size: 8} 9 end 10 11 @impl true 12 def fitness_function(chromosome) do 13 tropic_scores = [0.0, 3.0, 2.0, 1.0, 0.5, 1.0, -1.0, 0.0] 14 tundra_scores = [1.0, 3.0, -2.0, -1.0, 0.5, 2.0, 1.0, 0.0] 15 traits = chromosome.genes 16 17 traits 18 |> Enum.zip(tundra_scores) 19 |> Enum.map(fn {t, s} -> t*s end) 20 |> Enum.sum() 21 end 22 23 @impl true 24 def terminate?(_population, generation), do: generation == 1000 25 26 def average_tiger(population) do 27 genes = Enum.map(population, & &1.genes) 28 fitnesses = Enum.map(population, & &1.fitness) 29 ages = Enum.map(population, & &1.age) 30 num_tigers = length(population) 31 32 avg_fitness = Enum.sum(fitnesses) / num_tigers 33 avg_age = Enum.sum(ages) / num_tigers 34 avg_genes = 35 genes 36 |> Enum.zip() 37 |> Enum.map(& Enum.sum(Tuple.to_list(&1)) / num_tigers) 38 39 %Chromosome{genes: avg_genes, age: avg_age, fitness: avg_fitness} 40 end 41end 42 43tiger = Genetic.run(TigerSimulation, 44 population_size: 20, 45 selection_rate: 0.9, 46 mutation_rate: 0.1, 47 statistics: %{average_tiger: &TigerSimulation.average_tiger/1}) 48 49IO.write("\n") 50IO.inspect(tiger) 51genealogy = Utilities.Genealogy.get_tree() 52 53IO.inspect(Graph.vertices(genealogy))

我们需要首先调整终止条件。目前,算法设置为在运行 1000 代后终止(如上述代码第 24 行所示)。为了本章的目的,我们将大幅减少这个数值,以便更轻松地可视化谱系。在此示例中,我们将代数减少到 1,种群规模减少到 2:

1defmodule TigerSimulation do 2 # ... 3 def terminate?(_population, generation), do: generation == 1 4 # ... 5end 6 7tiger = Genetic.run(TigerSimulation, 8 population_size: 2, 9 selection_rate: 1.0, 10 mutation_rate: 0.0, 11 statistics: %{average_tiger: &TigerSimulation.average_tiger/1})

接下来,我们需要将谱系树导出为 DOT 文件,如下所示:

1genealogy = Utilities.Genealogy.get_tree() 2 3{:ok, dot} = Graph.Serializers.DOT.serialize(genealogy) 4{:ok, dotfile} = File.open("tiger_simulation.dot", [:write]) 5:ok = IO.binwrite(dotfile, dot) 6:ok = File.close(dotfile)

在这段代码中,我们使用 libgraph API 将谱系树序列化为 DOT 格式的二进制数据。DOT 是一种标准的图结构序列化格式。然后我们创建一个新文件,并将序列化的图写入其中。

测试应用程序

我们可以运行以下应用来测试效果:

No configuration found for ID: be36387e6948034935c169da177e62ef5833bfd1cfc5c078d642d3e16b286a9f

注意:请注意,谱系本质上是从第一代的两个染色体开始并由此扩展出去的一棵树。

这种可视化方式非常有助于展示最适染色体随时间的变化过程。

追踪遗传算法

可视化基础统计