Algorithmically 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/lib/Algorithmically.rb +1 -0
- data/lib/Algorithmically/Stochastic/guided_local_search.rb +107 -0
- data/lib/Algorithmically/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 923dab150a1c719d4578803afb1f2f00f0cefa9d
|
4
|
+
data.tar.gz: df4628866699eab63f79a99aa315dba1cc58d466
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cac3441e02e4de16906501f54904bee60c51259ba2dcff2c9dbbe14e48f52e2160a42b043b96aff8a9db53820fa4e71937db65a9fd8d043eb434c8ff9895a8e
|
7
|
+
data.tar.gz: 931ca10d22d3a4a4bbb6896a93337b0b9ac96d33ee4e3e38fbd825c360711733aebb82f2d52ac24aeb1cfec24b728ee2f0b3bb0df835852776ec5dd3ade3ddad
|
data/README.md
CHANGED
@@ -25,5 +25,9 @@ Or install it yourself as:
|
|
25
25
|
Algorithmically::RandomSearch.new(2, 50)
|
26
26
|
|
27
27
|
Algorithmically::AdaptiveRandomSearch.new(1000, 2, 0.05, 1.3, 3.0, 10, 30)
|
28
|
+
|
29
|
+
Algorithmically::HillClimbing.new(2, 1000)
|
30
|
+
|
31
|
+
Algorithmically::GuidedLocalSearch.new(150, [[565,575],[25,185],[345,750],[945,685]], 20, 0.3)
|
28
32
|
|
29
33
|
|
data/lib/Algorithmically.rb
CHANGED
@@ -0,0 +1,107 @@
|
|
1
|
+
module Stochastic
|
2
|
+
|
3
|
+
class GuidedLocalSearch
|
4
|
+
|
5
|
+
def initialize(max_iterations, berlin52, max_no_improv, lambda)
|
6
|
+
@berlin52 = berlin52
|
7
|
+
@max_iterations = max_iterations
|
8
|
+
@max_no_improv = max_no_improv
|
9
|
+
alpha = 0.3
|
10
|
+
local_search_optima = 12000.0
|
11
|
+
lambda = alpha * (local_search_optima/berlin52.size.to_f)
|
12
|
+
@lambda = lambda
|
13
|
+
best = search(@max_iterations, @berlin52, @max_no_improv, lambda)
|
14
|
+
puts "Done. Best Solution: c=#{best[:cost]}, v=#{best[:vector].inspect}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def euc_2d(c1, c2)
|
18
|
+
Math.sqrt((c1[0] - c2[0])**2.0 + (c1[1] - c2[1])**2.0).round
|
19
|
+
end
|
20
|
+
|
21
|
+
def random_permutation(cities)
|
22
|
+
perm = Array.new(cities.size) { |i| i }
|
23
|
+
perm.each_index do |i|
|
24
|
+
r = rand(perm.size-i) + i
|
25
|
+
perm[r], perm[i] = perm[i], perm[r]
|
26
|
+
end
|
27
|
+
perm
|
28
|
+
end
|
29
|
+
|
30
|
+
def stochastic_two_opt(permutation)
|
31
|
+
perm = Array.new(permutation)
|
32
|
+
c1, c2 = rand(perm.size), rand(perm.size)
|
33
|
+
exclude = [c1]
|
34
|
+
exclude << ((c1==0) ? perm.size-1 : c1-1)
|
35
|
+
exclude << ((c1==perm.size-1) ? 0 : c1+1)
|
36
|
+
c2 = rand(perm.size) while exclude.include?(c2)
|
37
|
+
c1, c2 = c2, c1 if c2 < c1
|
38
|
+
perm[c1...c2] = perm[c1...c2].reverse
|
39
|
+
perm
|
40
|
+
end
|
41
|
+
|
42
|
+
def augmented_cost(permutation, penalties, cities, lambda)
|
43
|
+
distance, augmented = 0, 0
|
44
|
+
permutation.each_with_index do |c1, i|
|
45
|
+
c2 = (i==permutation.size-1) ? permutation[0] : permutation[i+1]
|
46
|
+
c1, c2 = c2, c1 if c2 < c1
|
47
|
+
d = euc_2d(cities[c1], cities[c2])
|
48
|
+
distance += d
|
49
|
+
augmented += d + (lambda * (penalties[c1][c2]))
|
50
|
+
end
|
51
|
+
[distance, augmented]
|
52
|
+
end
|
53
|
+
|
54
|
+
def cost(cand, penalties, cities, lambda)
|
55
|
+
cost, acost = augmented_cost(cand[:vector], penalties, cities, lambda)
|
56
|
+
cand[:cost], cand[:aug_cost] = cost, acost
|
57
|
+
end
|
58
|
+
|
59
|
+
def local_search(current, cities, penalties, max_no_improv, lambda)
|
60
|
+
cost(current, penalties, cities, lambda)
|
61
|
+
count = 0
|
62
|
+
begin
|
63
|
+
candidate = {:vector => stochastic_two_opt(current[:vector])}
|
64
|
+
cost(candidate, penalties, cities, lambda)
|
65
|
+
count = (candidate[:aug_cost] < current[:aug_cost]) ? 0 : count+1
|
66
|
+
current = candidate if candidate[:aug_cost] < current[:aug_cost]
|
67
|
+
end until count >= max_no_improv
|
68
|
+
current
|
69
|
+
end
|
70
|
+
|
71
|
+
def calculate_feature_utilities(penal, cities, permutation)
|
72
|
+
utilities = Array.new(permutation.size, 0)
|
73
|
+
permutation.each_with_index do |c1, i|
|
74
|
+
c2 = (i==permutation.size-1) ? permutation[0] : permutation[i+1]
|
75
|
+
c1, c2 = c2, c1 if c2 < c1
|
76
|
+
utilities[i] = euc_2d(cities[c1], cities[c2]) / (1.0 + penal[c1][c2])
|
77
|
+
end
|
78
|
+
utilities
|
79
|
+
end
|
80
|
+
|
81
|
+
def update_penalties!(penalties, cities, permutation, utilities)
|
82
|
+
max = utilities.max()
|
83
|
+
permutation.each_with_index do |c1, i|
|
84
|
+
c2 = (i==permutation.size-1) ? permutation[0] : permutation[i+1]
|
85
|
+
c1, c2 = c2, c1 if c2 < c1
|
86
|
+
penalties[c1][c2] += 1 if utilities[i] == max
|
87
|
+
end
|
88
|
+
penalties
|
89
|
+
end
|
90
|
+
|
91
|
+
def search(max_iterations, cities, max_no_improv, lambda)
|
92
|
+
current = {:vector => random_permutation(cities)}
|
93
|
+
best = nil
|
94
|
+
penalties = Array.new(cities.size) { Array.new(cities.size, 0) }
|
95
|
+
max_iterations.times do |iter|
|
96
|
+
current=local_search(current, cities, penalties, max_no_improv, lambda)
|
97
|
+
utilities=calculate_feature_utilities(penalties, cities, current[:vector])
|
98
|
+
update_penalties!(penalties, cities, current[:vector], utilities)
|
99
|
+
best = current if best.nil? or current[:cost] < best[:cost]
|
100
|
+
puts " > iter=#{(iter+1)}, best=#{best[:cost]}, aug=#{best[:aug_cost]}"
|
101
|
+
end
|
102
|
+
best
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Algorithmically
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- popac
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- bin/setup
|
78
78
|
- lib/Algorithmically.rb
|
79
79
|
- lib/Algorithmically/Stochastic/adaptive_random_search.rb
|
80
|
+
- lib/Algorithmically/Stochastic/guided_local_search.rb
|
80
81
|
- lib/Algorithmically/Stochastic/hill_climbing.rb
|
81
82
|
- lib/Algorithmically/Stochastic/random_search.rb
|
82
83
|
- lib/Algorithmically/version.rb
|