Документ взят из кэша поисковой машины. Адрес
оригинального документа
: 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