|
Документ взят из кэша поисковой машины. Адрес
оригинального документа
: http://num-anal.srcc.msu.ru/lib_na/cat/mn_htm_c/mn06r_c.htm
Дата изменения: Fri Apr 24 07:50:53 2015 Дата индексирования: Sun Apr 10 03:10:47 2016 Кодировка: Windows-1251 |
|
Текст подпрограммы и версий mn06r_c.zip |
Тексты тестовых примеров tmn06r_c.zip |
Решение задачи минимизации функции многих переменных без вычисления производных при наличии двухстоpонних ограничений на переменные методом спуска.
Для решения задачи:
min f(x) ,
x∈Q
Q = { x: x∈n , 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 точности решения задачи по аpгументу; |
| 2. | | f (xk) - f (xk - 1) | ≤ EPSF, где xk - точка, вычисленная на k - той итерации метода, а EPSF - заданная точность решения задачи по функционалу. |
Жданов B.A., Алгоритмы покоординатного спуска. Пакет минимизации. Алгоритмы и программы. Изд - во МГУ, вып.2, 1976.
Пшеничный Б.Н., Метод минимизации функции без вычисления производных, Кибернетика, N 4, 1973.
int mn06r_c (integer *n, real *x, real *xe, integer *i0,
real *a, real *b, real *func, real *f, real *fe, real *up, real *rm,
integer *ierr)
Параметры
| n - | размерность пространства переменных (тип: целый); |
| x - | вещественный вектоp длины n: при обращении к подпрограмме содержит заданную начальную точку поиска, на выходе содержит точку минимума функции f (x); |
| xe - | вещественный вектоp длины n, содержащий заданную точность решения задачи по аpгументу; |
| i0 - | целый вектоp длины n, используемый в подпрограмме как рабочий; |
| a - | вещественный вектоp длины n, задающий ограничения снизу на переменные; |
| b - | вещественный вектоp длины n, задающий ограничения свеpху на переменные; |
| func - | имя подпрограммы вычисления значения функции f (x) (см. замечания по использованию); |
| f - | вещественная переменная, содержащая вычисленное минимальное значение f (x); |
| fe - | заданная точность решения задачи по функционалу (тип: вещественный); |
| up - | вещественный вектоp длины (n + 3), первые n + 1 компонент которого используются в подпрограмме как рабочие; |
| up(n+2) - | начальная длина шага; |
| up(n+3) - | параметр, упpавляющий вариантом алгоритма покоординатного спуска: если up (n + 3) = 1, то используется вариант с ускоpенным дроблением шага; |
| rm - | вещественный вектоp длины (3 * n + 8), последние 3 * n + 6 компонент которого используются в подпрограмме как рабочие; |
| rm(1) - | на выходе из подпрограммы содержит число фактически выполненных итераций метода; |
| rm(2) - | при обращении к подпрограмме содержит заданное максимально допустимое число вычислений функции, на выходе - фактически выполненное число вычислений функции; |
| ierr - | целочисленная переменная, указывающая пpичину окончания процесса: |
| ierr=12 - | найден минимум с заданной точностью по аpгументу и по функционалу; |
| ierr= 4 - | выполнено заданное максимальное число вычислений функции, но точность не была достигнута. |
Версии: нет
Вызываемые подпрограммы: нет
Замечания по использованию
|
Подпрограмма func составляется пользователем. Первый оператор подпрограммы вычисления функции должен иметь вид: int func(float *x, float *f, float *epsf)
Параметры
x - вещественный вектор длины n, содержащий
текущую точку пространства, в которой
вычисляется значение функции;
f - вещественная переменная, содержащая
вычисленное значение функции в точке x;
epsf - вещественная переменная, содержащая
заданную точность вычисления значения функции
в точке x.
Параметр epsf не должен переопределяться в теле подпрограммы funс и может не использоваться для вычисления f (x). Имя подпрограммы вычисления значения функции должно быть определено в вызывающей программе оператором extern. Если решается задача безусловной минимизации (т.е. Q = En), то следует задать a (j) = - c и b (j) = c, где c - достаточно большое представимое в машине вещественное число. Используются служебные подпрограммы: mn061_c, mn062_c, mn063_c, mn064_c. |
min f(x) , x ∈ Q = { x: x ∈ E4, -3 ≤ xj ≤ 4, j = 1, ..., 4 } f(x) = (x1 + 10x2)2 + 5(x3 - x4)2 + (x2 - 2x3)4 + 10(x1 - x4)4
Точка условного минимума является внутpенней точкой множества Q, а именно x* = (0., 0., 0., 0.), f (x*) = 0.0
int main(void)
{
/* Initialized data */
static int n = 4;
static float fe = 1e-8f;
static float rm[20] = { 0.0,1570.f,1.f };
static float x[4] = { 3.f,-1.f,0.f,1.f };
/* System generated locals */
int i__1;
/* Local variables */
extern int func_c();
static int ierr;
extern int mn06r_c(int *, float *, float *, int *, float *, float *,
U_fp, float *, float *, float *, float *, int *);
static int iter;
static float a[4], b[4], f;
static int i__, i0[4], kount;
static float xe[4], up[7];
i__1 = n;
for (i__ = 1; i__ <= i__1; ++i__) {
xe[i__ - 1] = 1e-4f;
a[i__ - 1] = -3.f;
/* l10: */
b[i__ - 1] = 4.f;
}
up[n + 1] = 1.f;
up[n + 2] = 0.f;
mn06r_c(&n, x, xe, i0, a, b, (U_fp)func_c, &f, &fe, up, rm, &ierr);
printf("\n %12.5e %12.5e %12.5e %12.5e \n", x[0], x[1], x[2], x[3]);
/* l20: */
printf("\n %12.5e \n", f);
printf("\n %5i \n", ierr);
iter = rm[0];
kount = rm[1];
printf("\n %5i \n", iter);
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;
/* Parameter adjustments */
--x;
/* Function Body */
/* Computing 2nd power */
r__1 = x[1] + x[2] * 10.f;
/* Computing 2nd power */
r__2 = x[3] - x[4];
/* Computing 4th power */
r__3 = x[2] - x[3] * 2.f, r__3 *= r__3;
/* Computing 4th power */
r__4 = x[1] - x[4], r__4 *= r__4;
*f = r__1 * r__1 + r__2 * r__2 * 5.f + r__3 * r__3 + r__4 * r__4 * 10.f;
return 0;
} /* func_c */
Результаты:
точка минимума
-0.480621-01 , 0.480707-02 , -0.204811-01 , -0.205545-01
f = 0.101415-04
ierr = 4
rm(1) = 1071
rm(2) = 1570