Class: AntTsp::AntTsp
- Inherits:
-
Object
- Object
- AntTsp::AntTsp
- Defined in:
- lib/ant_tsp.rb
Instance Method Summary collapse
-
#cost(sh, cities) ⇒ Object
cost, of the tour.
-
#decay_pheromone(pheromone, decay_factor) ⇒ Object
decay, pheromone.
-
#euc_2d(c1, c2) ⇒ Object
distance, between two cities.
-
#get_choices(cities, last_city, skip, pheromone, c_heur, c_hist) ⇒ Object
choices, get them.
-
#search(cities, max_it, num_ants, decay_factor, c_heur, c_hist) ⇒ Object
search.
-
#select_next_city(choices) ⇒ Object
next city.
-
#setup_phero_matrix(num_cities, naive_score) ⇒ Object
setup, pheromone matrix.
-
#shake(cities) ⇒ Object
shake, cities.
-
#stepwise_const(cities, phero, c_heur, c_hist) ⇒ Object
next city, add them up.
-
#update_pheromone(pheromone, solutions) ⇒ Object
update, pheromone.
Instance Method Details
#cost(sh, cities) ⇒ Object
cost, of the tour
11 12 13 14 15 16 17 18 |
# File 'lib/ant_tsp.rb', line 11 def cost(sh, cities) distance = 0 sh.each_with_index do |c1, i| c2 = (i == (sh.size - 1)) ? sh[0] : sh[i + 1] distance += euc_2d(cities[c1], cities[c2]) end distance end |
#decay_pheromone(pheromone, decay_factor) ⇒ Object
decay, pheromone
76 77 78 79 80 81 82 |
# File 'lib/ant_tsp.rb', line 76 def decay_pheromone(pheromone, decay_factor) pheromone.each do |array| array.each_with_index do |p, i| array[i] = (1.0 - decay_factor) * p end end end |
#euc_2d(c1, c2) ⇒ Object
distance, between two cities
6 7 8 |
# File 'lib/ant_tsp.rb', line 6 def euc_2d(c1, c2) Math.sqrt((c1[0] - c2[0]) ** 2.0 + (c1[1] - c2[1]) ** 2.0).round end |
#get_choices(cities, last_city, skip, pheromone, c_heur, c_hist) ⇒ Object
choices, get them
37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/ant_tsp.rb', line 37 def get_choices(cities, last_city, skip, pheromone, c_heur, c_hist) choices = [] cities.each_with_index do |position, i| next if skip.include?(i) prob = {:city => i} prob[:history] = pheromone[last_city][i] ** c_hist prob[:distance] = euc_2d(cities[last_city], position) prob[:heuristic] = (1.0 / prob[:distance]) ** c_heur prob[:prob] = prob[:history] * prob[:heuristic] choices << prob end choices end |
#search(cities, max_it, num_ants, decay_factor, c_heur, c_hist) ⇒ Object
search
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/ant_tsp.rb', line 96 def search(cities, max_it, num_ants, decay_factor, c_heur, c_hist) best = {:vector => shake(cities)} best[:cost] = cost(best[:vector], cities) pheromone = setup_phero_matrix(cities.size, best[:cost]) max_it.times do |iter| solutions = [] num_ants.times do candidate = {} # +++ get tour candidate[:vector] = stepwise_const(cities, pheromone, c_heur, c_hist) candidate[:cost] = cost(candidate[:vector], cities) best = candidate if candidate[:cost] < best[:cost] solutions << candidate end # +++ decay phero decay_pheromone(pheromone, decay_factor) # +++ update phero update_pheromone(pheromone, solutions) puts " > iteration #{(iter + 1)}, best #{best[:cost]}" end best end |
#select_next_city(choices) ⇒ Object
next city
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/ant_tsp.rb', line 52 def select_next_city(choices) sum = choices.inject(0.0) {|sum, element| sum + element[:prob]} return choices[rand(choices.size)][:city] if sum == 0.0 v = rand() choices.each_with_index do |choice, i| v -= (choice[:prob] / sum) return choice[:city] if v <= 0.0 end return choices.last[:city] end |
#setup_phero_matrix(num_cities, naive_score) ⇒ Object
setup, pheromone matrix
31 32 33 34 |
# File 'lib/ant_tsp.rb', line 31 def setup_phero_matrix(num_cities, naive_score) v = num_cities.to_f / naive_score return Array.new(num_cities){|i| Array.new(num_cities, v)} end |
#shake(cities) ⇒ Object
shake, cities
21 22 23 24 25 26 27 28 |
# File 'lib/ant_tsp.rb', line 21 def shake(cities) sh = Array.new(cities.size){|i| i} sh.each_index do |i| r = rand(sh.size - i) + i sh[r], sh[i] = sh[i], sh[r] end sh end |
#stepwise_const(cities, phero, c_heur, c_hist) ⇒ Object
next city, add them up
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/ant_tsp.rb', line 64 def stepwise_const(cities, phero, c_heur, c_hist) shake = [] shake << rand(cities.size) begin choices = get_choices(cities, shake.last, shake, phero, c_heur, c_hist) next_city = select_next_city(choices) shake << next_city end until shake.size == cities.size shake end |
#update_pheromone(pheromone, solutions) ⇒ Object
update, pheromone
85 86 87 88 89 90 91 92 93 |
# File 'lib/ant_tsp.rb', line 85 def update_pheromone(pheromone, solutions) solutions.each do |other| other[:vector].each_with_index do |x, i| y = (i == (other[:vector].size - 1)) ? other[:vector][0] : other[:vector][i + 1] pheromone[x][y] += (1.0 / other[:cost]) pheromone[y][x] += (1.0 / other[:cost]) end end end |