-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopt_methods.py
More file actions
122 lines (97 loc) · 4.04 KB
/
Copy pathopt_methods.py
File metadata and controls
122 lines (97 loc) · 4.04 KB
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
def f(x):
return x[0]**5 - x[1]**2
import numpy as np
from scipy.optimize import minimize_scalar
import pandas as pd
def hook_jeeves(x_start, delta, epsilon):
df = pd.DataFrame(columns=['x', 'y', 'f(x, y)'])
x = x_start.copy()
x_new = x_start.copy()
while True:
# Исследовательский поиск
for i in range(len(x)):
x_plus = x.copy()
x_plus[i] += delta
x_minus = x.copy()
x_minus[i] -= delta
if f(x_plus) < f(x):
x_new[i] = x_plus[i]
elif f(x_minus) < f(x):
x_new[i] = x_minus[i]
# Узловой поиск
x_pattern = 2*x_new - x
if f(x_pattern) < f(x):
x = x_pattern.copy()
df = pd.concat([df, pd.DataFrame({'x': [x[0]], 'y': [x[1]], 'f(x, y))': [f(x)]})], ignore_index=True)
else:
if np.linalg.norm(delta) < epsilon:
df = pd.concat([df, pd.DataFrame({'x': [x[0]], 'y': [x[1]], 'f(x, y))': [f(x)]})], ignore_index=True)
break
delta /= 2
x_new = x.copy()
return x, f(x), df
def gauss_zeidel(x_start, n, epsilon):
df = pd.DataFrame(columns=['x', 'y', 'f(x, y)'])
y = np.copy(x_start)
k = 1
j = 1
while True:
# Одномерный поиск
res = minimize_scalar(lambda lmbd: f(y + lmbd * np.eye(n)[j-1]))
lmbd = res.x
# Обновление y
y = y + lmbd * np.eye(n)[j-1]
if j < n:
j += 1
df = pd.concat([df, pd.DataFrame({'x': [y[0]], 'y': [y[1]], 'f(x, y))': [f(y)]})], ignore_index=True)
else:
if np.linalg.norm(y - x_start) < epsilon:
df = pd.concat([df, pd.DataFrame({'x': [y[0]], 'y': [y[1]], 'f(x, y))': [f(y)]})], ignore_index=True)
break
else:
x_start = y
j = 1
k += 1
df = pd.concat([df, pd.DataFrame({'x': [y[0]], 'y': [y[1]], 'f(x, y))': [f(y)]})], ignore_index=True)
return y, f(x), df
def rosenbrock(x_start, alpha, epsilon):
df = pd.DataFrame(columns=['x', 'y', 'f(x, y)'])
while True:
x_prev = x.copy()
# Поиск вдоль оси x
while True:
f_prev = f(x_start)
x_start[0] -= alpha * ((2 * (x_start[0] - a) * np.exp(-(x_start[0] - a)) * (1 + (x_start[1] - a))) + ((x_start[1] - b) * np.exp(-(x_start[0] - b))))
if abs(f(x_start) - f_prev) < epsilon:
break
# Поиск вдоль оси y
while True:
f_prev = f(x_start)
x_start[1] -= alpha * (x_start[1] - b) * np.exp(-(x_start[0] - b))
if abs(f(x_start) - f_prev) < epsilon:
break
# Проверка критерия остановки
if np.linalg.norm(x_start - x_prev) < epsilon:
df = pd.concat([df, pd.DataFrame({'x': [x_start[0]], 'y': [x_start[1]], 'f(x, y))': [f(x_start)]})], ignore_index=True)
break
else:
df = pd.concat([df, pd.DataFrame({'x': [x_start[0]], 'y': [x_startx[1]], 'f(x, y))': [f(x_start)]})], ignore_index=True)
return x_start, f(x_start), df
def grad_f(x):
dfdx = (x[0]-a)*np.exp(-(x[0]-a)) + 1
dfdy = (x[1]-b)*np.exp(-(x[1]-b)) + 1
return np.array([dfdx, dfdy])
def rapid_descent(x_start, epsilon):
df = pd.DataFrame(columns=['x', 'y', 'f(x, y)'])
while True:
g = grad_f(x_start)
if np.linalg.norm(g) < epsilon:
df = pd.concat([df, pd.DataFrame({'x': [x_start[0]], 'y': [x_start[1]], 'f(x, y))': [f(x_start)]})], ignore_index=True)
break
# направление спуска
S = -g / np.linalg.norm(g)
res = minimize_scalar(lambda alpha: f(x_start + alpha*S))
alpha_opt = res.x_start
x_start = x_start + alpha_opt * S
df = pd.concat([df, pd.DataFrame({'x': [x_start[0]], 'y': [x_start[1]], 'f(x, y))': [f(x_start)]})], ignore_index=True)
return x_start