Simulated annealing: Difference between revisions
Content added Content deleted
Line 1,716: | Line 1,716: | ||
0 |
0 |
||
</pre> |
</pre> |
||
=={{header|Icon}}== |
|||
<lang icon>link printf |
|||
link random |
|||
procedure main () |
|||
local initial_path |
|||
local final_path |
|||
local kT, kmax |
|||
randomize() |
|||
kT := 1.0 |
|||
kmax := 1000000 |
|||
write() |
|||
write(" kT: ", kT) |
|||
write(" kmax: ", kmax) |
|||
write() |
|||
write(" k T E(s)") |
|||
write(" --------------------------") |
|||
initial_path := randomize_path_vector() |
|||
final_path := simulate_annealing (kT, kmax, initial_path) |
|||
write() |
|||
display_path (final_path) |
|||
write() |
|||
write() |
|||
printf("Final E(s): %.2r\n", path_length(final_path)) |
|||
write() |
|||
end |
|||
procedure randomize_path_vector () |
|||
local path |
|||
local i, j |
|||
path := [] |
|||
every put (path, 0 to 99) |
|||
# Shuffle elements 2 to 0. |
|||
every i := 1 to 98 do { |
|||
j := ?(99 - i) + i + 1 |
|||
path[i + 1] :=: path[j + 1] |
|||
} |
|||
return path |
|||
end |
|||
procedure distance (loc1, loc2) |
|||
local i1, j1 |
|||
local i2, j2 |
|||
local di, dj |
|||
i1 := loc1 / 10 |
|||
j1 := loc1 % 10 |
|||
i2 := loc2 / 10 |
|||
j2 := loc2 % 10 |
|||
di := i1 - i2 |
|||
dj := j1 - j2 |
|||
return sqrt ((di * di) + (dj * dj)) |
|||
end |
|||
procedure path_length (path) |
|||
local i |
|||
local len |
|||
len := distance(path[1], path[100]) |
|||
every i := 1 to 99 do len +:= distance(path[i], path[i + 1]) |
|||
return len |
|||
end |
|||
procedure find_neighbors (loc) |
|||
local c1, c2, c3, c4, c5, c6, c7, c8 |
|||
local i, j |
|||
local neighbors |
|||
c1 := c2 := c3 := c4 := c5 := c6 := c7 := c8 := 0 |
|||
i := loc / 10 |
|||
j := loc % 10 |
|||
if (i < 9) then { |
|||
c1 := (10 * (i + 1)) + j |
|||
if (j < 9) then c2 := (10 * (i + 1)) + (j + 1) |
|||
if (0 < j) then c3 := (10 * (i + 1)) + (j - 1) |
|||
} |
|||
if (0 < i) then { |
|||
c4 := (10 * (i - 1)) + j |
|||
if (j < 9) then c5 := (10 * (i - 1)) + (j + 1) |
|||
if (0 < j) then c6 := (10 * (i - 1)) + (j - 1) |
|||
} |
|||
if (j < 9) then c7 := (10 * i) + (j + 1) |
|||
if (0 < j) then c8 := (10 * i) + (j - 1) |
|||
neighbors := [] |
|||
every put(neighbors, 0 ~= (c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8)) |
|||
return neighbors |
|||
end |
|||
procedure make_neighbor_path (path) |
|||
local neighbor_path |
|||
local u, v, iu, iv, j |
|||
local neighbors |
|||
neighbor_path := copy(path) |
|||
u := ?99 |
|||
neighbors := find_neighbors(u) |
|||
v := neighbors[?(*neighbors)] |
|||
j := 2 |
|||
iu := 0 |
|||
iv := 0 |
|||
while iu = 0 | iv = 0 do { |
|||
if neighbor_path[j] = u then { |
|||
iu := j |
|||
} else if neighbor_path[j] = v then { |
|||
iv := j |
|||
} |
|||
j +:= 1 |
|||
} |
|||
neighbor_path[iu] := v |
|||
neighbor_path[iv] := u |
|||
return neighbor_path |
|||
end |
|||
procedure temperature (kT, kmax, k) |
|||
return kT * (1.0 - (real(k) / real(kmax))) |
|||
end |
|||
procedure my_exp (x) |
|||
# Icon's exp() might bail out with an underflow error, if we are not |
|||
# careful. |
|||
return (if x < -50 then 0.0 else exp(x)) |
|||
end |
|||
procedure probability (delta_E, T) |
|||
return (if T = 0.0 then 0.0 else my_exp(-(delta_E / T))) |
|||
end |
|||
procedure show (k, T, E) |
|||
printf(" %7d %7.1r %10.2r\n", k, T, E) |
|||
return |
|||
end |
|||
procedure display_path (path) |
|||
local i |
|||
every i := 1 to 100 do { |
|||
printf("%2d ->", path[i]) |
|||
if ((i - 1) % 8) = 7 then { |
|||
write() |
|||
} else { |
|||
writes(" ") |
|||
} |
|||
} |
|||
printf("%2d", path[1]) |
|||
return |
|||
end |
|||
procedure simulate_annealing (kT, kmax, path) |
|||
local kshow |
|||
local k |
|||
local E, E_trial, T |
|||
local trial |
|||
kshow := kmax / 10 |
|||
E := path_length(path) |
|||
every k := 0 to kmax do { |
|||
T := temperature(kT, kmax, k) |
|||
if (k % kshow) = 0 then show(k, T, E) |
|||
trial := make_neighbor_path(path) |
|||
E_trial := path_length(trial) |
|||
if E_trial <= E | ?0 <= probability (E_trial - E, T) then { |
|||
path := trial |
|||
E := E_trial |
|||
} |
|||
} |
|||
return path |
|||
end</lang> |
|||
{{out}} |
|||
An example run: |
|||
<pre>$ icont -s -u simanneal-in-Icon.icn && ./simanneal-in-Icon |
|||
kT: 1.0 |
|||
kmax: 1000000 |
|||
k T E(s) |
|||
-------------------------- |
|||
0 1.0 511.67 |
|||
100000 0.9 206.16 |
|||
200000 0.8 186.68 |
|||
300000 0.7 165.92 |
|||
400000 0.6 158.49 |
|||
500000 0.5 141.76 |
|||
600000 0.4 122.53 |
|||
700000 0.3 119.47 |
|||
800000 0.2 107.56 |
|||
900000 0.1 102.89 |
|||
1000000 0.0 102.24 |
|||
0 -> 10 -> 20 -> 30 -> 31 -> 41 -> 40 -> 50 -> |
|||
60 -> 70 -> 71 -> 72 -> 62 -> 61 -> 51 -> 52 -> |
|||
53 -> 63 -> 54 -> 44 -> 45 -> 35 -> 34 -> 24 -> |
|||
25 -> 26 -> 27 -> 17 -> 7 -> 8 -> 9 -> 19 -> |
|||
29 -> 39 -> 49 -> 59 -> 69 -> 79 -> 89 -> 99 -> |
|||
98 -> 97 -> 96 -> 86 -> 76 -> 75 -> 84 -> 85 -> |
|||
95 -> 94 -> 93 -> 92 -> 91 -> 90 -> 80 -> 81 -> |
|||
82 -> 83 -> 73 -> 74 -> 64 -> 55 -> 65 -> 66 -> |
|||
56 -> 46 -> 36 -> 37 -> 47 -> 57 -> 67 -> 77 -> |
|||
87 -> 88 -> 78 -> 68 -> 58 -> 48 -> 38 -> 28 -> |
|||
18 -> 16 -> 6 -> 5 -> 15 -> 14 -> 4 -> 3 -> |
|||
2 -> 12 -> 13 -> 23 -> 33 -> 43 -> 42 -> 32 -> |
|||
22 -> 21 -> 11 -> 1 -> 0 |
|||
Final E(s): 102.24 |
|||
</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |