|
Текст подпрограммы и версий mna6r_c.zip , mna6d_c.zip |
Тексты тестовых примеров tmna6r_c.zip , tmna6d_c.zip |
Поиск локального минимума функции многих переменных методом Пауэлла.
Пусть задана функция N переменных F (x1, x2, ..., xN) и пусть известны координаты начальной точки X = (x*1, x*2, ..., x*N) поиска локального минимума (N ≤ 50).
Подпрограмма mna6r_c выполняет итерационный процесс, состоящий в проведении последовательных одномерных поисков минимумов, начиная с точки X, вдоль системы определяемых в самой подпрограмме сопряженных направлений. В качестве начальных направлений поиска выбираются направления координатных осей в пространстве En.
Итерационный процесс продолжаетася до тех пор, пока модуль разности между значениями функции F в точках приближения к минимуму на двух последних итерациях не станет меньше EPS.
Предполагается, что составляемая пользователем подпрограмма - функция вычисления F в текущей точке XTEC всегда имеет имя FUNC и оформляется с двумя формальными параметрами:
XTEC - вещественный вектор длины N, содержащий координаты точки, в которой вычисляется значение функции F;
N - количество переменных (тип: целый).
Д.Химмельбау. Прикладное нелинейное программирование. Изд - во "Мир", 1975.
int mna6r_c (integer *n, real *x, real *y, real *p, real *eps,
integer *iflag, integer *itmax)
Параметры
| n - | количество переменных; n ≤ 50 (тип: целый); |
| x - | вещественный вектор длины n, содержащий на входе координаты начальной точки поиска локального минимума, а на выходе - координаты этого минимума; |
| y - | вещественная переменная, содержащая на выходе значение функции F в полученной точке минимума; |
| p - | вещественный двумерный массив размеров n на n, используемый в подпрограмме в качестве рабочего; |
| eps - | заданное допустимое отклонение между значениями функции F на двух последовательных итерациях (тип: вещественный); |
| iflag - | целая переменная, служащая для сообщения о том, удалось ли найти локальный минимум за itmax итераций; при этом: |
| iflag=0 - | когда минимум функции F не найден; тогда вектор x содержит приближение к минимуму на последней итерации, а y - значение F в этой точке; |
| iflag=1 - | когда точка минимум найдена; |
| itmax - | заданное максимальное число итераций (тип: целый). |
Версии
| mna6d_c - | поиск локального минимума функции многих переменных методом Пауэлла в режиме удвоенной точности; при этом параметры x, y, p и eps должны иметь тип double, а подпрограмма - функция FUNC должна быть описана как double. |
Вызываемые подпрограммы
|
mna1r_c - mna1d_c | локализация минимума функции одной переменной в режимах одинарной и удвоенной точности; используются в подпрограммах mna6r_c и mna6d_c соответственно; |
|
mna3r_c - mna3d_c | поиск локального минимума функции одной переменной методом Брента (методом обратной параболической интерполяции) в режимах одинарной и удвоенной точности; используются в подпрограммах mna6r_c и mna6d_c соответственно. |
Замечания по использованию
|
В подпрограммах mna6r_c и mna6d_c имеется внешняя структура с именем mna6rr_ , содержащая элемент целого типа с именем iter. Переменная iter полагается равной количеству итераций, выполненных при поиске минимума функции. Если iflag = 0, то iter = itmax. В этом случае следует либо увеличить itmax, либо увеличить eps. В качестве рабочих используются подпрограммы mna6r1_c (mna6d1_c) и mna6r2_c (mna6d2_c), в которых имеется внешняя структура с именем mna6rc_ . |
struct {
int ntest;
} _BLNK__;
#define _BLNK__1 _BLNK__
struct {
int iter;
} mna6rr_;
#define mna6rr_1 mna6rr_
int main(void)
{
/* Local variables */
extern int mna6r_c(int *, float *, float *, float *, float *, int *,
int *);
static int n, iflag;
static float y;
static int itmax;
static float p1[4] /* was [2][2] */,
p2[4] /* was [2][2] */, x1[2], x2[2], eps;
_BLNK__1.ntest = 1;
n = 2;
x1[0] = 8.f;
x1[1] = 9.f;
eps = 1e-6f;
itmax = 500;
mna6r_c(&n, x1, &y, p1, &eps, &iflag, &itmax);
printf("\n %16.7e %16.7e \n", x1[0], x1[1]);
printf("\n %16.7e \n", y);
printf("\n %5i \n", iflag);
printf("\n %5i \n", mna6rr_1.iter);
_BLNK__1.ntest = 2;
x2[0] = 1.2f;
x2[1] = 1.f;
mna6r_c(&n, x2, &y, p2, &eps, &iflag, &itmax);
printf("\n %16.7e %16.7e \n", x2[0], x2[1]);
printf("\n %16.7e \n", y);
printf("\n %5i \n", iflag);
printf("\n %5i \n", mna6rr_1.iter);
return 0;
} /* main */
float func_c(float *x, int *n)
{
/* System generated locals */
float ret_val, r__1, r__2, r__3;
/* Parameter adjustments */
--x;
/* Function Body */
if (_BLNK__1.ntest != 1) {
goto l1;
}
/* Computing 2nd power */
r__1 = x[1] - .5f;
/* Computing 2nd power */
r__2 = x[2] - 6.f;
ret_val = r__1 * r__1 * 4.f + r__2 * r__2;
return ret_val;
l1:
/* Computing 2nd power */
r__2 = x[1];
/* Computing 2nd power */
r__1 = x[2] - r__2 * r__2;
/* Computing 2nd power */
r__3 = 1.f - x[1];
ret_val = r__1 * r__1 * 100.f + r__3 * r__3;
return ret_val;
} /* func_c */
Результаты:
x1(1) = 0.5 ; x1(2) = 6.0 ; y = 0.0
iflag = 1 ; mna6rr_1.iter = 3
x2(1) = 1.00001 ; x2(2) = 1.0 ; y = 0.295415e - 7
iflag = 1 ; mna6rr_1.iter = 2