Guest User

Untitled

a guest
Mar 17th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.40 KB | None | 0 0
  1. #!/usr/bin/ruby
  2.  
  3. class Problem
  4. @matrix
  5. @initial
  6. attr_reader :colors, :width
  7. def initialize(width = 14, colors = 6)
  8. srand 42
  9. @colors = colors
  10. @width = 14
  11. @matrix = Array.new(@width, Array.new(@width))
  12. @matrix.map! {|line| line.map {rand(@colors)} }
  13. @initial = Marshal.load(Marshal.dump(@matrix))
  14. end
  15.  
  16. def reset
  17. @matrix = Marshal.load(Marshal.dump(@initial))
  18. end
  19.  
  20. def to_s
  21. str = ""
  22. @matrix.each do |line|
  23. str << line.inject("|"){|r,el| r + el.to_s + "|"} << "\n"
  24. end
  25. return str
  26. end
  27.  
  28. def propagate col
  29. origine = @matrix[0][0]
  30. closed = []
  31. open = [[0,0]]
  32. while !open.empty? do
  33. x,y = open.pop
  34. closed << [x,y]
  35. open << [x-1,y] if x > 0 && @matrix[x-1][y] == origine && !closed.index([x-1,y])
  36. open << [x+1,y] if x < @width-1 && @matrix[x+1][y] == origine && !closed.index([x+1,y])
  37. open << [x,y-1] if y > 0 && @matrix[x][y-1] == origine && !closed.index([x,y-1])
  38. open << [x,y+1] if y < @width-1 && @matrix[x][y+1] == origine && !closed.index([x,y+1])
  39. @matrix[x][y] = col
  40. end
  41. end
  42.  
  43. # propage toutes les couleurs et donne le score
  44. # nombre d'essais + points restant à la fin
  45. def propagate_all colors
  46. colors.each_with_index do |col,i|
  47. propagate col
  48. return i if score == @width * @width
  49. end
  50. return colors.size + (@width * @width - score)
  51. end
  52.  
  53. def eval colors
  54. mark = propagate_all colors
  55. reset
  56. return mark
  57. end
  58.  
  59. def score
  60. color = @matrix[0][0]
  61. return @matrix.inject(0){ |r,l|
  62. r + l.inject(0){|r2,e| if e == color then r2 + 1 else r2 end }
  63. }
  64. end
  65. end
  66.  
  67. class Solver
  68. attr_reader :population
  69. def initialize problem
  70. @population = []
  71. @nb = 30
  72. @x_rate = 0.1
  73. @mutation_rate = 0.1
  74. @length = 40
  75. @problem = problem
  76. 0.upto @nb-1 do
  77. @population << Array.new(@length) { rand(@problem.colors) }
  78. end
  79. end
  80.  
  81. def cross
  82. father = @population[rand(@population.size)]
  83. mother = @population[rand(@population.size)]
  84. puts "mom", father.length if father.length != @length
  85. puts "dad", mother.length if mother.length != @length
  86. cut = rand(@length)
  87. son = father.slice(0..cut-1)
  88. if son == nil
  89. print father, "(", cut
  90. end
  91. son.concat(mother.slice(cut..-1))
  92. if son.size != @length
  93. puts "WFTF?/?", son.length
  94. end
  95. @population << son
  96. son = mother.slice(0..cut-1)
  97. if son == nil || father.slice(cut..-1) == nil
  98. print father, "(", cut
  99. end
  100. son.concat(father.slice(cut..-1))
  101. end
  102.  
  103. def mutate
  104. @population[rand(@population.size)][rand(@lenght)] = rand(@problem.colors)
  105. end
  106.  
  107. def filter
  108. @population.sort! do |a,b|
  109. @problem.eval(a) <=> @problem.eval(b)
  110. end
  111. @population.slice!(@nb..-1)
  112. end
  113.  
  114. def run
  115. 10.times do
  116. cross
  117. mutate if rand < @mutation_rate
  118. end
  119. filter
  120.  
  121. @population.each{|p| puts "Score=" + (@problem.eval p).to_s }
  122. end
  123.  
  124. end
Add Comment
Please, Sign In to add comment