gradient_free_optimizers.optimizers.global_opt.pattern_search   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 14
eloc 90
dl 0
loc 123
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A PatternSearch.evaluate() 0 21 5
A PatternSearch.__init__() 0 28 1
A PatternSearch.generate_pattern() 0 30 3
A PatternSearch.iterate() 0 10 3
A PatternSearch.finish_initialization() 0 3 1

1 Function

Rating   Name   Duplication   Size   Complexity  
A max_list_idx() 0 4 1
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