PatternSearch.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 28
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 24
dl 0
loc 28
rs 9.304
c 0
b 0
f 0
cc 1
nop 10

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 random
6
import numpy as np
7
8
from ..base_optimizer import BaseOptimizer
9
from ..local_opt.hill_climbing_optimizer import HillClimbingOptimizer
10
11
12
def max_list_idx(list_):
13
    max_item = max(list_)
14
    max_item_idx = [i for i, j in enumerate(list_) if j == max_item]
15
    return max_item_idx[-1:][0]
16
17
18
class PatternSearch(BaseOptimizer):
19
    name = "Pattern Search"
20
    _name_ = "pattern_search"
21
    __name__ = "PatternSearch"
22
23
    optimizer_type = "global"
24
    computationally_expensive = False
25
26
    def __init__(
27
        self,
28
        search_space,
29
        initialize={"grid": 4, "random": 2, "vertices": 4},
30
        constraints=[],
31
        random_state=None,
32
        rand_rest_p=0,
33
        nth_process=None,
34
        n_positions=4,
35
        pattern_size=0.25,
36
        reduction=0.9,
37
    ):
38
        super().__init__(
39
            search_space=search_space,
40
            initialize=initialize,
41
            constraints=constraints,
42
            random_state=random_state,
43
            rand_rest_p=rand_rest_p,
44
            nth_process=nth_process,
45
        )
46
47
        self.n_positions = n_positions
48
        self.pattern_size = pattern_size
49
        self.reduction = reduction
50
51
        self.n_positions_ = min(n_positions, self.conv.n_dimensions)
52
        self.pattern_size_tmp = pattern_size
53
        self.pattern_pos_l = []
54
55
    def generate_pattern(self, current_position):
56
        pattern_pos_l = []
57
58
        n_valid_pos = len(self.positions_valid)
59
        n_pattern_pos = int(self.n_positions_ * 2)
60
        n_pos_min = min(n_valid_pos, n_pattern_pos)
61
62
        best_in_recent_pos = any(
63
            np.array_equal(np.array(self.pos_best), pos)
64
            for pos in self.positions_valid[n_pos_min:]
65
        )
66
        if best_in_recent_pos:
67
            self.pattern_size_tmp *= self.reduction
68
        pattern_size = self.pattern_size_tmp
69
70
        for idx, dim_size in enumerate(self.conv.dim_sizes):
71
            pos_pattern_p = np.array(current_position)
72
            pos_pattern_n = np.array(current_position)
73
74
            pos_pattern_p[idx] += pattern_size * dim_size
75
            pos_pattern_n[idx] -= pattern_size * dim_size
76
77
            pos_pattern_p = self.conv2pos(pos_pattern_p)
78
            pos_pattern_n = self.conv2pos(pos_pattern_n)
79
80
            pattern_pos_l.append(pos_pattern_p)
81
            pattern_pos_l.append(pos_pattern_n)
82
83
        self.pattern_pos_l = list(
84
            random.sample(pattern_pos_l, self.n_positions_)
85
        )
86
87
    @BaseOptimizer.track_new_pos
88
    @BaseOptimizer.random_iteration
89
    def iterate(self):
90
        while True:
91
            pos_new = self.pattern_pos_l[0]
92
            self.pattern_pos_l.pop(0)
93
94
            if self.conv.not_in_constraint(pos_new):
95
                return pos_new
96
            return self.move_climb(pos_new)
97
98
    def finish_initialization(self):
99
        self.generate_pattern(self.pos_current)
100
        self.search_state = "iter"
101
102
    @BaseOptimizer.track_new_score
103
    def evaluate(self, score_new):
104
        BaseOptimizer.evaluate(self, score_new)
105
        if len(self.scores_valid) == 0:
106
            return
107
108
        modZero = self.nth_trial % int(self.n_positions_ * 2) == 0
109
110
        if modZero or len(self.pattern_pos_l) == 0:
111
            if self.search_state == "iter":
112
                self.generate_pattern(self.pos_current)
113
114
            score_new_list_temp = self.scores_valid[-self.n_positions_ :]
115
            pos_new_list_temp = self.positions_valid[-self.n_positions_ :]
116
117
            idx = max_list_idx(score_new_list_temp)
118
            score = score_new_list_temp[idx]
119
            pos = pos_new_list_temp[idx]
120
121
            self._eval2current(pos, score)
122
            self._eval2best(pos, score)
123