|
Текст подпрограммы и версий mnb2r_c.zip |
Тексты тестовых примеров tmnb2r_c.zip |
Минимизация функции многих переменных по заданному направлению на заданном отрезке методом деления пополам (дихотомический поиск).
Для решения задачи
min φ (x0 + λ s) , a0 ≤ λ ≤ b0 ,
λ
где x0, s ∈ En, a0, b0, λ ∈ E1, используется метод деления отрезка пополам.
Hа каждой итерации метода строится очередной отрезок [ak, bk] такой, что [ak bk] ⊂ [ak - 1, bk - 1] ⊂ ... ⊂ [a0, b0] и λ* ∈ [ai, bi] для всех i, где λ* - точка минимума φ (x) по направлению S.
Вычисления заканчиваются, если для некоторого k длина отрезка [ak, bk] меньше заданного числа ε > 0. Функция φ предполагается строго квазивыпуклой по направлению S.
B.A.Березнев. Алгоритм дихотомического поиска минимума унимодальной функции на отрезке. - Оптимизация и упpавление. М.: МГУ, 1982.
int mnb2r_c (integer *n, real *x, real *s, real *xx, real *a,
real *b, real *eps, real *c, real *fc, integer *maxk, S_fp fun,
integer *ierr)
Параметры
| n - | разность пространства переменных (тип: целый); |
| x - | вещественный вектоp длины n, задающий начальную точку поиска минимума по направлению; |
| s - | вещественный вектоp длины n, задающий направление одномерной минимизации; |
| xx - | вещественный вектоp длины n, используемый в подпрограмме как рабочий; |
| a - | вещественная переменная, задающая нижнюю гpаницу исходного отрезка неопределенности; |
| b - | вещественная переменная, задающая верхнюю границу исходного отрезка неопределенности; |
| eps - | заданная точность вычисления точки минимума (тип: вещественный); |
| c - | вещественная переменная, содержащая на выходе шаг по направлению s до вычисленной точки минимума; |
| fc - | вещественная переменная, содержащая на выходе минимальное значение функции по направлению; |
| maxk - | заданное максимальное допустимое число вычислений функции (тип: целый); |
| fun - | имя подпрограммы вычисления значения функции (см. замечания по использованию); |
| ierr - | целая переменная, указывающая пpичину окончания процесса: |
| ierr= 0 - | получено решение с заданной точностью eps; |
| ierr=65 - | выполнено maxk вычислений функции; |
| ierr=66 - | функция не является строго квазивыпуклой. |
Версии: нет
Вызываемые подпрограммы: нет
Замечания по использованию
| 1. |
Длина очередного отрезка неопределенности на k - й итерации метода pавна (b - a)/2k, поэтому нетpудно определить число вычислений функции, необходимое для сокращения исходного отрезка до длины, меньшей eps. Параметр maxk в связи с этим целесообразно задавать на несколько единиц большим необходимого числа вычислений функции, чтобы избежать зацикливания. | |
| 2. |
Подпрограмма fun составляется пользователем. Первый оператор подпрограммы должен иметь вид: int fun(float *x, float *f, float *fe)
Параметры
x - точка, в которой вычисляется значение функции;
f - вычисленное значение функции;
fe - точность, с которой вычисляется значение f.
Имя подпрограммы вычисления функции должно быть
определено в вызывающей программе в операторе extern.
Параметp fe не должен переопределяться в теле подпрограммы fun.
|
min φ (x) , -2 ≤ x ≤ 1 ,
φ (x) = log(-x) , если x ≤ -1 ,
φ (x) = x3 + 1 , если x > -1.
int main(void)
{
/* Initialized data */
static int n = 1;
static float a = -2.f;
static float b = 1.f;
static float x[1] = { 0.f };
static float s[1] = { 1.f };
static float eps = 1e-5f;
static int maxk = 20;
/* Local variables */
extern int func_c();
static int ierr;
extern int mnb2r_c(int *, float *, float *, float *, float *, float *,
float *, float *, float *, int *, U_fp, int *);
static float c__, fc, xx[1];
mnb2r_c(&n, x, s, xx, &a, &b, &eps, &c__, &fc, &maxk,
(U_fp)func_c, &ierr);
printf("\n %15.7f \n", c__);
printf("\n %17.7e \n", fc);
printf("\n %5i \n", ierr);
return 0;
} /* main */
int func_c(float *x, float *f, float *fe)
{
/* System generated locals */
float r__1;
/* Builtin functions */
double r_lg10(float *);
/* Parameter adjustments */
--x;
/* Function Body */
if (x[1] + 1.f <= 0.f) {
goto l10;
} else {
goto l20;
}
l10:
r__1 = -x[1];
*f = (float)r_lg10(&r__1);
goto l30;
l20:
/* Computing 3rd power */
r__1 = x[1];
*f = r__1 * (r__1 * r__1) + 1.f;
l30:
return 0;
} /* func_c */
Результаты:
ierr = 0
c__ = -1.00000095
fc = 4.14175e-7