Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
DataScienceUWL
GitHub Repository: DataScienceUWL/DS775
Path: blob/main/Homework/Lesson 05 HW - Local Optimization/locsearch/ls.py
852 views
1
from __future__ import absolute_import
2
from __future__ import division
3
from __future__ import print_function
4
from __future__ import unicode_literals
5
import abc
6
import copy
7
import math
8
import signal
9
import sys
10
11
class LocalSearcher(object):
12
13
"""Performs local search by calling functions to calculate
14
objective function value and make moves on a state. The search terminates when
15
no improvements to the objective function value have made for max_no_improve
16
iterations (default 1000)
17
"""
18
19
__metaclass__ = abc.ABCMeta
20
21
# defaults
22
max_no_improve = 1000
23
update_iter = 100
24
copy_strategy = 'deepcopy'
25
26
# placeholders
27
best_x = None
28
best_f = None
29
iterations = 0
30
31
def __init__(self, initial_state=None):
32
if initial_state is not None:
33
self.state = self.copy_state(initial_state)
34
else:
35
raise ValueError('No inital_state supplied')
36
37
@abc.abstractmethod
38
def move(self):
39
"""Create a state change"""
40
pass
41
42
@abc.abstractmethod
43
def objective(self):
44
"""Calculate state's objective function value"""
45
pass
46
47
def copy_state(self, state):
48
"""Returns an exact copy of the provided state
49
Implemented according to self.copy_strategy, one of
50
51
* deepcopy : use copy.deepcopy (slow but reliable)
52
* slice: use list slices (faster but only works if state is list-like)
53
* method: use the state's copy() method
54
"""
55
if self.copy_strategy == 'deepcopy':
56
return copy.deepcopy(state)
57
elif self.copy_strategy == 'slice':
58
return state[:]
59
elif self.copy_strategy == 'method':
60
return state.copy()
61
else:
62
raise RuntimeError('No implementation found for ' +
63
'the self.copy_strategy "%s"' %
64
self.copy_strategy)
65
66
def update(self):
67
"""
68
Prints the current best value and iterations every update_iter iterations.
69
"""
70
71
if self.iterations == 0:
72
print("\n Obj Fun Val | Iterations")
73
else:
74
print(f"{self.best_f:12.2f} | {self.iterations:d}")
75
76
77
def localsearch(self):
78
"""Minimizes the objective function value by local search.
79
80
Parameters
81
state : an initial arrangement of the system
82
83
Returns
84
(state, objective): the best state and objective function value found.
85
"""
86
self.iterations = 0
87
num_moves_no_improve = 0
88
89
# set initial state and compute initial objective value
90
self.best_x = self.copy_state(self.state)
91
self.best_f = self.objective()
92
self.update()
93
94
# main local search loop
95
while num_moves_no_improve < self.max_no_improve:
96
num_moves_no_improve += 1
97
self.iterations += 1
98
curr_state = self.copy_state(self.state)
99
self.move() # stores new state with move in self.state
100
new_f = self.objective()
101
if new_f < self.best_f:
102
num_moves_no_improve = 0
103
self.best_x = self.copy_state(self.state)
104
self.best_f = new_f
105
else: # if move not improvement reset state to curr_state
106
self.state = self.copy_state(curr_state)
107
if( self.iterations % self.update_iter == 0): # output every update_iter iterations
108
self.update() # print output
109
110
# output one last time for final iteration
111
self.update()
112
113
# Return best state and energy
114
return self.best_x, self.best_f
115