0 / 0 / 0
Регистрация: 19.08.2010
Сообщений: 22
|
|
1
|
Оптимизация функции двух переменных
28.05.2013, 14:52. Показов 3130. Ответов 0
Доброго времени суток! Помогите пожалуйста решить задачу:
Дана функция -2*x*x+3*x*y-5*y*y+3*y, нужно её оптимизировать
Я вот вроде как методом градиента делаю, но программа зацикливается(читал - по всей видимости, у меня "овраг")
Как с этим бороться?
Кликните здесь для просмотра всего текста
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| #include <stdio.h>
#include <conio.h>
#include <math.h>
#include<iostream>
#define N 2// количество переменных
double x_k[N];//неизвестные
double x_k_1[N];//значение последвательного приближения
double lambda_k;//шаг
double y(double *x, int n)
{
return (-2*pow(x[0],2)+3*x[1]*x[0] - 5*x[1]*x[1]+3*x[1]); //функция
}
double dy_dx0(double *x, int n) // первая частная производная по Х
{
return (-4*x[0]+3*x[1]-3);
}
double dy_dx1(double *x, int n) // первая частная производная по Y
{
return (3*x[0]-10*x[1]+3);
}
double dy2_dx0(double *x, int n)// 2-я частная производная по X
{
return (-4);
}
double dy2_dx1(double *x, int n)// 2-я частная производная по Y
{
return (-10);
}
int main(void)
{
setlocale(LC_CTYPE, "Russian");
lambda_k = 0.001;//шаг
x_k[0] = 0;//начальное
x_k[1] = 5;//приближение
while(1)//будет длится до конца интервала
{
x_k_1[0] = x_k[0]- lambda_k*dy_dx0(x_k, N) ;//последвательное
x_k_1[1] = x_k[1]-lambda_k*dy_dx1(x_k, N);//приближение
if(fabs(dy_dx0(x_k_1, N))>lambda_k && fabs(dy_dx1(x_k_1, N))<lambda_k) break;//условие при котором меняются значения меняется начальное и конечное значение промежутка
x_k[0] = x_k_1[0];//присвоение начальному значению
x_k[1] = x_k_1[1];//значение приближения
}
x_k[0] = x_k_1[0];
x_k[1] = x_k_1[1];
printf("\tГрадиентный метод:\n");
printf("\tМинимум найден на x1 =%.3lf, x2 =%.3lf, Y(X1,X2) =%3.3f\n", x_k[0], x_k[1], y(x_k, N));//Вывод минимальных точек и значения функции в этой точке
getch();
return 0;
} |
|
Добавлено через 17 часов 36 минут
Всё, уже разобрался: это не овраг. Кому интересно:
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| #include <stdio.h>
#include <conio.h>
#include <math.h>
#include<iostream>
#define N 2// количество переменных
double x_k[N];//неизвестные
double x_k_1[N];//значение последвательного приближения
double lambda_k;//шаг
double y(double *x, int n)
{
return (-2*pow(x[0],2)+3*x[1]*x[0]-5*x[1]*x[1]+3*x[1]); //функция
}
double dy_dx0(double *x, int n) // первая частная производная по Х
{
return (-4*x[0]+3*x[1]);
}
double dy_dx1(double *x, int n) // первая частная производная по Y
{
return (3*x[0]-10*x[1]+3);
}
double dy2_dx0(double *x, int n)// 2-я частная производная по X
{
return (-4);
}
double dy2_dx1(double *x, int n)// 2-я частная производная по Y
{
return (-10);
}
int main(void)
{
setlocale(LC_CTYPE, "Russian");
lambda_k = 0.00001;//шаг
x_k[0] = 1;//начальное
x_k[1] = 1;//приближение
while(1)//будет длится до конца интервала
{
x_k_1[0] = x_k[0]+lambda_k*dy_dx0(x_k, N) ;//последвательное
x_k_1[1] = x_k[1]+lambda_k*dy_dx1(x_k, N);//приближение
if(fabs(dy_dx0(x_k_1, N))<lambda_k && fabs(dy_dx1(x_k_1, N))<lambda_k) break;//условие при котором меняются значения меняется начальное и конечное значение промежутка
x_k[0] = x_k_1[0];//присвоение начальному значению
x_k[1] = x_k_1[1];//значение приближения
}
x_k[0] = x_k_1[0];
x_k[1] = x_k_1[1];
printf("\tГрадиентный метод:\n");
printf("\tМинимум найден на x1 =%.3lf, x2 =%.3lf, Y(X1,X2) =%3.3f\n", x_k[0], x_k[1], y(x_k, N));//Вывод минимальных точек и значения функции в этой точке
getch();
return 0;
} |
|
0
|