Passed
Push — master ( 87b46e...a9e71c )
by Simon
01:42
created

HillClimbingOptimizer.move_climb()   A

Complexity

Conditions 3

Size

Total Lines 9
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nop 3
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
import numpy as np
6
7
from ..base_optimizer import BaseOptimizer
8
9
from numpy.random import normal, laplace, logistic, gumbel
10
11
dist_dict = {
12
    "normal": normal,
13
    "laplace": laplace,
14
    "logistic": logistic,
15
    "gumbel": gumbel,
16
}
17
18
19
def max_list_idx(list_):
20
    max_item = max(list_)
21
    max_item_idx = [i for i, j in enumerate(list_) if j == max_item]
22
    return max_item_idx[-1:][0]
23
24
25
class HillClimbingOptimizer(BaseOptimizer):
26
    name = "Hill Climbing"
27
    _name_ = "hill_climbing"
28
    __name__ = "HillClimbingOptimizer"
29
30
    optimizer_type = "local"
31
    computationally_expensive = False
32
33
    def __init__(
34
        self, *args, epsilon=0.03, distribution="normal", n_neighbours=3, **kwargs
35
    ):
36
        super().__init__(*args, **kwargs)
37
        self.epsilon = epsilon
38
        self.distribution = distribution
39
        self.n_neighbours = n_neighbours
40
41
    def move_climb(self, pos, epsilon_mod=1):
42
        while True:
43
            sigma = self.conv.max_positions * self.epsilon * epsilon_mod
44
            pos_normal = dist_dict[self.distribution](pos, sigma, pos.shape)
45
            pos = self.conv2pos(pos_normal)
46
47
            if self.conv.not_in_constraint(pos):
48
                return pos
49
            epsilon_mod *= 1.01
50
51
    @BaseOptimizer.track_new_pos
52
    @BaseOptimizer.random_iteration
53
    def iterate(self):
54
        return self.move_climb(self.pos_current)
55
56
    @BaseOptimizer.track_new_score
57
    def evaluate(self, score_new):
58
        BaseOptimizer.evaluate(self, score_new)
59
        if len(self.scores_valid) == 0:
60
            return
61
62
        modZero = self.nth_trial % self.n_neighbours == 0
63
        if modZero:
64
            score_new_list_temp = self.scores_valid[-self.n_neighbours :]
65
            pos_new_list_temp = self.positions_valid[-self.n_neighbours :]
66
67
            idx = max_list_idx(score_new_list_temp)
68
            score = score_new_list_temp[idx]
69
            pos = pos_new_list_temp[idx]
70
71
            self._eval2current(pos, score)
72
            self._eval2best(pos, score)
73