|
Текст подпрограммы и версий mne1r_c.zip , mne1d_c.zip |
Тексты тестовых примеров tmne1r_c.zip , tmne1d_c.zip |
Решение задачи безусловной минимизации выпуклой недифференцируемой функции многих переменных субградиентным методом.
Для решения задачи:
min f(x) , x ∈ En ,
где f (x) - выпуклая недифференцируемая функция, применяется субградиентный метод последовательной релаксации с построением сопряженных направлений. Для ускорения сходимости и уточнения длины шага может проводиться одномерная минимизация по направлению.
Коннов И.В. Субградиентный метод последовательной релаксации для решения задач оптимизации. Деп.ВИНИТИ, N 531 - 83.
Демьянов В.Ф., Васильев Л.Ф. Недифференцируемая оптимизация. М.: Наука, 1981.
int mne1r_c (real *f, real *fe, S_fp func, real *g, real *ge,
integer *ierr, integer *i0, integer *n, real *rm, S_fp subg, real *up,
real *x, real *xe)
Параметры
| f - | вещественная переменная, содержащая вычисленное минимальное значение f (x); |
| fe - | заданная точность решения задачи по функции (тип: вещественный); |
| func - | имя подпрограммы вычисления значения функции f (x) (см. замечания по использованию); |
| g - | вещественный вектор длины n, содержащий субградиент функции f в вычисленной точке x; |
| ge - | вещественный вектор длины n, задающий точность решения задачи по субградиенту; |
| ierr - | целая переменная, указывающая причину окончания процесса; |
| ierr=1 - | найден минимум с заданной точностью по аргументу; |
| ierr=2 - | найден минимум с заданной точностью по функции; |
| ierr=3 - | найден минимум с заданной точностью по субградиенту; |
| ierr=4 - | выполнено максимальное (см. up (4)) количество вычислений функции; |
| ierr=5 - | истекло заданное время, отведенное пользователем на решение задачи (см. up (5)); |
| ierr=6 - | произошло замедление счета (см.замечания по использованию); |
| i0 - | целый вектор длины n, задающий фиксированные на время минимизации компоненты вектора x: если i0 (i) = 0, то i - ая компонента вектора x остается равной своему начальному значению; |
| n - | размерность пространства переменных (тип: целый); |
| rm - | вещественный вектор длины 2n, используемый в подпрограмме как рабочий; |
| subg - | имя подпрограммы вычисления субградиента функции f (x) (см.замечания по использованию); |
| up - | вещественный вектор длины 9, задающий управляющие параметры алгоритма; |
| up(1) - | заданная начальная длина шага; |
| up(2) - | заданная константа дробления шага, 0 < up (2) < 1; |
| up(3) - | заданный коэффициент, определяющий величину убывания функции на одной итерации, 0 < up (3) < 1; |
| up(4) - | заданное максимально допустимое количество вычислений функции; |
| up(5) - | время, отведенное центральному процессору на решение задачи, задается пользователем в секундах; |
| up(6),up(7) - | параметры, формирующие критерий замедления счета; рекомендуется задавать на входе up (6) = 0, тогда эти параметры вычисляются автоматически внутри подпрограммы; |
| up(8) - | заданный параметр, определяющий, через сколько итераций проводится одномерная минимизация (см. замечания по использованию); |
| up(9) - | заданный признак печати сообщения об окончании счета: up (9) = 1 - печатается сообщение о выполнившемся критерии останова, up (9) = 0 - сообщение не печатается; |
| x - | вещественный вектор длины n; при обращении к подпрограмме содержит заданную начальную точку поиска, при выходе содержит точку минимума функции f (x); |
| xe - | вещественный вектор длины n, задающий точность решения задачи по аргументу. |
Версии
| mne1d_c - | решение задачи безусловной минимизации выпуклой недифференцируемой функции многих переменных субградиентным методом, при этом вычисления проводятся с удвоенной точностью. Параметры f, fe, g, ge, rm, x, xe подпрограммы mne1d_c и подпрограмм func, subg должны иметь тип double. Тип остальных параметров не изменяется. |
Вызываемые подпрограммы
| mnb8r_c - | подпрограмма минимизации функции многих переменных по заданному направлению методом золотого сечения; вызывается при работе подпрограммы mne1r_c; |
| mnb8d_c - | подпрограмма минимизации по заданному направлению методом золотого сечения; вычисления проводятся с двойной точностью; вызывается при работе подпрограммы mne1d_c |
Замечания по использованию
|
Подпрограммы func и subg составляются пользователем. Первый оператор подпрограммы вычисления функции должен иметь вид: int func(float *x, float *f, float *fe)Параметры: |
| x - | вещественный вектор длины n, содержащий текущую точку пространства, в которой вычисляется значение функции; |
| f - | вещественная переменная, содержащая вычисленное значение функции в точке x; |
| fe - | вещественная переменная, содержащая на входе заданную точность вычисления значения функции в точке x, а на выходе - достигнутую точность. |
|
Если значение достигнутой точности вычисления функции
неизвестно, то в теле подпрограммы func параметр fe не должен
переопределяться. Первый оператор подпрограммы вычисления субградиента должен иметь вид: int subg(float *x, float *g, float *ge, int *i0)Параметры: |
| x - | вещественный вектор длины n, содержащий текущую точку пространства, в которой вычисляется субградиент; |
| g - | вещественный вектор длины n, содержащий вычисленный субградиент (произвольный из множества субградиентов) в точке x; |
| ge - | вещественный вектор длины n, содержащий на входе заданную покомпонентную точность вычисления субградиента функции, а на выходе - достигнутую точность вычисления субградиента; |
| i0 - | целый вектор фиксированных компонент, управляющий вычислением компонент субградиента: если i0 (i) = 0, то полагается g (i) = 0. |
|
Если значение достигнутой точности ge (i) для
некоторого i неизвестно, то в теле подпрограммы subg
параметр ge (i) не должен переопределяться.
Имена подпрограмм вычисления значения функции и ее субградиента должны быть определены в вызывающей программе оператором extern. Не рекомендуется проводить одномерную минимизацию на каждой итерации, так как построенное направление не является, вообще говоря, направлением наискорейшего убывания. Рекомендуется задавать up (8) > 4, либо up (8) = 0 (в этом случае одномерная минимизация не проводится). Для лучшего согласования управляющих параметров в процессе счета полезно задавать начальный шаг достаточно большим. Признак выхода из подпрограммы по замедлению счета ierr = 6 указывает на слишком медленную сходимость алгоритма, то есть изменение функции на каждой итерации оказывается на несколько порядков меньше, чем разность между текущим значением и минимальным. При работе подпрограммы mne1r_c используются следующие
служебные подпрограммы: mne1d1_c, mne1d2_c, mne1d3_c, mne1d4_c, mne1d5_c, mmkrid_c, mnr1nd_c, utmn05_c, utmne1_c, а также внешняя структура с именем mmkrd_ , содержащая элементы zf, kr, akr, df |
Найти минимальное значение функции
f(x) = | x1 + 2 | + | 4x2 - 6 | ;
начальное приближение x = (- 3., 1.)
int main(void)
{
/* Initialized data */
static float fe = 1e-7f;
static float xe[2] = { 1e-8f,1e-8f };
static float ge[2] = { .001f,.001f };
static float up[9] = { 5.f,.7f,.3f,500.f,600.f,0.f,0.f,10.f,1.f };
static int i0[2] = { 1,1 };
static int n = 2;
static float x[2] = { -3.f,1.f };
/* Local variables */
static int ierr;
extern int mne1r_c(float *, float *, U_fp, float *, float *, int *,
int *, int *, float *, U_fp, float *, float *, float *);
static float f, g[2];
extern int conus_c();
static float rm[4];
extern int subcon_c();
mne1r_c(&f, &fe, (U_fp)conus_c, g, ge, &ierr, i0, &n, rm, (U_fp)subcon_c,
up, x, xe);
printf("\n %13.7f %13.7f \n", x[0], x[1]);
printf("\n %13.7f \n", f);
printf("\n %13.7f %13.7f \n", g[0], g[1]);
printf("\n %5i \n", ierr);
printf("\n %9.3f \n", up[4]);
return 0;
} /* main */
int conus_c(float *x, float *f, float *fe)
{
/* Initialized data */
static float a[2] = { 1.f,4.f };
static float b[2] = { -2.f,6.f };
static int i__;
static float arg;
/* Parameter adjustments */
--x;
/* Function Body */
*f = 0.f;
for (i__ = 1; i__ <= 2; ++i__) {
arg = a[i__ - 1] * x[i__] - b[i__ - 1];
*f += abs(arg);
/* l1: */
}
return 0;
} /* conus_c */
int subcon_c(float *x, float *g, float *ge, int *i0)
{
/* Initialized data */
static float a[2] = { 1.f,4.f };
static float b[2] = { -2.f,6.f };
/* Builtin functions */
double r_sign(float *, float *);
/* Local variables */
static int i__;
static float arg;
/* Вычисляет субградиент ф-ции conus */
/* Parameter adjustments */
--i0;
--ge;
--g;
--x;
/* Function Body */
for (i__ = 1; i__ <= 2; ++i__) {
if (i0[i__] == 0) {
goto l2;
}
arg = a[i__ - 1] * x[i__] - b[i__ - 1];
g[i__] = (float)r_sign(&c_b14, &arg) * a[i__ - 1];
goto l1;
l2:
g[i__] = 0.f;
l1:
;
}
return 0;
} /* subcon_c */
Результаты счета:
Библиотека НИВЦ МГУ, подпрограмма mne1r_c
Выполнено максимальное количество вычислений функции
x = - 2.0000001 1.5000000
f = 0.0000001
ierr = 4