1
|
|
|
# Author: Simon Blanke |
2
|
|
|
# Email: [email protected] |
3
|
|
|
# License: MIT License |
4
|
|
|
|
5
|
|
|
import numpy as np |
6
|
|
|
|
7
|
|
|
from ..local_opt import HillClimbingOptimizer |
8
|
|
|
|
9
|
|
|
|
10
|
|
|
def roation(n_dim, vector): |
11
|
|
|
if n_dim == 1: |
12
|
|
|
return -1 # not sure about that |
13
|
|
|
|
14
|
|
|
I = np.identity(n_dim - 1) |
15
|
|
|
R = np.pad(I, ((1, 0), (0, 1)), constant_values=(0, 0)) |
16
|
|
|
R[0, n_dim - 1] = -1 |
17
|
|
|
|
18
|
|
|
return np.matmul(R, vector) |
19
|
|
|
|
20
|
|
|
|
21
|
|
|
class Spiral(HillClimbingOptimizer): |
22
|
|
|
def __init__(self, *args, **kwargs): |
23
|
|
|
super().__init__(*args, **kwargs) |
24
|
|
|
self.global_pos_best = None |
25
|
|
|
|
26
|
|
|
self.decay_rate = None |
27
|
|
|
self.decay_factor = 3 |
28
|
|
|
|
29
|
|
|
def _move_part(self, pos, velo): |
30
|
|
|
pos_new = (pos + velo).astype(int) |
31
|
|
|
# limit movement |
32
|
|
|
n_zeros = [0] * len(self.conv.max_positions) |
33
|
|
|
|
34
|
|
|
return np.clip(pos_new, n_zeros, self.conv.max_positions) |
35
|
|
|
|
36
|
|
|
@HillClimbingOptimizer.track_new_pos |
37
|
|
|
@HillClimbingOptimizer.random_iteration |
38
|
|
|
def move_spiral(self, center_pos): |
39
|
|
|
self.decay_factor *= self.decay_rate |
40
|
|
|
step_rate = self.decay_factor * self.conv.max_positions / 1000 |
41
|
|
|
|
42
|
|
|
A = center_pos |
43
|
|
|
rot = roation(len(center_pos), np.subtract(self.pos_current, center_pos)) |
44
|
|
|
|
45
|
|
|
B = np.multiply(step_rate, rot) |
46
|
|
|
new_pos = A + B |
47
|
|
|
|
48
|
|
|
n_zeros = [0] * len(self.conv.max_positions) |
49
|
|
|
pos_new = np.clip(new_pos, n_zeros, self.conv.max_positions).astype(int) |
50
|
|
|
return pos_new |
51
|
|
|
|
52
|
|
|
@HillClimbingOptimizer.track_new_score |
53
|
|
|
def evaluate(self, score_new): |
54
|
|
|
self._new2current() |
55
|
|
|
self._evaluate_current2best() |
56
|
|
|
|