1 | # pylint: disable=redefined-variable-type |
||
2 | 1 | import numpy as np |
|
3 | |||
4 | 1 | from grortir.main.model.core.optimization_status import OptimizationStatus |
|
5 | 1 | from grortir.main.pso.group_optimization_strategy import \ |
|
6 | GroupOptimizationStrategy |
||
7 | |||
8 | |||
9 | 1 | class CreditCallsGroupOptimizationStrategy(GroupOptimizationStrategy): |
|
10 | """Optimization with credits. |
||
11 | Attributes: |
||
12 | stages_in_group (list): stages in group |
||
13 | process (AbstractProcess): optimized process |
||
14 | max_calls_for_group (int): max calls which can be |
||
15 | used for this group |
||
16 | expected_quality (float): expected quality |
||
17 | """ |
||
18 | |||
19 | 1 | def __init__(self, stages_in_group, process): |
|
20 | 1 | self.stages_in_group = stages_in_group |
|
21 | 1 | self.process = process |
|
22 | 1 | self.max_calls_for_group = 0 |
|
23 | 1 | self.expected_quality = np.inf |
|
24 | |||
25 | 1 | def initialize(self): |
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
26 | """ |
||
27 | Called once and set initial value of max_calls_for_group. |
||
28 | """ |
||
29 | 1 | if self._calculate_current_cost_in_group() != 0: |
|
30 | 1 | raise ValueError( |
|
31 | "Stages in group shouldn't started with initial cost.") |
||
32 | 1 | all_initial_calls = 0 |
|
33 | 1 | already_used_calls = 0 |
|
34 | 1 | all_stages = self.process.nodes() |
|
35 | 1 | for stage in all_stages: |
|
36 | 1 | all_initial_calls += stage.get_maximal_acceptable_cost() |
|
37 | 1 | for stage in all_stages: |
|
38 | 1 | already_used_calls += stage.get_cost() |
|
39 | 1 | self.max_calls_for_group = all_initial_calls - already_used_calls |
|
40 | |||
41 | 1 | for stage in self.stages_in_group: |
|
42 | 1 | if self.expected_quality > stage.maximum_acceptable_quality: |
|
43 | 1 | self.expected_quality = stage.maximum_acceptable_quality |
|
44 | |||
45 | 1 | def should_continue(self, best_particle): |
|
0 ignored issues
–
show
|
|||
46 | """ |
||
47 | Return true if optimization should be continued for Calls Process with |
||
48 | credits. |
||
49 | Args: |
||
50 | best_particle Particle: best particle in swarm. |
||
51 | |||
52 | Returns: |
||
53 | bool: true if continuation is required. |
||
54 | |||
55 | """ |
||
56 | 1 | return self._is_safe_cost() and not self._is_enough_quality( |
|
57 | best_particle) |
||
58 | |||
59 | 1 | def finalize(self, best_particle): |
|
0 ignored issues
–
show
|
|||
60 | """ |
||
61 | Set proper status after finished group optimization. |
||
62 | Args: |
||
63 | best_particle (Particle): best particle in Swarm |
||
64 | """ |
||
65 | 1 | optimizatin_status = OptimizationStatus.failed |
|
66 | 1 | if self._is_safe_cost() and self._is_enough_quality( |
|
67 | best_particle): |
||
68 | 1 | optimizatin_status = OptimizationStatus.success |
|
69 | 1 | for stage in self.stages_in_group: |
|
70 | 1 | stage.optimization_status = optimizatin_status |
|
71 | |||
72 | 1 | def _is_safe_cost(self): |
|
73 | 1 | return ( |
|
74 | self._calculate_current_cost_in_group() <= self.max_calls_for_group) |
||
75 | |||
76 | 1 | def _is_enough_quality(self, best_particle): |
|
77 | 1 | return best_particle.best_quality <= self.expected_quality |
|
78 | |||
79 | 1 | def _calculate_current_cost_in_group(self): |
|
80 | 1 | calls_used_in_group = 0 |
|
81 | 1 | for stage in self.stages_in_group: |
|
82 | 1 | calls_used_in_group += stage.get_cost() |
|
83 | return calls_used_in_group |
||
84 |