
ЛР_3
.pdfГУАП
КАФЕДРА № 41
ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ
ПРЕПОДАВАТЕЛЬ
ассистент |
|
|
|
Б. К. Акопян |
|
|
|
|
|
должность, уч. степень, звание |
|
подпись, дата |
|
инициалы, фамилия |
ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №3
Решение одномерной задачи оптимизации
по курсу: ПРИКЛАДНЫЕ МЕТОДЫ ОПТИМИЗАЦИИ
РАБОТУ ВЫПОЛНИЛ |
|
|
|
|
|
|
СТУДЕНТ ГР. № |
4017 |
|
|
|
Т. А. Михайлова |
|
|
|
|
|
подпись, дата |
|
инициалы, фамилия |
Санкт-Петербург, 2023г.

Цель работы:
изучение алгоритмов поиска экстремума унимодальной функции, определение срав-
нительной эффективности методов одномерной оптимизации
Задание:
реализовать алгоритмы каждого из описанных методов поиска экстремума функции в указанном интервале с требуемой погрешностью в соответствии с вариантом задания, рас-
считать значения критерия оптимальности каждого из алгоритмов.
Мой вариант 9, задание взято из методички (рисунок 1).
Рисунок 1 – Задание по варианту
Теоретические сведения:
Метод равномерного поиска простейший из методов поиска значений действительно-значных функций по ка-
кому-либо из критериев сравнения (на максимум, на минимум, на определённую кон-
станту). Применительно к экстремальным задачам является примером прямого метода условной одномерной пассивной оптимизации.
Метод дихотомии раздвоенность, последовательное деление на две части, более связанные внутри,
чем между собой. Способ логического деления класса на подклассы, который состоит в том,
что делимое понятие полностью делится на два взаимоисключающих понятия. Дихотоми-
ческое деление в математике, философии, логике и лингвистике является способом образо-
вания подразделов одного понятия или термина и служит для образования классификации элементов.
Метод золотой пропорции метод поиска экстремума действительной функции одной переменной на заданном
отрезке. В основе метода лежит принцип деления отрезка в пропорциях золотого сечения.
Является одним из простейших вычислительных методов решения задач оптимизации.
Единственное в своём роде отношение частей и целого, при котором отношения частей между собой и каждой части к целому равны.
2

Метод Фибоначчи это улучшение реализации поиска с помощью золотого сечения, служащего для
нахождения минимума/максимума функции. Подобно методу золотого сечения, он требует двух вычислений функции на первой итерации, а на каждой последующей только по од-
ному. Однако этот метод отличается от метода золотого сечения тем, что коэффициент со-
кращения интервала неопределенности меняется от итерации к итерации.
После этого написала код (Листинг 1) для вычисления данных мне задач. Результаты
(Рисунки 2-3).
Рисунок 2 – Результаты различных методов
Рисунок 3 – Сравнение различных методов
Вывод: изучила алгоритм поиска экстремума унимодальной функции с помощью 4
способов: метода равномерного поиска, метода дихотомии, метода золотой пропорции и метода Фибоначчи. После данных исследований провела сравнение эффективности данных методов.
3

Листинг 1 – Расчет числа итераций для каждого метода
from matplotlib import pyplot as plt from math import *
eps = [2 ** (-i) for i in range(1, 17)] # Генератор для последовательнсти постоянно уменьшающегося эпсилон
#исследуемая функция F(x) = cos(x-2*pi/3) def Func(x):
return cos(x-(2*pi/3))
#Метод равномерного поиска
def UniformSearch(left, right): for i in eps:
step = 0 x = 0
tempLeft,tempRight = left,right #заводим временные переменные,
указывающие на левый и правый край области в которой производится поиск (для всех методов одинаково)
while (abs(tempRight-tempLeft) > i): #ищем значение пока область нахождения не станеет меньеш либо равно эпсилон
first = Func(tempLeft) #получаем значение слева от области tempLeft += i #Увеличиваем левый край на эпсилон
second = Func(tempLeft) #получаем значение слева + эпсилон if first > second: # Если значение f(x) > f(x+e) (т.е функция
уменьшается на отрезке)
x = tempLeft #указываем новое значение координаты мини-
мума
step += 1
yield [x, tempRight, step] #возвращаем строку данных, указывающую левый край области, правый край области, и количество итерация для нахождения это области
def DihotomialSearch(left, right): for i in eps:
step = 0
tempLeft,tempRight = left,right while (abs(tempRight-tempLeft) > i):
n = (tempLeft + tempRight) / 2 #получаем области
4

x = [n-i, n+i] #получаем значения функции слева и справа на эпсилон от этой функции
values = [Func(j) for j in x]
if (values[0] < values[1]): # если значения слева меньше зна-
чения справа - сдвигаем правый край, иначе сдвигаем левый tempRight = n
else:
tempLeft = n step += 1
yield [tempLeft, tempRight, step]
def grf(left, right):
return [left + (right-left)*0.382, left + (right - left)*0.618]
def GolderRationSearch(left, right): for i in eps:
step = 0
tempLeft,tempRight = left,right while (abs(tempRight-tempLeft) > i):
x = grf(tempLeft, tempRight) #получаем значения функции слева и справа на расстоянии согласно золотой пропорции
values = [Func(j) for j in x]
if (values[0] < values[1]): # если значение слева меньше зна-
чения справа сдвигаем правый край, иначе сдвигаемл левый tempRight = x[1]
else:
tempLeft = x[0] step += 1
yield [tempLeft, tempRight, step]
def FibonacciSearch(left, right): for i in eps:
step = 1 fib = [1, 1]
tempLeft,tempRight = left,right
while ((tempRight-tempLeft) / fib[-1] > i): #Заполняем последо-
вательность фиббоначи пока результат деления расстояния области на последний член последовательности не станет меньше чем эпсилон
fib.append(fib[-2]+fib[-1]) while (abs(tempLeft-tempRight) > i):
5

n = len(fib)-1 #Получаем тек. длину последвоательности фибо-
наччи
x = [tempLeft+(tempRight-tempLeft)*(fib[n-step-1]/fib[n- step+1]), #находим значения функции слева и справа, для точек высчитанных по методу фибонначии
tempLeft+(tempRight-tempLeft)*(fib[n-step]/fib[n-
step+1])]
values = [Func(j) for j in x]
if (values[0] > values[1]): #если значения слева больше зна-
чения справа, то сдвигаем левый край, иначе сдвигаем правый tempLeft = x[0]
else:
tempRight = x[1] step += 1
yield [tempLeft,tempRight,step-1]
def PrintData(algoName,data):
print(f"{algoName}:\n Left={data[0]}, Right={data[1]}, Steps={data[2]}")
def InitPlot(): # Создаем окно, настраиваем оси, выставляем размер plt.figure(figsize=(24,16))
plt.ylim([0,100])
plt.xscale('log',base=2) plt.xlabel('Эпсилон') plt.ylabel("Кол-во итераций")
def DrawPlot(algoName,data): #Отрисовываем в окне график по переданному сету данных
plt.plot(eps,[row[2] for row in data],label=algoName)
#Отрисовываем переданный сет данных на консоли и в окне def OutInfo(algoName,data):
PrintData(algoName,data[-1])
DrawPlot(algoName,data)
def main():
l,r = -5*pi/3,-2*pi/3 #указываем левый и правый край (по варианту) usData = list(UniformSearch(l,r)) #получаем значения для равномерного
поиска
dihData = list(DihotomialSearch(l,r)) #дихотомия
6

grData = list(GolderRationSearch(l,r)) #золтое сечение fibData = list(FibonacciSearch(l,r)) #Фибоначчи
InitPlot()# Инициализируем график
#Выводим данные о всех методах
OutInfo('Метод равномерного поиска',usData)
OutInfo('Метод дихтомии',dihData)
OutInfo('Метод золотой пропорции',grData)
OutInfo('Метод Фибоначчи',fibData)
#Отображаем легенду и отрисовываем окно plt.legend()
plt.show()
#вызов главной функции
main()
7