Подпрограмма: mnn1r_c
Назначение
Решение задачи минимизации функции многих переменных без
вычисления производных при наличии двухсторонних ограничений
на переменные методом покоординатного спуска с построением
аппроксимирующей параболы с использованием метода
Хука - Дживса.
Математическое описание
Для решения задачи
min f (x) ,
Q = { x: x ∈ En , aj ≤ xj ≤ bj , aj > - ∞ , bj < ∞ , j = 1, ..., n } ,
используется метод покоординатного спуска с построением
аппроксимирующей параболы.
Точка xk ∈ Q
считается точкой минимума f (x) на Q, если
выполнено хотя бы одно из следующих условий:
1.
|
| xjk - xjk - 1 | ≤ EPSX j
для всех j = 1, ..., n, где
xk = (x1k, ..., xnk) -
точка, полученная на k - ой итерации метода,
а EPSX - заданный вектоp точности решения задачи по аргументу;
|
2.
|
| f (xk) - f (xk - 1) | ≤ EPSF,
где xk - точка, вычисленная на
k - ой итерации метода, а EPSF - заданная
точность решения задачи по функционалу;
|
3.
|
NF > KMAX, где NF - фактически выполненное число
вычислений функции, KMAX - заданное максимально допустимое
число вычислений функции.
|
Использование
int mnn1r_c (integer *n, real *x, real *xe, real *a, real *b,
S_fp fun, real *f, real *fe, real *up, integer *i0, integer *irm,
real *rm, integer *ierr)
Параметры
n -
|
размерность пространства переменных (тип: целый);
|
x -
|
вещественный вектоp длины n, содержащий на входе
заданную начальную точку поиска, на выходе -
точку минимума функции f (x);
|
xe -
|
вещественный вектоp длины n, содержащий заданную
абсолютную точность решения задачи по аргументу;
|
a -
|
вещественный вектоp длины n, задающий
ограничения снизу на переменные;
|
b -
|
вещественный вектоp длины n, задающий
ограничения свеpху на переменные;
|
fun -
|
имя подпрограммы вычисления функции f (x);
|
f -
|
вещественная переменная, содержащая вычисленное
минимальное значение f (x);
|
fe -
|
заданная абсолютная точность решения задачи по функционалу;
|
up -
|
вещественный вектоp длины 11, задающий
управляющие параметры алгоритма:
|
up(1) -
|
заданная вещественная константа, участвующая в формировании начальной
точности вычисления по аргументу
(up (1) ≥ 1);
|
up(2) -
|
заданная вещественная константа, участвующая в формировании начальной
точности вычисления по функционалу
(up (2) ≥ 1);
|
up(3) -
|
заданная вещественная константа,
используемая при сравнении разностных
производных (0 < up (3) < 1);
|
up(4) -
|
заданная вещественная константа,
участвующая в формировании начального шага
(up (4) > 1);
|
up(5) -
|
заданная вещественная константа,
используемая для изменения величины шага
(константа дробления) (up (5) > 1);
|
up(6) -
|
вещественная константа, участвующая в изменении точности по аргументу,
0 < up (6) < 1;
|
up(7) -
|
вещественная константа, участвующая в
изменении точности вычисления по
функционалу, 0 < up (7) < 1;
|
up(8) -
|
вещественная константа, используемая в качестве "машинного нуля"
(up (8) ≈ 103 * min,
где min - минимально представимое число с плавающей
запятой в машине);
|
up(9) -
|
вещественная константа, используемая
для изменения величины шага (для увеличения шага) (up > 1);
|
up(10) -
|
заданная вещественная константа,
указывающая максимальное время работы подпрограммы;
|
up(11) -
|
вещественная константа, влияющая на
величину шага в подпрограмме mnn09_c
(0.1 < < up (11) < 1);
|
i0 -
|
целый вектоp длины n, задающий фиксированные
компоненты вектоpа переменных
(если i0 (i)= 0,
то x (i) - фиксируется, в противном случае
i0 (i) = 1);
|
irm -
|
целый вектоp длины n, используемый в подпрограмме как рабочий;
|
rm -
|
вещественный вектоp длины 4n;
на входе:
|
rm(1) -
|
заданное максимально допустимое число итераций метода;
|
rm(2) -
|
заданное максимально допустимое число вычислений функции;
|
rm(1) -
|
выполненное число итераций;
|
rm(2) -
|
выполненное число вычислений функции;
|
ierr -
|
целочисленная переменная, указывающая причину
окончания счета:
|
ierr= 1 -
|
если достигнута точность по аргументу;
|
ierr= 2 -
|
если достигнута точность вычисления функции;
|
ierr= 4 -
|
если выполнено заданное число вычислений функции;
|
ierr= 5 -
|
если истекло заданное время вычислений;
|
ierr= 6 -
|
если произошло замедление счета.
|
Версии: нет
Вызываемые подпрограммы: нет
Замечания по использованию
|
Подпрограмма fun составляется пользователем.
Первый оператор вычисления функции должен иметь вид:
int fun(float *x, float *f, float *fe)
Параметры
x - вещественный вектор длины n, содержащий
текущую точку пространства, в которой
вычисляется значение функции;
f - вещественная переменная, содержащая
вычисленное значение функции в точке x;
fe - вещественная переменная, содержащая заданную
точность вычисления значения функции в точке x.
Имя подпрограммы вычисления значения функции должно
быть определено в вызывающей подпрограмме оператором
extern.
Используются служебные подпрограммы mnn02_c, mnn04_c,
mnn05_c, mnn06_c, mnn07_c, mnn08_c, mnn09_c, utmn05_c, mmkrit_c и
внешняя структура с именем mmkric_.
|
Пример использования
Найти минимальное значение функции:
f(x) = (x1 - 1)2 + 10(x2 - 1)2 + 100(x3 - 1)2 + 1000(x4 - 1)2
- 4 ≤ x i ≤ 4 , i = 1, ..., 4 ;
начальное приближение
x0 = ( - 1, - 2, - 3, - 4 )
struct {
float zf;
int kr;
float akr, df[15];
} mmkric_;
#define mmkric_1 mmkric_
int main(void)
{
/* Initialized data */
static float x[4] = { -1.f,-2.f,-3.f,-4.f };
static float a[4] = { -4.f,-4.f,-4.f,-4.f };
static float b[4] = { 4.f,4.f,4.f,4.f };
static float xe[4] = { 1e-5f,1e-5f,1e-5f,1e-5f };
static float fe = 1e-5f;
static int i0[4] = { 1,1,1,1 };
static float up[11] = { 100.f,100.f,.1f,10.f,2.f,.1f,.1f,1e-16f,2.f,20.f,
.8f };
static float rm[30] = { 200.f,200.f };
/* Local variables */
static int ierr;
extern int mnn1r_c(int *, float *, float *, float *, float *, U_fp,
float *, float *, float *, int *, int *, float *,
int *);
static float f;
static int n, irm[4];
extern int fun_c();
n = 4;
mnn1r_c(&n, x, xe, a, b, (U_fp)fun_c, &f, &fe, up, i0, irm, rm, &ierr);
printf("\n %12.4f \n", f);
printf("\n %13.5e \n", fe);
printf("\n %13.5e %13.5e %13.5e %13.5e \n", x[0], x[1], x[2], x[3]);
printf("\n %12.4f %12.4f %12.4f %12.4f \n", xe[0], xe[1], xe[2], xe[3]);
printf("\n %9.1e %9.1e \n", rm[0], rm[1]);
printf("\n %5i \n", ierr);
printf("\n %12.4e \n", up[8]);
return ;
} /* main */
int fun_c(float *x, float *f, float *fe)
{
/* System generated locals */
float r__1, r__2, r__3, r__4;
/* Parameter adjustments */
--x;
/* Function Body */
/* Computing 2nd power */
r__1 = x[1] - 1.f;
/* Computing 2nd power */
r__2 = x[2] - 1.f;
/* Computing 2nd power */
r__3 = x[3] - 1.f;
/* Computing 2nd power */
r__4 = x[4] - 1.f;
*f = r__1 * r__1 + r__2 * r__2 * 10.f + r__3 * r__3 * 100.f +
r__4 * r__4 * 1e3f;
return 0;
} /* fun_c */
Результаты:
f = 0.00000
fe = 0.000010
x = 1.00000, 1.00000, 1.00000, 1.00000
xe = 0.00001, 0.00001, 0.00001, 0.00001
rm(1) = 10
rm(2) = 60
ierr = 12
up = 2.0000
Примечание: ierr=12 означает, что выполнено одновременно два
критерия останова 1 и 2.