Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №4.docx
Скачиваний:
0
Добавлен:
25.06.2025
Размер:
1.92 Mб
Скачать

Расчетные таблицы при Поиск по образцу

ɛ

N

l

21.6172

-21.3516

-837.557

77

18

0.0221028

21.6318

-21.3662

-837.558

97

23

0.00146876

21.6337

-21.3668

-837.558

117

28

0.000501258

21.6332

-21.3669

-837.558

153

37

2.57625e-005

21.6332

-21.3668

-837.558

181

44

1.45411e-006

Симплекс-регулярный

ɛ

N

l

19.8594

-19.5742

-831.163

104

85

2.52187

21.3315

-21.0684

-837.377

198

173

0.424339

21.5943

-21.3284

-837.555

289

258

0.0546825

21.6332

-21.3668

-837.558

469

430

1.89652e-005

21.6332

-21.3668

-837.558

483

438

2.44035e-005

Метод конфигураций

ɛ

N

l

21.6318

-21.3613

-837.556

187

18

0.00566442

21.6318

-21.3613

-837.556

211

18

0.00566442

21.633

-21.3665

-837.558

300

24

0.000401662

21.6332

-21.3668

-837.558

381

30

2.90569e-005

21.6332

-21.3668

-837.558

443

34

2.60567e-006

Циклический покоординатный спуск

ɛ

N

l

17.3105

-17.0645

-800.322

4217

154

6.09881

21.2992

-21.0348

-837.336

15019

408

0.470946

21.6318

-21.3651

-837.558

31423

746

0.00215164

21.6289

-21.3626

-837.558

43707

842

0.00604765

21.6328

-21.3665

-837.558

67638

1092

0.0004969

Траектория движения точек

Поиск по образцу

Симплекс-регулярный

Метод конфигураций

Метод покоординатного цикличного спуска

Код программы:

#include <stdafx.h>

#include <iostream>

#include <Windows.h>

#include <algorithm>

#include <math.h>

#include <iomanip>

#include <conio.h>

#include <stdlib.h>

using namespace std;

const int iteration = 5;

const double const_x1 = 1.0, const_x2 = 1.0;

const double rasch_x1 = 21.6331659, rasch_x2 = -21.3668342;

double f(double x1, double x2) {

return 100 * pow(x1, 2) + 198 * x1 * x2 + 100 * pow(x2, 2) - 96 * x1 - 10 * x2 + 94;

}

double f_dx1(double x1, double x2) {

double dfx1;

dfx1 = 200 * x1 + 198 * x2 - 96;

return dfx1;

}

double f_dx2(double x1, double x2) {

double dfx2;

dfx2 = 198 * x1 + 200 * x2 - 10;

return dfx2;

}

void obr();

void simplex();

void config();

void pokoord();

void function_find_lymbda_1(double x1, double x2, double eps, double& lymbda, int& N_0);

void function_find_lymbda_2(double x1, double x2, double eps, double& lymbda, int& N_0);

int main() {

SetConsoleOutputCP(1251);

cout << left;

int j;

while (1) {

system("CLS");

cout << "\n\t1. \"Поиск по образцу\"";

cout << "\n\t2. \"Симплекс-регулярный\"";

cout << "\n\t3. \"Метод конфигурации\"";

cout << "\n\t4. \"Циклический покоординатный спуск\"";

cout << "\n\t0. Выход";

cout << "\n\n\tВвод: ";

cin >> j;

cout << "\n\n\n";

switch (j) {

case 1:

obr();

cout << endl << endl;

system("pause");

break;

case 2:

simplex();

cout << endl << endl;

system("pause");

break;

case 3:

config();

cout << endl << endl;

system("pause");

break;

case 4:

pokoord();

cout << endl << endl;

system("pause");

break;

case 0:

exit(0);

break;

default:

continue;

break;

}

cout << endl << endl;

}

cin.get();

cin.clear();

cin.ignore(2018, '\n');

cout << endl << endl;

exit(0);

}

void obr() { //Поиск по образцу

cout << "\n\n\tПоиск по образцу";

double eps, culc_x1, culc_x2, culc_y, eps_fact;

int N, l;

double h, y[5], x1[5], x2[5];

int k;

cout << "\n\tВведите eps ";

cin >> eps;

h = 10.0;

k = 0;

x1[0] = const_x1;

x2[0] = const_x2;

y[0] = f(x1[0], x2[0]);

N = 1;

l = 0;

while (1) {

x1[1] = x1[0] + h;

x1[2] = x1[0] + h;

x1[3] = x1[0] - h;

x1[4] = x1[0] - h;

x2[1] = x2[0] + h;

x2[2] = x2[0] - h;

x2[3] = x2[0] - h;

x2[4] = x2[0] + h;

for (int i = 1; i <= 4; i++) {

y[i] = f(x1[i], x2[i]);

if (i == 1 || y[k] > y[i]) k = i;

}

N += 4;

if (y[k] < y[0]) {

x1[0] = x1[k];

x2[0] = x2[k];

y[0] = y[k];

}

else if ((sqrt(2.0) * h) > eps)h /= 2.0;

else break;

l++;

}

culc_x1 = x1[0];

culc_x2 = x2[0];

culc_y = f(culc_x1, culc_x2);

eps_fact = sqrt(pow((culc_x1 - rasch_x1), 2) + pow((culc_x2 - rasch_x2), 2));

cout << "\neps = " << eps << "\nx_rasch = " << culc_x1 << "\ny_rasch = " << culc_x2 << "\ny_rasch = " << culc_y << "\nN = " << N << "\nl = " << l << "\neps_fact = "<< eps_fact;

}

void simplex() { //Симплекс-регулярный

cout << "\n\n\tСимплекс-регулярный";

double eps, culc_x1, culc_x2, culc_y, eps_fact;

int N, l;

double r, y[3], x1[3], x2[3], c1, c2, u1, u2, y_tmp;

int k_max, k_min;

cout << "\n\tВведите eps ";

cin >> eps;

k_min = 0;

k_max = 0;

x1[0] = const_x1;

x2[0] = const_x2;

r = 15;

l = 0;

x1[1] = x1[0] + r;

x1[2] = x1[0];

x2[1] = x2[0];

x2[2] = x2[0] + r;

y[0] = f(x1[0], x2[0]);

y[1] = f(x1[1], x2[1]);

y[2] = f(x1[2], x2[2]);

N = 3;

while (fabs(r) > eps) {

for (int i = 0; i <= 2; i++) {

if (y[k_min] > y[i]) k_min = i;

if (y[k_max] < y[i]) k_max = i;

}

c1 = 0.5 * (x1[0] + x1[1] + x1[2] - x1[k_max]);

c2 = 0.5 * (x2[0] + x2[1] + x2[2] - x2[k_max]);

u1 = 2.0 * c1 - x1[k_max];

u2 = 2.0 * c2 - x2[k_max];

y_tmp = f(u1, u2);

N++;

if (y_tmp < y[k_max]) {

x1[k_max] = u1;

x2[k_max] = u2;

y[k_max] = y_tmp;

}

else {

for (int i = 0; i <= 2; i++) {

x1[i] = (x1[i] + x1[k_max]) / 2.0;

x2[i] = (x2[i] + x2[k_max]) / 2.0;

y[i] = f(x1[i], x2[i]);

}

N += 2;

r /= 2.0;

}

l++;

}

culc_x1 = x1[k_min];

culc_x2 = x2[k_min];

culc_y = f(x1[k_min], x2[k_min]);

eps_fact = sqrt(pow((culc_x1 - rasch_x1), 2.0) + pow((culc_x2 - rasch_x2), 2.0));

cout << "\neps = " << eps << "\nx_rasch = " << culc_x1 << "\ny_rasch = " << culc_x2 << "\ny_rasch = " << culc_y << "\nN = " << N << "\nl = " << l << "\neps_fact = "<< eps_fact;

}

void config() { //Метод конфигурации

cout << "\n\n\tМетод конфигурации";

double eps, culc_x1, culc_x2, culc_y, eps_fact;

int N, l;

double h, lymbda, x1L, x2L, x1L1, x2L1, x1L2, x2L2, y0, y1, y2, y3;

double y[3][3];

cout << "\n\tВведите eps ";

cin >> eps;

l = 0;

y0 = f(const_x1, const_x2);

N = 1;

x1L = x1L1 = const_x1;

x2L = x2L1 = const_x2;

h = 0.4;

while (1) {

x1L = x1L1;

x2L = x2L1;

y[0][0] = f((x1L - h), (x2L + h));

y[0][1] = f((x1L), (x2L + h));

y[0][2] = f((x1L + h), (x2L + h));

y[1][0] = f((x1L - h), (x2L));

y[1][1] = f((x1L), (x2L));

y[1][2] = f((x1L + h), (x2L));

y[2][0] = f((x1L - h), (x2L - h));

y[2][1] = f((x1L), (x2L - h));

y[2][2] = f((x1L + h), (x2L - h));

N += 8;

y1 = y2 = y[1][1];

for (int i = 0; i < 3; i++)

for (int j = 0; j < 3; j++)

if (y[i][j] < y2) {

y2 = y[i][j];

if (j == 0)x1L1 = x1L - h;

else if (j == 1)x1L1 = x1L;

else x1L1 = x1L + h;

if (i == 0)x2L1 = x2L + h;

else if (i == 1)x2L1 = x2L;

else x2L1 = x2L - h;

}

if (x1L1 == x1L && x2L1 == x2L)

if (h > eps) h /= 2.0;

else break;

else {

lymbda = 1000.0;

do {

x1L2 = x1L + lymbda * (x1L1 - x1L);

x2L2 = x2L + lymbda * (x2L1 - x2L);

y3 = f(x1L2, x2L2);

N++;

lymbda /= 2.0;

} while (y3 >= y2);

x1L1 = x1L2;

x2L1 = x2L2;

l += 2;

y0 = y3;

}

}

culc_x1 = x1L;

culc_x2 = x2L;

culc_y = f(culc_x1, culc_x2);

eps_fact = sqrt(pow((culc_x1 - rasch_x1), 2.0) + pow((culc_x2 - rasch_x2), 2.0));

cout << "\neps = " << eps << "\nx_rasch = " << culc_x1 << "\ny_rasch = " << culc_x2 << "\ny_rasch = " << culc_y << "\nN = " << N << "\nl = " << l << "\neps_fact = "<< eps_fact;

}

void pokoord() { //Циклический покоординатный спуск

cout << "\n\n\tЦиклический покоординатный спуск";

double eps, culc_x1, culc_x2, culc_y, eps_fact;

int N, l, N_0, N_1;

double x1L, x1L1, x1L2, x2L, x2L1, x2L2, lymbda, d;

cout << "\n\tВведите eps ";

cin >> eps;

N_0 = 0;

N_1 = 0;

l = 0;

x1L = const_x1;

x2L = const_x2;

do {

function_find_lymbda_1(x1L, x2L, eps, lymbda, N_0);

x1L1 = x1L + lymbda;

x2L1 = x2L;

function_find_lymbda_2(x1L1, x2L1, eps, lymbda, N_0);

x1L2 = x1L1;

x2L2 = x2L1 + lymbda;

d = sqrt(pow((x1L2 - x1L), 2.0) + pow((x2L2 - x2L), 2.0));

l += 2;

x1L = x1L2;

x2L = x2L2;

} while (d > eps);

culc_x1 = x1L;

culc_x2 = x2L;

culc_y = f(culc_x1, culc_x2);

N = N_0 + N_1;

eps_fact = sqrt(pow((culc_x1 - rasch_x1), 2.0) + pow((culc_x2 - rasch_x2), 2.0));

cout << "\neps = " << eps << "\nx_rasch = " << culc_x1 << "\ny_rasch = " << culc_x2 << "\ny_rasch = " << culc_y << "\nN = " << N << "\nl = " << l << "\neps_fact = "<< eps_fact;

}

void function_find_lymbda_1(double x1, double x2, double eps, double& lymbda, int& N_0) {

double lymbda_1, lymbda_2, y_2, y_1;

double h = 50.0;

lymbda_1 = 0.0;

y_1 = f(x1, x2);

N_0++;

while (1) {

while (1) {

lymbda_2 = lymbda_1 + h;

y_2 = f((x1 + lymbda_2), x2);

N_0++;

if (y_1 > y_2) {

lymbda_1 = lymbda_2;

y_1 = y_2;

}

else break;

}

if (fabsl(h) <= eps) {

lymbda = lymbda_1;

break;

}

else {

h /= -4.0;

lymbda_1 = lymbda_2;

y_1 = y_2;

}

}

}

void function_find_lymbda_2(double x1, double x2, double eps, double& lymbda, int& N_0) {

double lymbda_1, lymbda_2, y_2, y_1;

double h = 50.0;

lymbda_1 = 0.0;

y_1 = f(x1, x2);

N_0++;

while (1) {

while (1) {

lymbda_2 = lymbda_1 + h;

y_2 = f(x1, (x2 + lymbda_2));

N_0++;

if (y_1 > y_2) {

lymbda_1 = lymbda_2;

y_1 = y_2;

}

else break;

}

if (fabsl(h) <= eps) {

lymbda = lymbda_1;

break;

}

else {

h /= -4.0;

lymbda_1 = lymbda_2;

y_1 = y_2;

}

}

}

Блок – схемы:

Блок – схема метода поиска по образцу

Блок – схема метода симплекс - регулярного

Блок -схема метода конфигураций

Блок – схема метода циклического покоординатного спуска

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