-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEnviroment.rb
121 lines (94 loc) · 3.02 KB
/
Enviroment.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# encoding: UTF-8
#
# Evolution.ruby
# (Konsolenanwendung in Ruby)
#
# String-Evolution in Ruby mit Kreuzung und Mutation
# erstellt von Conrad Kernrot 4-2015
# github@conradhenke.de
#
require "./Individual.rb"
# Population ist ein Lehrbeispiel zum Thema "genetische Algorithmen" in
# Analogie zur biologischen Evolution.
class Enviroment
attr_accessor :wortliste
attr_accessor :merkmal
attr_accessor :anzahl
#Genpool
Genpool = [*'0'..'9', *'a'..'z', *'A'..'Z']
#Überlebensanteil, Mutationswarscheinlichkeit (>0;<1)
SurviveQuantity = 0.5
MutationProbability = 0.25
# Startpopulation initialisieren (Konstruktor)
def initialize( optimal = "MUTANTEN", size = 100, lev=false)
@lev = lev
@space = size
@optimal = optimal
@population = Array.new(@space) do |i|
Individual.new(Genpool.sample( rand( 50)+ 1).join, Genpool, optimal, @lev)
end
end
def population
return @population
end
def populationFittness
return @population.inject(0){ |sum, el| sum + (el.rating) }.to_f / @population.length
end
def genpool
return Genpool
end
def print_configuration
puts "Gewichungen C "+WeightContent.to_s
puts "Gewichungen I "+WeightIdentical.to_s
puts "Gewichungen L "+WeightLength.to_s
puts "Überlebensanteil "+SurviveQuantity.to_s
puts "Mutationsrunden pro Mutation: "+MutationRuns.to_s
puts "Population initialisiert.\n"
end
# sortiert nach bewertung, behält die besser bewertete Hälfte der Population
def selektion
@population.sort! { |a,b| (a.rating <=> b.rating) }
@population = @population[0...(@population.length*SurviveQuantity)]
end
#kreuzung zweier Elemente
def mixIndividuals(vather, mother)
# kindlänge ist zufällig länge von vater,mutter,avg(vater,mutter),zufällig
length = [vather.gene.length, mother.gene.length,
(0.5*(vather.gene.length+mother.gene.length)).ceil,
(0.5*(vather.gene.length+mother.gene.length)).floor].sample
parentGenes = (vather.gene+mother.gene).split("")
child = ""
length.times do |i|
child+=parentGenes.sample
end
# nochmal wenn kind nicht verschieden von mutter und vater
if ((child == vather) || (child == mother))
child = mixIndividuals(vather,mother)
end
return Individual.new(child,Genpool,@optimal,@lev)
end
# kreuzung zufälliger Elemente(2) der Population, aufüllen auf alte Populationsgröße
def crossover
fromLastGen = @population.length
while(@population.length<@space)
vather = @population[0...10].sample
mother = @population[10...fromLastGen].sample
child = mixIndividuals(vather,mother)
@population.push(child)
end
end
# gesamte population mutieren
def mutate
@population.each{ |i|
probability = 1.0/MutationProbability
if((rand(probability)+1)%probability==0)
i.mutate
end
}
end
# Population anzeigen
def show
@population.sort! { |a,b| (a.rating <=> b.rating) }
puts @population.map{ |i| i.to_s}
end
end