Genetic Algorith Application: Optimization
7
SCoon
This snippet illustrates using Genetic Algorithm for the hardware optimization.
class Device
attr_reader :weight, :cost, :lifetime
def initialize(cost, lifetime, weight)
@cost = cost
@lifetime = lifetime
@weight = weight
end
def to_s
"#{@cost}:#{lifetime}:#{weight}"
end
end
class PowerSource < Device
attr_reader :power
def initialize(cost, lifetime, weight, power, kind)
super(cost, lifetime, weight)
@power = power
@kind = kind
end
def to_s
"#{@kind}%#{super.to_s}->#{@power}"
end
end
class Gear < Device
def initialize(cost, lifetime, weight, loSpeed, hiSpeed, minPower, optimalPower, kind)
super(cost, lifetime, weight)
@loSpeed = loSpeed
@hiSpeed = hiSpeed
@minPower = minPower
@optimalPower = optimalPower
@kind = kind
end
def speed(power)
return @hiSpeed if power >= @optimalPower
return @loSpeed if power >= @minPower
return 0
end
def to_s
"#{@kind}%#{super.to_s}<#{@loSpeed}-#{@hiSpeed}>:<#{@minPower}-#{@optimalPower}>"
end
end
class Instrument < Device
def initialize(count)
super(count * 50, 3000, count * 20)
@count = count
end
def required_power
2 * @count
end
def value(availablePower)
return @count * 1000 if required_power < availablePower
return 0
end
def consume_power(availablePower)
if availablePower > required_power
availablePower - required_power
else
0
end
end
def to_s
"#{@count}Instr%#{super.to_s}"
end
end
# Abstract Mars Explorer hardware configuration
class Explorer
def initialize(dna)
@dna = dna
@powerSource = buildPowerSource(next_dna_fragment(2))
@gear = buildGear(next_dna_fragment(2))
@instruments = buildInstruments(next_dna_fragment(2))
end
def value
lifetime = [ @powerSource.lifetime, @gear.lifetime, @instruments.lifetime]
power = @powerSource.power
speed = @gear.speed(@instruments.consume_power(power))
distance = speed * lifetime.min
return distance * @instruments.value(power)
end
def buildPowerSource(fragment)
case fragment
when 0b00
PowerSource.new(100, 1000, 100, 20, 'Solar')
when 0b01
PowerSource.new( 10, 400, 400, 60, 'Chemical')
when 0b10
PowerSource.new(700, 700, 20, 10, 'Bioelectric')
when 0b11
PowerSource.new(900, 3000, 600, 50, 'Atomic')
else
raise "Internal error"
end
end
def buildGear(fragment)
case fragment
when 0b00
Gear.new(30, 1000, 20, 100, 200, 10, 20, 'wheels')
when 0b01
Gear.new(60, 1000, 50, 100, 200, 10, 20, 'tracks')
when 0b10
Gear.new(90, 50, 30, 500, 900, 40, 50, 'aerial')
when 0b11
Gear.new(80, 700, 60, 100, 300, 20, 30, 'walking')
else
raise "Internal error"
end
end
def buildInstruments(fragment)
count = 1 + fragment
Instrument.new count
end
def next_dna_fragment(bits)
fragment = (@dna & ((1 << bits) - 1))
@dna = @dna >> bits
return fragment
end
def to_s
"[Explorer #{@powerSource} #{@gear} #{@instruments}]"
end
end
seed = Generation.new(10, 7, 1000000,
proc { |dna|
explorer = Explorer.new(dna)
explorer.value
},
proc { |dna1, dna2|
len = 6
dna = combine_random_bits(dna1, dna2, len)
dna = mutate_random_bits(dna, len) if rand(10) == 1
return dna
})
while seed.has_more_space
seed.add Individual.new(rand(0b1000000))
end
universe = Universe.new(seed)
universe.run 100
best = universe.best
puts "Best indivdual: #{best}"
explorer = Explorer.new(best.dna)
puts "Optimal hardware configuration: #{explorer} -> #{explorer.value}"
attr_reader :weight, :cost, :lifetime
def initialize(cost, lifetime, weight)
@cost = cost
@lifetime = lifetime
@weight = weight
end
def to_s
"#{@cost}:#{lifetime}:#{weight}"
end
end
class PowerSource < Device
attr_reader :power
def initialize(cost, lifetime, weight, power, kind)
super(cost, lifetime, weight)
@power = power
@kind = kind
end
def to_s
"#{@kind}%#{super.to_s}->#{@power}"
end
end
class Gear < Device
def initialize(cost, lifetime, weight, loSpeed, hiSpeed, minPower, optimalPower, kind)
super(cost, lifetime, weight)
@loSpeed = loSpeed
@hiSpeed = hiSpeed
@minPower = minPower
@optimalPower = optimalPower
@kind = kind
end
def speed(power)
return @hiSpeed if power >= @optimalPower
return @loSpeed if power >= @minPower
return 0
end
def to_s
"#{@kind}%#{super.to_s}<#{@loSpeed}-#{@hiSpeed}>:<#{@minPower}-#{@optimalPower}>"
end
end
class Instrument < Device
def initialize(count)
super(count * 50, 3000, count * 20)
@count = count
end
def required_power
2 * @count
end
def value(availablePower)
return @count * 1000 if required_power < availablePower
return 0
end
def consume_power(availablePower)
if availablePower > required_power
availablePower - required_power
else
0
end
end
def to_s
"#{@count}Instr%#{super.to_s}"
end
end
# Abstract Mars Explorer hardware configuration
class Explorer
def initialize(dna)
@dna = dna
@powerSource = buildPowerSource(next_dna_fragment(2))
@gear = buildGear(next_dna_fragment(2))
@instruments = buildInstruments(next_dna_fragment(2))
end
def value
lifetime = [ @powerSource.lifetime, @gear.lifetime, @instruments.lifetime]
power = @powerSource.power
speed = @gear.speed(@instruments.consume_power(power))
distance = speed * lifetime.min
return distance * @instruments.value(power)
end
def buildPowerSource(fragment)
case fragment
when 0b00
PowerSource.new(100, 1000, 100, 20, 'Solar')
when 0b01
PowerSource.new( 10, 400, 400, 60, 'Chemical')
when 0b10
PowerSource.new(700, 700, 20, 10, 'Bioelectric')
when 0b11
PowerSource.new(900, 3000, 600, 50, 'Atomic')
else
raise "Internal error"
end
end
def buildGear(fragment)
case fragment
when 0b00
Gear.new(30, 1000, 20, 100, 200, 10, 20, 'wheels')
when 0b01
Gear.new(60, 1000, 50, 100, 200, 10, 20, 'tracks')
when 0b10
Gear.new(90, 50, 30, 500, 900, 40, 50, 'aerial')
when 0b11
Gear.new(80, 700, 60, 100, 300, 20, 30, 'walking')
else
raise "Internal error"
end
end
def buildInstruments(fragment)
count = 1 + fragment
Instrument.new count
end
def next_dna_fragment(bits)
fragment = (@dna & ((1 << bits) - 1))
@dna = @dna >> bits
return fragment
end
def to_s
"[Explorer #{@powerSource} #{@gear} #{@instruments}]"
end
end
seed = Generation.new(10, 7, 1000000,
proc { |dna|
explorer = Explorer.new(dna)
explorer.value
},
proc { |dna1, dna2|
len = 6
dna = combine_random_bits(dna1, dna2, len)
dna = mutate_random_bits(dna, len) if rand(10) == 1
return dna
})
while seed.has_more_space
seed.add Individual.new(rand(0b1000000))
end
universe = Universe.new(seed)
universe.run 100
best = universe.best
puts "Best indivdual: #{best}"
explorer = Explorer.new(best.dna)
puts "Optimal hardware configuration: #{explorer} -> #{explorer.value}"






There are currently no comments for this snippet.