-
Notifications
You must be signed in to change notification settings - Fork 0
/
chromosome.rb
68 lines (58 loc) · 1.51 KB
/
chromosome.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
class Chromosome
attr_reader :bit_value, :string_value, :numeric_value, :fitness
@@bit_encoding = {
'0000' => '0',
'0001' => '1',
'0010' => '2',
'0011' => '3',
'0100' => '4',
'0101' => '5',
'0110' => '6',
'0111' => '7',
'1000' => '8',
'1001' => '9',
'1010' => '+',
'1011' => '-',
'1100' => '*',
'1101' => '/',
}
def initialize bits
raise "Bit string must be binary encoded" if bits.match(/[^01]/)
@bit_value = bits
@string_value = correct(decode @bit_value)
@numeric_value = compute @string_value
@fitness = 0.0
end
def decode bits
decoded = bits.scan(/..../).map { |gene| @@bit_encoding[gene] }.compact
end
def correct decoded
corrected = ""
looking_for = 'digit'
decoded.each do |gene|
case looking_for
when 'digit'
next unless gene.match(/[0-9]/)
corrected += gene.to_f.to_s
looking_for = 'symbol'
when 'symbol'
next unless gene.match(/[\+\-\*\/]/)
corrected += gene
looking_for = 'digit'
end
end
corrected.gsub(/\D\z/, '')
end
def compute numeric_string
return 0.0 if numeric_string.empty?
value = eval numeric_string
("%.4f" % value).to_f
end
def fitness= number
raise "Can only assign fitness a Float" unless number.instance_of? Float
@fitness = number
end
def to_s
"Bit Value: #{@bit_value}\nString Value: #{@string_value}\nNumeric Value: #{@numeric_value}\nFitness: #{@fitness}"
end
end