Passed
Push — master ( 07671f...674edd )
by Simon
03:40
created

DownhillSimplexOptimizer.__init__()   A

Complexity

Conditions 1

Size

Total Lines 21
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nop 8
dl 0
loc 21
rs 9.55
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
from ...search import Search
9
10
11
def sort_list_idx(list_):
12
    list_np = np.array(list_)
13
    idx_sorted = list(list_np.argsort()[::-1])
14
    return idx_sorted
15
16
17
def centeroid(array_list):
18
    centeroid = []
19
    for idx in range(array_list[0].shape[0]):
20
        center_dim_pos = []
21
        for array in array_list:
22
            center_dim_pos.append(array[idx])
23
24
        center_dim_mean = np.array(center_dim_pos).mean()
25
        centeroid.append(center_dim_mean)
26
27
    return centeroid
28
29
30
class DownhillSimplexOptimizer(BaseOptimizer, Search):
31
    def __init__(
32
        self,
33
        search_space,
34
        initialize={"grid": 4, "random": 2, "vertices": 4},
35
        alpha=1,
36
        gamma=2,
37
        beta=0.5,
38
        sigma=0.5,
39
        rand_rest_p=0.01,
40
    ):
41
        super().__init__(search_space, initialize)
42
43
        self.alpha = alpha
44
        self.gamma = gamma
45
        self.beta = beta
46
        self.sigma = sigma
47
48
        self.n_simp_positions = len(search_space) + 1
49
        self.simp_positions = []
50
51
        self.simplex_step = 0
52
53
    def finish_initialization(self):
54
        idx_sorted = sort_list_idx(self.scores_valid)
55
        self.simplex_pos = [self.positions_valid[idx] for idx in idx_sorted]
56
        self.simplex_scores = [self.scores_valid[idx] for idx in idx_sorted]
57
58
        print("\n self.simplex_pos \n", self.simplex_pos)
59
60
        self.simplex_step = 1
61
62
        self.i_x_0 = 0
63
        self.i_x_N_1 = -2
64
        self.i_x_N = -1
65
66
    @BaseOptimizer.track_nth_iter
67
    def iterate(self):
68
        print("")
69
        if self.simplex_step == 1:
70
            print("iter 1 ")
71
            idx_sorted = sort_list_idx(self.simplex_scores)
72
            self.simplex_pos = [self.simplex_pos[idx] for idx in idx_sorted]
73
            self.simplex_scores = [self.simplex_scores[idx] for idx in idx_sorted]
74
75
            self.center_array = centeroid(self.simplex_pos[:-1])
76
            r_pos = self.center_array + self.alpha * (
77
                self.center_array - self.simplex_pos[-1]
78
            )
79
80
            self.r_pos = self.conv2pos(r_pos)
81
            return self.r_pos
82
83
        elif self.simplex_step == 2:
84
            print("iter 2 ")
85
            e_pos = self.center_array + self.gamma * (
86
                self.center_array + self.simplex_pos[-1]
87
            )
88
            self.e_pos = self.conv2pos(e_pos)
89
            print(" self.e_pos ", self.e_pos)
90
            self.simplex_step = 1
91
92
            return self.e_pos
93
94
        elif self.simplex_step == 3:
95
            print("iter 3 ")
96
            return self.r_pos
97
98
        elif self.simplex_step == 4:
99
            print("iter 4 self.c_pos", self.c_pos)
100
            return self.c_pos
101
102
        elif self.simplex_step == 5:
103
            pos = self.simplex_pos[self.compress_idx]
104
            pos = pos + self.sigma * (self.simplex_scores[0] - pos)
105
106
            return self.conv2pos(pos)
107
108
    def evaluate(self, score_new):
109
        self.score_new = score_new
110
111
        if self.simplex_step == 1:
112
            print(" self.simplex_step ", self.simplex_step)
113
            if score_new > self.simplex_scores[0]:
114
                print("eval 1 ")
115
                # if r is better than x0
116
                self.simplex_pos[-1] = self.r_pos
117
                self.simplex_scores[-1] = score_new
118
                self.simplex_step = 2
119
            elif score_new > self.simplex_scores[-2]:
120
                print("eval 2 ")
121
                # if r is better than x N-1
122
                self.simplex_pos[-2] = self.r_pos
123
                self.simplex_scores[-2] = score_new
124
                self.simplex_step = 3
125
            elif score_new > self.simplex_scores[-1]:
126
                print("eval 3 ")
127
                # if r is better than x N
128
                self.h_pos = self.r_pos
129
                c_pos = self.h_pos + self.beta * (self.center_array - self.h_pos)
130
                self.c_pos = self.conv2pos(c_pos)
131
132
                self.simplex_step = 4
133
            else:
134
                print("eval 4 ")
135
                # if r is worse than x N
136
                self.h_pos = self.simplex_pos[-1]
137
                c_pos = self.h_pos + self.beta * (self.center_array - self.h_pos)
138
                self.c_pos = self.conv2pos(c_pos)
139
140
                self.simplex_step = 4
141
142
        elif self.simplex_step == 2:
143
            print(" self.simplex_step ", self.simplex_step)
144
145
            idx_sorted = sort_list_idx(self.scores_valid[-2:])
146
            self.simplex_pos[-1] = self.simplex_pos[-2:][idx_sorted][0]
147
            self.simplex_scores[-1] = self.simplex_scores[-2:][idx_sorted][0]
148
149
            self.simplex_step -= 1
150
151
            print(" self.simplex_pos[-1] ", self.simplex_pos[-1])
152
153
        elif self.simplex_step == 3:
154
            print(" self.simplex_step ", self.simplex_step)
155
156
            self.simplex_step = 1
157
158
        elif self.simplex_step == 4:
159
            print(" self.simplex_step ", self.simplex_step)
160
161
            if score_new > self.simplex_scores[-1]:
162
                self.simplex_pos[-1] = self.c_pos
163
                self.simplex_scores[-1] = score_new
164
                self.simplex_step = 1
165
            else:
166
                self.simplex_step = 5
167
                self.compress_idx = 0
168
169
        elif self.simplex_step == 5:
170
            print(" self.simplex_step ", self.simplex_step)
171
172
            self.simplex_scores[self.compress_idx] = score_new
173
            self.compress_idx += 1
174
175
            if self.compress_idx == self.n_simp_positions:
176
                self.simplex_step = 1
177