milardovich

Evolutional Algorithms DRAFT

Sep 18th, 2013
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 4.73 KB | None | 0 0
  1. #################################################################################################
  2. #                                               #
  3. # This is a really simple framework for solving evolutional algorithms              #
  4. # This script was made for academic-only usage. You shouldn't use it on production evironments  #
  5. # because most things here are experimental.                            #
  6. # Author: Sergio Milardovich <[email protected]>                 #
  7. # Licence: GNU/GPL (http://www.gnu.org/licenses/old-licenses/gpl-2.0.html)          #
  8. # THIS PROGRAM IS FREE SOFTWARE.                                #
  9. #                                               #
  10. #################################################################################################
  11. class Genetics
  12.     attr_reader :iterations, :population, :population_count, :obj_sum
  13.  
  14.     def initialize
  15.  
  16.         # This variable works just as a buffer. It is used in the roulette function
  17.         @buffer = []
  18.  
  19.         # Number of individuals
  20.         @population_count = 50
  21.         # Lenght of every individual
  22.         @population_lenght = 23
  23.  
  24.         @population = []
  25.         # In this array you should put the values which an individual can take (by default is 0,1)
  26.         @population_dictionary = [0,1]
  27.         # This array contains the probability of each element to be chosen
  28.         @population_obj_rate = []
  29.  
  30.         # Mutation probability
  31.         @mutation_rate = 0.05
  32.         @mutation_type = "inversion"
  33.  
  34.         # Crossover probability
  35.         @crossover_rate = 0.75
  36.         @crossover_type = "one-cut"
  37.  
  38.         @obj_const = (2.0**30)-1
  39.         @obj_sum = 0.0
  40.  
  41.         # Eltisim function
  42.         @elitism = false
  43.         # Number of elements passed by elitism
  44.         @elitism_count = 0
  45.  
  46.         # Tournament function
  47.         @tournament = false
  48.         # Number of participants
  49.         @tournament_participants = 0
  50.  
  51.         @selection_method = "roulette"
  52.  
  53.         @iterations = 200
  54.  
  55.  
  56.     end
  57.  
  58.     def generatePopulation
  59.         @population_count.times {
  60.             |i|
  61.             @population_lenght.times{
  62.                 | k |
  63.                 unless @population[i]
  64.                     @population[i] = [@population_dictionary[rand(@population_dictionary.length)]]
  65.                 else
  66.                     @population[i] << @population_dictionary[rand(@population_dictionary.length)]
  67.                 end
  68.             }
  69.         }
  70.         self.makeObjRateArray
  71.     end
  72.  
  73.     def doCrossover(index,start,c_end)
  74.         buffer = @population[index].clone
  75.         start.upto(c_end){
  76.             |i|
  77.             @buffer[index][i] = @buffer[index+1][i]
  78.             @buffer[index+1][i] = buffer[i]
  79.         }
  80.     end
  81.  
  82.     def checkMutationByInversion(index)
  83.         @population_lenght.times{
  84.             | i |
  85.             if rand(0.0..1.0) <= @mutation_rate then
  86.                 self.doMutationByInversion(index,i)
  87.             end
  88.         }
  89.     end
  90.     def doMutationByInversion(index,chromosome)
  91.         if @population_dictionary.count == 2 then
  92.             if @population[index][chromosome] == @population_dictionary[0] then
  93.                 @population[index][chromosome] = @population_dictionary[1]
  94.             else
  95.                 @population[index][chromosome] = @population_dictionary[0]
  96.             end
  97.         end
  98.     end
  99.  
  100.     def getObjFunction(index)
  101.         return (@population[index].join().to_i(2)/@obj_const)**2
  102.     end
  103.  
  104.     def getObjSum()
  105.         @obj_sum = 0
  106.         @population_count.times{
  107.             |i|
  108.             @obj_sum = @obj_sum+self.getObjFunction(i)
  109.         }
  110.         return @obj_sum
  111.     end
  112.  
  113.     def checkObjSum()
  114.         self.getObjSum()
  115.         check = 0
  116.         @population_count.times{
  117.             | i |
  118.             check = check + (self.getObjFunction(i)/@obj_sum)
  119.         }
  120.         return check
  121.     end
  122.  
  123.     def makeObjRateArray()
  124.         self.getObjSum()
  125.         @population_count.times{
  126.             | i |
  127.             @population_obj_rate[i] = [i,(self.getObjFunction(i)/@obj_sum)]
  128.         }
  129.     end
  130.  
  131.     def findMaxObj()
  132.         max = 0
  133.         @population_count.times{
  134.             | i |
  135.             if self.getObjFunction(i) >= self.getObjFunction(max) then
  136.                 max = i
  137.             end
  138.         }
  139.         return self.getObjFunction(max)
  140.     end
  141.  
  142.     def findMaxFitness()
  143.         return self.findMaxObj()/@obj_sum
  144.     end
  145.  
  146.     def roulette
  147.         self.getObjSum()
  148.         @buffer = @population.clone
  149.         # This small script will choose a new element using the probabilities from the array @population_obj_rate
  150.         @population_count.times{
  151.             | i |
  152.             target = rand
  153.             new_element = @population_obj_rate.find { |x, weight| target -= weight; target < 0 }.first
  154.             @buffer[i] = @population[new_element].clone
  155.  
  156.             case @mutation_type
  157.                 when "inversion"
  158.                     self.checkMutationByInversion(i)
  159.             end        
  160.  
  161.         }
  162.  
  163.         ((@population_count)/2).times{
  164.             | k |
  165.             if rand(0.0..1.0) <= @crossover_rate then
  166.                 case @crossover_type
  167.                     when "one-cut"
  168.                         self.doCrossover(k*2,rand(@population_lenght-1),@population_lenght)
  169.                     when "two-cuts"
  170.                         c_start = rand(@population_lenght-1)
  171.                         self.doCrossover(k*2,c_start,rand(c_start,@population_lenght))
  172.                 end
  173.             end
  174.         }
  175.  
  176.         #if @elitism == true then
  177.         #   self.elitism()
  178.         #end
  179.         @population = @buffer.clone
  180.         self.makeObjRateArray()
  181.     end
  182.  
  183.     def selectPopulation
  184.         case @selection_method
  185.             when "roulette"
  186.                 self.roulette
  187.         end
  188.     end
  189.  
  190.     def doElitism
  191.         bestElements = @population.map {|bin_str| bin_str.join().to_i(2)}.sort.last 2
  192.        
  193.     end
  194.  
  195.  
  196. #   def runTest
  197. end
Advertisement
Add Comment
Please, Sign In to add comment