Текст подпрограммы и версий 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