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

DownhillSimplexOptimizer.finish_initialization()   A

Complexity

Conditions 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nop 1
dl 0
loc 12
rs 9.95
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
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