Вы находитесь на странице: 1из 11

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ

НАЦИОНАЛЬНЫЙ АЭРОКОСМИЧЕСКИЙ УНИВЕСИТЕТ


ИМ. Н. Е. ЖУКОВСКОГО «ХАИ»

Лабораторная работа №3

«Решение задач нелинейного программирования на ЭВМ»

Выполнил: студент группы 433


Писаная Ольга
Проверил: преподаватель каф. 304
Яровая О. В.

Харьков – 2020
Цель работы: знакомство с оптимизационными задачами, изучение различных методов многомерной
оптимизации и сравнение эффективности их применения для конкретных целевых функций.

Постановка задачи

Задание 1: Построить график заданной функции с указанными параметрами с шагом h = 0.1. Определить
область нахождения глобального минимума в указанном интервале: x1нач = –2, x1кон = 2, x2нач = –2, x2кон = 2.

Задание 2: Используя методы градиентный, наискорейшего спуска, сопряжённых градиентов, тяжёлого шарика
определить экстремум заданной функции R(x) с точностью ε = 0,001.
Параметры поиска:

 коэффициент шага h = 0.1, пробный шаг g = 0.001,


 алгоритм коррекции шага: без коррекции коэффициента пропорциональности шага (h = const).
 Способ вычисления производной: вычисление gradR с парными пробами.

Содержание отчёта по лабораторной работе


– задание на выполнение лабораторной работы;
– блок-схемы и программы для решения заданной функции R(x) методами градиентный, наискорейшего
спуска, сопряжённых градиентов, тяжёлого шарика;
– результаты работы программ с указанием точек экстремума и количества шагов, потребовавшихся для
нахождения решения;
– сравнение и анализ результатов решения для использованных методов.

Вариант № 15
F (x1 , x2 )=1 .8 ⋅ x12 +1.8 ⋅ x 22 +1.3 ⋅sin(¿ x 1 +2.8 ⋅ x1 ⋅ x 2+ x 2 )¿
MathCad Python
def f(x):
y = 1.8*(x[0]**2)+1.8*(x[1]**2)+1.3*sin(x[0]+2.8*x[0]*x[1]+x[1])
return y

def F(x1, x2):


y = 1.8*(x1*x1)+1.8*(x2*x2)+1.3*sin(x1+2.8*x1*x2+x2)
return y

def graph():
f = lambda x, y: 1.8 * (x * x) + 1.8 * (y * y) + 1.3 * np.sin(x + 2.8 * x * y + y)
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.grid()
xval = np.linspace(-4, 4, 100)
yval = np.linspace(-4, 4, 100)
x, y = np.meshgrid(xval, yval)
z = f(x, y)
surf = ax.plot_surface(x, y, z, rstride = 2,cstride = 2,cmap = cm.viridis)
plt.show()

def Built_in(x1,x2):
x = np.array([x1,x2])
built_in = optimize.minimize(f, x,options={'gtol': 1e-6, 'disp': True})
res = "x1 = {xx1} \n x2 = {xx2} \nf(x1,x2) = {yy}".format(xx1="%.5f" %
built_in.x[0],xx2="%.5f" % built_in.x[1],yy="%.5f" % built_in.fun)
return res
def grad_fabs(x1, x2, g):
R1 = F(x1+g, x2)
R2 = F(x1-g, x2)
R3 = F(x1, x2+g)
R4 = F(x1, x2-g)
p1 = (R1-R2)/(2*g)
p2 = (R3-R4)/(2*g)
G = sqrt(p1*p1 + p2*p2)
return G

def Gold(R,a,b,eps):
l = (sqrt(5)+1)/2
i=0
while fabs(b-a) > 2*eps and i < 10000:
x1 = b - (b-a)/l
x2 = a + (b-a)/l
if (R(x1) >= R(x2)):
a = x1
else: b = x2
i=i+1
x = (a+b)/2
return x
Метод градиента

def Gradient(x1, x2, h, g, eps):


i=0
while grad_fabs(x1, x2, g) > eps and i < 10000:
X = np.array([x1, x2])
G = optimize.approx_fprime(X, f, epsilon=1e-10)
x1 = x1 - h*G[0]
x2 = x2 - h*G[1]
i=i+1
y = F(x1, x2)
res = "x1 = " + str(("%.5f") % x1) + "\nx2 = " + str(("%.5f") %
x2) + \
"\nf(x1,x2) = " + str(("%.5f") % y) + "\ni = " + str(i)
return res
Метод наискорейшего спуска

def SteepestDescent(x1,x2,h,g,eps):
i=0
while grad_fabs(x1, x2, g) > eps and i < 10000:
X = np.array([x1, x2])
G = optimize.approx_fprime(X, f, epsilon=1e-6)
def R(h):
return F(x1 - h*G[0],x2 - h*G[1])
h = Gold(R, 0, 2, eps)
x1 = x1 - h*G[0]
x2 = x2 - h*G[1]
i=i+1
y = F(x1, x2)
res = "x1 = " + str(("%.5f") % x1) + "\nx2 = " +
str(("%.5f") % x2) + \
"\nf(x1,x2) = " + str(("%.5f") % y) + "\ni = " + str(i)
return res
Метод сопряженных градиентов
def ConjugateGradient(x1,x2,h,g,eps):
i=0
X0 = np.array([x1, x2])
G0 = optimize.approx_fprime(X0, f, epsilon=1e-6)
X1 = x1 - h*G0[0]
X2 = x2 - h*G0[1]
X = np.array([X1, X2])
G = optimize.approx_fprime(X, f, epsilon=1e-6)
while grad_fabs(X1, X2, g) > eps and i < 10000:
def R(h):
return F(X1 - h*G[0], X2 - h*G[1])
h = Gold(R, 0, 2, eps)
alfa = ((norm(G))**2)/((norm(G0))**2)
if (i % 2) == 0:
grad = G - alfa*G0
else:
grad = G
X1 = X1 - h*grad[0]
X2 = X2 - h*grad[1]
G0 = G
X = np.array([X1, X2])
G = optimize.approx_fprime(X, f, epsilon=1e-6)
i=i+1
y = f(X)
res = "x1 = " + str(("%.5f") % X1) + "\nx2 = " + str(("%.5f") % X2)
+\
"\nf(x1,x2) = " + str(("%.5f") % y) + "\ni = " + str(i)
return res
Метод тяжелого шарика

def HeavyBall(x0_1,x0_2,h,g,eps,alfa):
i=0
X0 = np.array([x0_1, x0_2])
G0 = optimize.approx_fprime(X0, f, epsilon=1e-6)
x1_1 = x0_1 - h*G0[0]
x1_2 = x0_2 - h*G0[1]
X1 = np.array([x1_1, x1_2])
G = optimize.approx_fprime(X1, f, epsilon=1e-6)
while grad_fabs(x1_1, x1_2, g) > eps and i < 10000:
def R(h):
return F(x1_1 - h*G[0], x1_2 - h*G[1])
h = Gold(R, 0, 2, eps)
x2_1 = x1_1 - alfa*(x1_1 - x0_1) - h*G[0]
x2_2 = x1_2 - alfa*(x1_2 - x0_2) - h*G[1]
X2 = np.array([x2_1, x2_2])
G = optimize.approx_fprime(X2, f, epsilon=1e-6)
x0_1 = x1_1
x0_2 = x1_2
x1_1 = x2_1
x1_2 = x2_2
X1 = np.array([x1_1, x1_2])
i=i+1
y = f(X1)
res = "x1 = " + str(("%.5f") % x1_1) + "\nx2 = " + str(("%.5f") % x1_2) + \
"\nf(x1,x2) = " + str(("%.5f") % y) + "\ni = " + str(i)
return res
Программа на языке Python def Gradient(x1, x2, h, g, eps):
i=0
while grad_fabs(x1, x2, g) > eps and i < 10000:
from math import fabs, sin, sqrt
X = np.array([x1, x2])
from scipy import optimize
G = optimize.approx_fprime(X, f, epsilon=1e-10)
from tkinter import *
x1 = x1 - h*G[0]
import numpy as np
x2 = x2 - h*G[1]
from numpy.linalg import norm
i=i+1
from mpl_toolkits.mplot3d import Axes3D
y = F(x1, x2)
from matplotlib import cm
res = "x1 = " + str(("%.5f") % x1) + "\nx2 = " + str(("%.5f") % x2) + \
import matplotlib.pyplot as plt
"\nf(x1,x2) = " + str(("%.5f") % y) + "\ni = " + str(i)
return res
def graph():
f = lambda x, y: 1.8 * (x * x) + 1.8 * (y * y) + 1.3 * np.sin(x + 2.8 * x * y + y)
def Gold(R,a,b,eps):
fig = plt.figure(figsize=(5, 5))
l = (sqrt(5)+1)/2
ax = fig.add_subplot(1, 1, 1, projection='3d')
i=0
ax.grid()
while fabs(b-a) > 2*eps and i < 10000:
xval = np.linspace(-4, 4, 100)
x1 = b - (b-a)/l
yval = np.linspace(-4, 4, 100)
x2 = a + (b-a)/l
x, y = np.meshgrid(xval, yval)
if (R(x1) >= R(x2)):
z = f(x, y)
a = x1
surf = ax.plot_surface(x, y, z, rstride = 2,cstride = 2,cmap = cm.viridis)
else: b = x2
plt.show()
i=i+1
x = (a+b)/2
return x
def f(x):
y = 1.8*(x[0]**2)+1.8*(x[1]**2)+1.3*sin(x[0]+2.8*x[0]*x[1]+x[1])
return y
def SteepestDescent(x1,x2,h,g,eps):
i=0
while grad_fabs(x1, x2, g) > eps and i < 10000:
def F(x1, x2):
X = np.array([x1, x2])
y = 1.8*(x1*x1)+1.8*(x2*x2)+1.3*sin(x1+2.8*x1*x2+x2)
G = optimize.approx_fprime(X, f, epsilon=1e-6)
return y
def R(h):
return F(x1 - h*G[0],x2 - h*G[1])
h = Gold(R, 0, 2, eps)
def grad_fabs(x1, x2, g):
x1 = x1 - h*G[0]
R1 = F(x1+g, x2)
x2 = x2 - h*G[1]
R2 = F(x1-g, x2)
i=i+1
R3 = F(x1, x2+g)
y = F(x1, x2)
R4 = F(x1, x2-g)
res = "x1 = " + str(("%.5f") % x1) + "\nx2 = " + str(("%.5f") % x2) + \
p1 = (R1-R2)/(2*g)
"\nf(x1,x2) = " + str(("%.5f") % y) + "\ni = " + str(i)
p2 = (R3-R4)/(2*g)
return res
G = sqrt(p1*p1 + p2*p2)
return G
def ConjugateGradient(x1,x2,h,g,eps):
i=0
X0 = np.array([x1, x2]) x1_1 = x2_1
G0 = optimize.approx_fprime(X0, f, epsilon=1e-6) x1_2 = x2_2
X1 = x1 - h*G0[0] X1 = np.array([x1_1, x1_2])
X2 = x2 - h*G0[1] i=i+1
X = np.array([X1, X2]) y = f(X1)
G = optimize.approx_fprime(X, f, epsilon=1e-6) res = "x1 = " + str(("%.5f") % x1_1) + "\nx2 = " + str(("%.5f") % x1_2) + \
while grad_fabs(X1, X2, g) > eps and i < 10000: "\nf(x1,x2) = " + str(("%.5f") % y) + "\ni = " + str(i)
def R(h): return res
return F(X1 - h*G[0], X2 - h*G[1])
h = Gold(R, 0, 2, eps)
alfa = ((norm(G))**2)/((norm(G0))**2)
if (i % 2) == 0: def fbut_1():
grad = G - alfa*G0 root = Tk()
else: root.title("Result")
grad = G root.minsize(width=200, height=50)
X1 = X1 - h*grad[0] lab0 = Label(root, text='Gradient',font="Arial 14").pack()
X2 = X2 - h*grad[1] lab1 = Label(root, text='Result is:').pack()
G0 = G lab2 = Label(root, text=Gradient(0, 0, 0.1, 0.001, 0.001)).pack()
X = np.array([X1, X2]) root.mainloop()
G = optimize.approx_fprime(X, f, epsilon=1e-6)
i=i+1
y = f(X) def fbut_2():
res = "x1 = " + str(("%.5f") % X1) + "\nx2 = " + str(("%.5f") % X2) + \ root = Tk()
"\nf(x1,x2) = " + str(("%.5f") % y) + "\ni = " + str(i) root.title("Result")
return res root.minsize(width=200, height=50)
lab0 = Label(root, text='Steepest Descent',font="Arial 14").pack()
lab1 = Label(root, text='Result is:').pack()
lab2 = Label(root, text=SteepestDescent(0,0,0.1,0.001,0.0001)).pack()
root.mainloop()
def HeavyBall(x0_1,x0_2,h,g,eps,alfa):
i=0
X0 = np.array([x0_1, x0_2]) def fbut_3():
G0 = optimize.approx_fprime(X0, f, epsilon=1e-6) root = Tk()
x1_1 = x0_1 - h*G0[0] root.title("Result")
x1_2 = x0_2 - h*G0[1] root.minsize(width=200, height=50)
X1 = np.array([x1_1, x1_2]) lab0 = Label(root, text='Conjugate Gradient',font="Arial 14").pack()
G = optimize.approx_fprime(X1, f, epsilon=1e-6) lab1 = Label(root, text='Result is:').pack()
while grad_fabs(x1_1, x1_2, g) > eps and i < 10000: lab2 = Label(root, text=ConjugateGradient(0,0,0.1,0.001,0.0001)).pack()
def R(h): root.mainloop()
return F(x1_1 - h*G[0], x1_2 - h*G[1])
h = Gold(R, 0, 2, eps)
x2_1 = x1_1 - alfa*(x1_1 - x0_1) - h*G[0] def fbut_4():
x2_2 = x1_2 - alfa*(x1_2 - x0_2) - h*G[1] root = Tk()
X2 = np.array([x2_1, x2_2]) root.title("Result")
G = optimize.approx_fprime(X2, f, epsilon=1e-6) root.minsize(width=200, height=50)
x0_1 = x1_1 lab0 = Label(root, text='Heavy Ball',font="Arial 14").pack()
x0_2 = x1_2 lab1 = Label(root, text='Result is:').pack()
lab2 = Label(root, text=HeavyBall(0,0,0.1,0.001,0.0001,0.1)).pack() root.title("Menu")
root.mainloop() root.minsize(width=200, height=40)
lab = Label(root, text='Choose the method:').pack()
but_1 = Button(root, text="Gradient", width=20, command=fbut_1).pack()
def Built_in(x1,x2): but_2 = Button(root, text="Steepest Descent", width=20, command=fbut_2).pack()
x = np.array([x1,x2]) but_3 = Button(root, text="Conjugate Gradient", width=20,
built_in = optimize.minimize(f, x,options={'gtol': 1e-6, 'disp': True}) command=fbut_3).pack()
res = "x1 = {xx1} \n x2 = {xx2} \nf(x1,x2) = {yy}".format(xx1="%.5f" % but_4 = Button(root, text="Heavy Ball", width=20, command=fbut_4).pack()
built_in.x[0],xx2="%.5f" % built_in.x[1],yy="%.5f" % built_in.fun) but_5 = Button(root, text="Built-in function", width=20, command=fbut_5).pack()
return res but_6 = Button(root, text="Graph", width=20, command=graph).pack()
root.mainloop()

def fbut_5():
root = Tk()
root.title("Result")
root.minsize(width=200, height=50)
lab0 = Label(root, text='Built-in function',font="Arial 14").pack()
lab1 = Label(root, text='Result is:').pack()
lab2 = Label(root, text=Built_in(0,0)).pack()
root.mainloop()

root = Tk()

Вывод: в ходе выполнения лабораторной работы было выполнено знакомство с оптимизационными задачами, изучение
различных методов многомерной оптимизации и сравнение эффективности их применения для конкретных целевых
функций.