Документ взят из кэша поисковой машины. Адрес оригинального документа : 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_С. Задача минимизации функции многих переменных с ограничениями
Текст подпрограммы и версий
mn06r_c.zip
Тексты тестовых примеров
tmn06r_c.zip

Подпрограмма:  mn06r_c

Назначение

Решение задачи минимизации функции многих переменных без вычисления производных при наличии двухстоpонних ограничений на переменные методом спуска.

Математическое описание

Для решения задачи:

         min  f(x) ,
        xQ
Q  =  { x:  xn ,  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