schedule.exs (1586B)
1 defmodule Schedule do 2 alias Types.Chromosome 3 @behaviour Problem 4 @max_classes 10 5 6 def genotype do 7 genes = Enum.map(1..10, fn _ -> Enum.random(0..1) end) 8 %Chromosome{genes: genes, size: @max_classes} 9 end 10 11 def fitness_function(chromosome) do 12 schedule = chromosome.genes 13 14 fitness = 15 [schedule, difficulties(), usefulness(), interest()] 16 |> Enum.zip() 17 |> Enum.map(fn {class, diff, use, int} -> 18 class * (0.3 * use + 0.4 * int - 0.3 * diff) 19 end) 20 |> Enum.sum() 21 22 credit = 23 schedule 24 |> Enum.zip(credit_hours()) 25 |> Enum.map(fn {class, credit} -> class * credit end) 26 |> Enum.sum() 27 28 if credit <= 18.0, do: fitness, else: -9999 29 end 30 31 def terminate?(_population, generation) do 32 generation == 350 33 end 34 35 defp credit_hours, do: [3.0, 3.0, 3.0, 4.5, 3.0, 3.0, 3.0, 3.0, 4.5, 1.5] 36 defp difficulties, do: [8.0, 9.0, 4.0, 3.0, 5.0, 2.0, 4.0, 2.0, 6.0, 1.0] 37 defp usefulness, do: [8.0, 9.0, 6.0, 2.0, 8.0, 9.0, 1.0, 2.0, 5.0, 1.0] 38 defp interest, do: [8.0, 8.0, 5.0, 9.0, 7.0, 2.0, 8.0, 2.0, 7.0, 10.0] 39 end 40 41 {soln, _} = 42 Genetic.run(Schedule, 43 crossover_type: &Toolbox.Crossover.single_point/3, 44 mutation_type: &Toolbox.Mutation.flip_some/2 45 ) 46 47 IO.puts("\nschedule: #{inspect(soln)}") 48 49 stats = 50 :ets.tab2list(:statistics) 51 |> Enum.sort_by(fn {gen, _stat} -> gen end) 52 |> Enum.map(fn {gen, stats} -> [gen, stats.mean_fitness] end) 53 54 {:ok, _} = 55 Gnuplot.plot( 56 [ 57 [:set, :title, "mean fitness versus generation (schedule)"], 58 [:plot, "-", :with, :points] 59 ], 60 [stats] 61 )