import numpy as np def point_info(x, f): return f"x = {x}, f(x) = {f(x)}" def hooke_jeeves(f, x0, delta0, epsilon, alpha, r=lambda x: True): x = np.array(x0) delta = np.array(delta0) iteration = 0 while np.linalg.norm(delta) > epsilon: iteration += 1 print() print("=" * 40) print("Итерация", iteration) print("Текущая базовая точка", point_info(x, f)) sample_x = exploratory_search(f, x, delta, r=r) if f(sample_x) < f(x): print("Исследующий поиск УДАЧНЫЙ") x_p = sample_search(f, x, sample_x, r=r) if f(x_p) < f(x): print("Поиск по образцу УДАЧНЫЙ") x = x_p else: print("Поиск по образцу ПРОВАЛЕН") x = sample_x print() print("Новая базовая точка", point_info(x, f)) else: print("Исследующий поиск ПРОВАЛЕН") print("Уменьшаем шаг", delta, "->", delta / alpha) delta = delta / alpha print("ε =", np.linalg.norm(delta)) return x, f(x) def exploratory_search(f, x, delta, r=lambda x: True): print() print("Выполняем исследующий поиск") x_new = np.array(x) f_x_new = f(x_new) for i in range(len(x)): x_up = x_new.copy() x_down = x_new.copy() x_up[i] += delta[i] x_down[i] -= delta[i] f_x_up = f(x_up) f_x_down = f(x_down) if f_x_up < f_x_new and f_x_up < f_x_down: x_new = x_up f_x_new = f_x_up elif f_x_down < f_x_new: x_new = x_down f_x_new = f_x_down if any([x_new[i] != x[i] for i in range(len(x))]): print("Найдена точка", x_new, f(x_new)) return x_new def sample_search(f, x1, x2, r=lambda x: True): print() print("Выполняем поиск по образцу") while f(x2) < f(x1): x2, x1 = x2 + (x2 - x1), x2 print("Найдена точка", x2, f(x2)) return x2 def f1(): x0 = [0, 0] delta0 = [1e6, 1e6, 1e6] alpha = 2 epsilon = 1e-4 c = [[1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1]] r = [[-1000, 1000], [-100, 100]] def f(x): return sum( [ sum([c[i][j] * x[i] ** j for j in range(len(c[i]))]) for i in range(len(c)) ] ) x, val = hooke_jeeves(f, x0, delta0, epsilon, alpha, r=r) return x, val def f2(): x0 = [1, 1] delta0 = [1, 1] alpha = 2 epsilon = 1e-6 def f(x): return x[0] ** 4 + x[1] ** 2 - 4 * x[0] * x[1] x, val = hooke_jeeves(f, x0, delta0, epsilon, alpha) return x, val def f3(): x0 = [1, 0] delta0 = [1, 1] alpha = 2 epsilon = 1e-5 def f(x): return x[0] * np.exp(x[0]) - (1 + np.exp(x[0])) * np.sin(x[1]) x, val = hooke_jeeves(f, x0, delta0, epsilon, alpha) return x, val def example(): x0 = [-4, -4] delta0 = [1, 1] alpha = 2 epsilon = 1e-4 def f(x): return 8 * (x[0] ** 2) + 4 * x[0] * x[1] + 5 * (x[1] ** 2) x, val = hooke_jeeves(f, x0, delta0, epsilon, alpha) return x, val if __name__ == "__main__": x, val = f1() # x, val = f2() # x, val = f3() # x, val = example() print() print("=" * 40) print("Точка экстремумв:", x) print("Минимальное значение функции:", val)