Текст подпрограммы и версий
mnn1r_c.zip
Тексты тестовых примеров
tmnn1r_c.zip

Подпрограмма:  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.