-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmethods.py
182 lines (145 loc) · 5.98 KB
/
methods.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import inline as inline
import matplotlib
matplotlib.use("TkAgg")
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt
from functions import *
from math import *
from interface import *
def get_method_names():
return ["Hooke-Jeeves", "Powell"]
def plot_function_3D(function, a, b, style, title):
fig = plt.figure()
ax = plt.axes(projection='3d')
x = np.linspace(a, b, 30)
y = x
X, Y = np.meshgrid(x, y)
Z = function([X, Y])
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=style, edgecolor="none")
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title(title)
plt.show()
def hooke_jeeves(function, x0, d, d_min, display_info=False, window=None):
n = x0.size
e = np.eye(n) * d
x = x0
fx = function(x)
num_iterations = 0
while e[1, 1] > d_min:
current_position = x
for i in range(0, n):
z = current_position + e[:, i]
y = function(z)
num_iterations += 1
if y < fx:
current_position = z
fx = y
if display_info and num_iterations % 10 == 0:
to_write = "Iteration {} -- Current X: {}\nFunction value: {}\n".format(num_iterations, x, fx)
window.result_console.append(to_write)
else:
z = current_position - e[:, i]
y = function(z)
num_iterations += 1
if y < fx:
current_position = z
fx = y
if display_info and num_iterations % 10 == 0:
to_write = "Iteration {} -- Current X: {}\nFunction value: {}\n".format(num_iterations, x, fx)
window.result_console.append(to_write)
if np.all(current_position == x):
e = e * 0.5
else:
x1 = current_position + (current_position - x)
f1 = function(x1)
num_iterations += 1
x = current_position
if display_info and num_iterations % 10 == 0:
to_write = "Iteration {} -- Current X: {}\nFunction value: {}\n".format(num_iterations, x, fx)
window.result_console.append(to_write)
if f1 < fx:
x = x1
fx = f1
for i in range(0, n):
z = x1 - e[:, i]
y = function(z)
num_iterations += 1
if y < f1:
x = z
fx = y
if display_info and num_iterations % 10 == 0:
to_write = "Iteration {} -- Current X: {}\nFunction value: {}\n".format(num_iterations, x, fx)
window.result_console.append(to_write)
return x, fx, num_iterations
def golden_ratio(function, e, current, a, b, tolerance):
c = (3 - sqrt(5)) / 2
x1 = a + (b - a) * c
x2 = a + b - x1
fx1 = function(current + x1 * e)
fx2 = function(current + x2 * e)
while b - a > tolerance:
if fx1 <= fx2:
b = x2
x2 = x1
fx2 = fx1
x1 = a + c * (b - a)
fx1 = function(current + x1 * e)
x = x1
else:
a = x1
x1 = x2
fx1 = fx2
x2 = b - c * (b - a)
fx2 = function(current + x2 * e)
x = x2
return x
def powell(function, helper_function, starting_position, tolerance, display_info=False, window=None, gda=-5, gdb=5):
dimension = starting_position.size
e = np.eye(dimension)
x = starting_position
x1 = starting_position + 2 * 10
num_iterations = 0
while np.max(np.abs(x - x1)) > tolerance:
num_iterations += 1
current = x
for i in range(dimension):
theta = helper_function(function, e[:, i], current, gda, gdb, tolerance)
current = current + theta * e[:, i]
for i in range(dimension - 1):
e[:, i] = e[:, i + 1]
e[:, dimension - 1] = current - x
x1 = x
theta = helper_function(function, e[:, dimension - 1], current, gda, gdb, tolerance)
x = current + theta * e[:, dimension - 1]
if display_info and num_iterations % 10 == 0:
to_write = "Iteration {} -- Current X: {}\nFunction value: {}\n".format(num_iterations, x, function(x))
window.result_console.append(to_write)
fx = function(x)
return x, fx, num_iterations
methods = {"Hooke-Jeeves": hooke_jeeves, "Powell": powell}
methods_info = {
"Hooke-Jeeves": "The Hooke-Jeeves algorithm, also known as “pattern search”, keeps track of the direction of travel as the process moves from point to point, instead of starting over from scratch at each new point.",
"Powell": "Powell's method, strictly Powell's conjugate direction method, is an algorithm proposed by Michael J. D. Powell for finding a local minimum of a function. The function doesn't need to be differentiable, and no derivatives are taken. The function must be a real-valued function of a fixed number of real-valued inputs."}
if __name__ == '__main__':
# Testni slucajevi:
a = np.array([1.0, 4.0]).T
b = np.array([2, 1, 2, 1, 3, 2, -1, 0, 1, 2]).T
c = np.array([2, 2, 2, 3]).T
d = np.array([-1.2, 1]).T
# Resenja idu redom: X, Y, broj iteracija
print("SFERA: ")
print(hooke_jeeves(sphere, b, 1, 0.0001))
print(powell(sphere, golden_ratio, b, 0.0001))
print("BANANA: ")
print(hooke_jeeves(rosenbrock, b, 1, 0.0001))
print(powell(rosenbrock, golden_ratio, b, 0.0001))
print("KAMILA: ")
print(hooke_jeeves(three_hump_camel, d, 1, 0.0001))
print(powell(three_hump_camel, golden_ratio, d, 0.0001))
# Odkomentarisati bilo koji poziv funkcije kako bi je iscrtali u 3D
# plot_function_3D(three_hump_camel, -2, 2, "viridis", "Three Hump Camel")
# plot_function_3D(sphere, -5, 5, "viridis", "Sphere")
# plot_function_3D(rosenbrock, -2.048, 2.048, "viridis", "Rosenbrock")