Текст подпрограммы и версий mnb3r_c.zip |
Тексты тестовых примеров tmnb3r_c.zip |
Решение задачи безусловной минимизации диффеpенциpуемой функции многих переменных методом Флетчера - Ривса.
Для решения задачи: min f (x) , x ∈ En используется метод Флетчера - Ривса. Некоторая вычисленная точка x* ∈ En считается точкой безусловного минимума функции f (x), если || f ' (x*)||2 ≤ EPS , где f ' (x*) - градиент функции f (x) в точке x*, а EPS - заданная точность вычисления минимума по гpадиенту. Если
n ∑ | xjk - xjk-1 | ≤ EPS , j= 1
где k - номеp итерации метода, и в то же время || f ' (x k)||2 > EPS , то считается, что для заданной функции алгоритм не может обеспечить сходимость с точностью EPS.
Для одномерной минимизации функции f (x) вдоль направления спуска используется метод кубической аппроксимации.
Д.Химмельблау, Прикладное нелинейное программирование. Изд - во "Мир", M., 1975.
int mnb3r_c (integer *n, integer *m, real *x1, real *f, real *g, real *est, real *eps, integer *limit, integer *ierr, real *h, integer *kount, S_fp fun, S_fp grad)
Параметры
n - | размерность пространства переменных (тип: целый); |
m - | целочисленная переменная, равная 2 * n; |
x1 - | вещественный вектоp длины n: при обращении к подпрограмме содержит заданную начальную точку поиска, на выходе содержит точку минимального вычисленого значения f (x); |
f - | вещественная переменная, содержащая вычисленное минимальное значение функции f (x); |
g - | вещественный вектоp длины n, содержащий градиент функции f (x) в вычисленной точке минимума; |
est - | заданное приближенное значение безусловного минимума функции f (x) (см. замечания по использованию) (тип: вещественный); |
eps - | заданная точность вычисления минимума по градиенту (тип: вещественный); |
limit - | заданное максимальное допустимое число итераций метода (тип: целый); |
ierr - | целочисленная переменная, указывающая пpичину окончания процесса: |
ierr= -1 - | нет сходимости; |
ierr= 0 - | найден минимум с заданной точностью; |
ierr= 1 - | выполнено limit итераций; |
ierr= 2 - | установлено, что в некотоpом направлении функция f (x) не имеет минимума; |
h - | вещественный вектоp длины m, используемый в подпрограмме как рабочий; |
kount - | целая переменная, содержащая фактически выполненное число итераций метода; |
fun - | имя подпрограммы вычисления значения функции f (x) (см. замечания по использованию); |
grad - | имя подпрограммы вычисления градиента функции f (x) (см. замечания по использованию). |
Версии: нет
Вызываемые подпрограммы: нет
Замечания по использованию
Оценка est минимального значения функции f (x) используется в пpоцедуpе одномерной минимизации по направлению. Если приближенное значение минимума можно указать, то это ускоpит процесс минимизации. В противном случае можно положить est = 0.0. Подпрограммы fun и grad составляются пользователем. Первый оператор подпрограммы вычисления функции должен иметь вид: int fun(float *x, float *f, float *fe) Параметры x1 - вещественный вектор n длины задающий точку пространства, в которой вычисляется значение функции; f - вещественная переменная, содержащая вычисленное значение функции в точке x1; fe - заданная точность вычисления значения функции в точке x1 (тип: вещественный); Параметр fe не должен переопределяться в теле подпрограммы fun и может не использоваться для вычисления f (x). Первый оператор подпрограммы вычисления градиента функции f (x)должен иметь вид: int grad(float *x, float *g, float *ge, int *i0) Параметры x1 - вещественный вектор n длины задающий точку пространства, в которой вычисляется градиент; g - вещественный вектоp длины n, содержащий вычисленный градиент функции в точке x1; ge - заданная точность вычисления компонент градиента (тип: вещественный); io - целочисленная переменная, используемая как рабочая. Параметры ge и io не должны переопределяться в теле подпрограммы grad и могут не использоваться для вычисления градиента. Имена подпрограммы вычисления значения функции f (x) и ее градиента должны быть определены в вызывающей программе оператором extern. |
min f(x) , x ∈ E4 . f(x) = 100 ( x2 - x12 )2 + (1 - x1)2 + 90 (x4 - x3)2 + (1 - x3)2 + + (1 - x3)2 + 10.1 ( (x2 - 1)2 + (x4 - 1)2 ) + 19.8 (x2 - 1) (x4 - 1) . Точка абсолютного минимума x* = (1., 1., 1., 1.) , f(x*) = 0.int main(void) { /* Initialized data */ static int n = 4; static int limit = 100; static float x[4] = { -3.f,-1.f,-3.f,-1.f }; /* Local variables */ extern int grad_c(), func_c(); static int ierr; extern int mnb3r_c(int *, int *, float *, float *, float *, float *, float *, int *, int *, float *, int *, U_fp, U_fp); static float f, g[4], h__[8]; static int m, kount; static float eps, est; eps = 1e-11f; est = 0.f; m = n << 1; mnb3r_c(&n, &m, x, &f, g, &est, &eps, &limit, &ierr, h__, &kount, (U_fp)func_c, (U_fp)grad_c); printf("\n %5i \n", ierr); printf("\n %16.7e \n", f); printf("\n %16.7e %16.7e %16.7e %16.7e \n", x[0], x[1], x[2], x[3]); /* l100: */ printf("\n %5i \n", kount); return 0; } /* main */ int func_c(float *x, float *f, float *fe) { /* System generated locals */ float r__1, r__2, r__3, r__4, r__5, r__6, r__7, r__8; /* Parameter adjustments */ --x; /* Function Body */ /* Computing 2nd power */ r__2 = x[1]; /* Computing 2nd power */ r__1 = x[2] - r__2 * r__2; /* Computing 2nd power */ r__3 = 1.f - x[1]; /* Computing 2nd power */ r__5 = x[3]; /* Computing 2nd power */ r__4 = x[4] - r__5 * r__5; /* Computing 2nd power */ r__6 = 1.f - x[3]; /* Computing 2nd power */ r__7 = x[2] - 1.f; /* Computing 2nd power */ r__8 = x[4] - 1.f; *f = r__1 * r__1 * 100.f + r__3 * r__3 + r__4 * r__4 * 90.f + r__6 * r__6 + (r__7 * r__7 + r__8 * r__8) * 10.1f + (x[2] - 1.f) * 19.8f * (x[4] - 1.f); return 0; } /* func_c */ int grad_c(float *x, float *g, float *ge, int *i0) { /* System generated locals */ float r__1; /* Parameter adjustments */ --g; --x; /* Function Body */ /* Computing 2nd power */ r__1 = x[1]; g[1] = x[1] * -400.f * (x[2] - r__1 * r__1) - (1.f - x[1]) * 2.f; /* Computing 2nd power */ r__1 = x[1]; g[2] = (x[2] - r__1 * r__1) * 200.f + (x[2] - 1.f) * 20.2f + (x[4] - 1.f) * 19.8f; /* Computing 2nd power */ r__1 = x[3]; g[3] = x[3] * -360.f * (x[4] - r__1 * r__1) - (1 - x[3]) * 2.f; /* Computing 2nd power */ r__1 = x[3]; g[4] = (x[4] - r__1 * r__1) * 180.f + (x[4] - 1.f) * 20.2f + (x[2] - 1.f) * 19.8f; return 0; } /* grad_c */ Результаты: ierr = -1 f = 0.3328214 - 09 x(1) = 1.0000100 + 00 x(2) = 1.0000190 + 00 x(3) = 0.99999060 + 00 x(4) = 0.99998120 + 00 итераций - 62