使用抛物线法来寻找单峰区间最小值,定义了一个匿名函数f,并对目标函数进行绘图,最后标记了找到的最小值。
Matlab代码
function min_x = parabolic_interpolation(f, x1, x2, x3, max_iterations, tolerance)
for i = 1:max_iterations
y1 = feval(f, x1);
y2 = feval(f, x2);
y3 = feval(f, x3);
A = [x1^2, x1, 1; x2^2, x2, 1; x3^2, x3, 1];
B = [y1; y2; y3];
sol = A \ B;
a = sol(1);
b = sol(2);
c = sol(3);
x = (x1 + x2) / 2 - b / (2 * a);
y = feval(f, x);
if abs(x2 - x) < tolerance
min_x = x;
return;
end
if y < y2
if x > x2
x3 = x2;
x2 = x;
else
x1 = x;
end
else
x3 = x;
end
end
min_x = x;
end
function min_x = find_minimum(f, a, b, max_iterations, tolerance)
x1 = a;
x3 = b;
x2 = (a + b) / 2;
min_x = parabolic_interpolation(f, x1, x2, x3, max_iterations, tolerance);
end
f = @(x) x^2 + 5 * sin(x);
a = -5;
b = 5;
x = linspace(a, b, 100);
y = f(x);
min_x = find_minimum(f, a, b, 100, 1e-6);
min_y = f(min_x);
plot(x, y, 'LineWidth', 2, 'DisplayName', 'Function');
hold on;
plot(min_x, min_y, 'ro', 'MarkerSize', 10, 'DisplayName', 'Minimum');
legend();
hold off;
Python代码
import numpy as np
import matplotlib.pyplot as plt
def parabolic_interpolation(f, x1, x2, x3, max_iterations, tolerance):
for i in range(max_iterations):
y1 = f(x1)
y2 = f(x2)
y3 = f(x3)
A = np.array([[x1**2, x1, 1], [x2**2, x2, 1], [x3**2, x3, 1]])
B = np.array([y1, y2, y3])
a, b, c = np.linalg.solve(A, B)
x = (x1 + x2) / 2 - b / (2 * a)
y = f(x)
if abs(x2 - x) < tolerance:
return x
if y < y2:
if x > x2:
x3 = x2
x2 = x
else:
x1 = x
else:
x3 = x
return x
def find_minimum(f, a, b, max_iterations, tolerance):
x1 = a
x3 = b
x2 = (a + b) / 2
return parabolic_interpolation(f, x1, x2, x3, max_iterations, tolerance)
def f(x):
return x**2 + 5 * np.sin(x)
a = -5
b = 5
x = np.linspace(a, b, 100)
y = f(x)
min_x = find_minimum(f, a, b, 100, 1e-6)
min_y = f(min_x)
plt.plot(x, y, label="Function")
plt.plot(min_x, min_y, "ro", label="Minimum")
plt.legend()
plt.show()