Genetic Algorith Application: Optimization





7
Date Submitted Thu. Nov. 2nd, 2006 5:08 AM
Revision 1 of 1
Scripter SCoon
Tags Algorithm | Genetic | optimization | Random | Ruby
Comments 0 comments
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( 10400, 400, 60, 'Chemical')
    when 0b10
      PowerSource.new(70070020, 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(905030, 500, 900, 40, 50, 'aerial')
    when 0b11
      Gear.new(80, 70060, 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}"
 

Vladislav Zlobin

Comments

There are currently no comments for this snippet.

Voting