|
Текст подпрограммы и версий mn11r_c.zip |
Тексты тестовых примеров tmn11r_c.zip |
Решение задачи квадратичного программирования при наличии двухсторонних ограничений на переменные методом покординатного спуска.
Решается задача квадратичнoгo пpoграммирования
min { Q(x) = (Gx, x) + (h, x) | a ≤ x ≤ b } ,
где G - симметричная матрица размерности n * n , x, h, a, b - векторы длины n, причем ai > - ∞, bi < +∞, i = 1, ..., n.
Матрица G задается в компактной форме, т.е. представляется в виде вектоpа длины n (n + 1)/2, который состоит из элементов нижнего треугольника матрицы, выписанных последовательно по строкам.
Для решения задачи используется метод покоординатного спуска. Для одномерной минимизации функции Q (x) вдоль направления спуска используется метод квадратичной аппроксимации.
Некоторая вычисленная точка xk, a ≤ xk ≤ b, считается точкой минимума функции Q (x), если выполнено хотя бы одно из следующих условий:
| 1. | | xik - xik - 1 | ≤ XE для всех i = 1, ..., n, где xk = (x1k, ..., xnk) - точка, полученная на k - ой итерации метода, а XE - заданная точность решения задачи по аргументу; |
| 2. | | Q (xk) - Q (xk - 1) | ≤ FE, xk - точка, вычисленная на k - ой итерации метода, а FE - заданная точность решения задачи по функционалу. |
Пшеничный Б.Н., Метод минимизации функции без вычисления производных, Кибернетика, N 4, 1973.
int mn11r_c (integer *n, real *x, real *xe, real *a, real *b,
real *g, real *h, real *fstep, integer *ipar, integer *maxk,
real *f, real *fe, integer *kount, integer *i0, real *rm,
integer *ierr)
Параметры
| n - | размерность пространства переменных (тип: целый); |
| x - | вещественный вектоp длины n: при обращении к подпрограмме содержит заданную начальную точку поиска, на выходе содержит точку минимума функции Q (x); |
| xe - | заданная точность решения задачи по аргументу (тип: вещественный); |
| a - | вещественный вектоp длины n, задающий ограничения снизу на переменные; |
| b - | вещественный вектоp длины n, задающий ограничения свеpху на переменные; |
| g - | вещественный вектоp длины n (n + 1)/2, содержащий компактную запись матрицы G; |
| h - | вещественный вектоp длины n, содержащий компоненты вектоpа h; |
| fstep - | начальная длина шага (тип: вещественный); |
| ipar - | параметр, управляющий вариантом покоординатного спуска (тип: целый): |
| ipar=1 - | используется вариант с ускоpенным дроблением шага; |
| maxk - | целая переменная, при обращении к подпрограмме содержащая заданное максимально допустимое число вычислений функции, на выходе - фактически выполненное число вычислений функции; |
| f - | вещественная переменная, содержащая вычисленное минимальное значение Q (x); |
| fe - | заданная точность решения задачи по функционалу (тип: вещественный); |
| kount - | целая переменная, содержащая число фактически выполненных итераций метода; |
| i0 - | целочисленный вектоp длины n, используемый как рабочий; |
| rm - | вещественный вектоp длины 4 * n + 11, используемый как рабочий; |
| ierr - | целая переменная, указывающая причину окончания процесса: |
| ierr= 0 - | найден минимум с заданной точностью по аргументу или по функционалу; |
| ierr= 4 - | выполнено заданное максимальное число вычислений функции, но точность не была достигнута. |
Версии: нет
Вызываемые подпрограммы: нет
Замечания по использованию
|
Используются служебные подпрограммы: mnp11_c, mnp13_c, mn214_c, mn215_c, mnp16_c. |
Найти min { Q(x) = (Gx, x) + (h, x) | a ≤ x ≤ b } , где
G - трехдиагональная матрица, у которой
верхняя и нижняя диагонали равны
( 0.5, 0.5, 0.5, 0., 0.5, 0.5, 0., 0.5, 0. ) ,
а главная диагональ равна
( 100., 100., 100., 100., 20., 20., 20., 3., 3., 1. ) .
h = ( - 202; - 202; - 202; - 200; - 42; - 42; - 40; - 8; - 6; - 2 ) ;
ai = - 2 , i = 1 , ..., 10 ;
bi = 2 , i = 1 , ..., 10 .
Начальная точка xi0 = - 1 , i = 1, ..., 10 . Q(x0) = 1419 .
Точка минимума x* ≈ (1.0050; 1.0000; 1.0000; 0.9950; 1.0250;
1.0000; 0.9750; 1.2000; 0.8000; 1.0000)
Q(x*) ≈ - 473.2300
int main(void)
{
/* Initialized data */
static int n = 10;
static float b[10] = { 2.f,2.f,2.f,2.f,2.f,2.f,2.f,2.f,2.f,2.f };
static float x[10] = { -1.f,-1.f,-1.f,-1.f,-1.f,-1.f,-1.f,-1.f,-1.f,-1.f };
static float fe = 5e-10f;
static float xe[10] = { 5e-10f,5e-10f,5e-10f,5e-10f,5e-10f,5e-10f,5e-10f,
5e-10f,5e-10f,5e-10f };
static float fstep = 1.f;
static int ipar = 1;
static int maxk = 1000;
static float g[55] = { 100.f,.5f,100.f,0.f,.5f,100.f,0.f,0.f,.5f,100.f,0.f,
0.f,0.f,0.f,20.f,0.f,0.f,0.f,0.f,.5f,20.f,0.f,0.f,0.f,0.f,0.f,.5f,
20.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,3.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,
.5f,3.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,1.f };
static float h__[10] = { -202.f,-202.f,-202.f,-200.f,-42.f,-42.f,-40.f,
-8.f,-6.f,-2.f };
static float a[10] = { -2.f,-2.f,-2.f,-2.f,-2.f,-2.f,-2.f,-2.f,-2.f,-2.f };
/* Local variables */
extern int mn11r_c(int *, float *, float *, float *, float *, float *,
float *, float *, int *, int *, float *, float *,
int *, int *, float *, int *);
static int ierr;
static float f;
static int kount, io[10], i;
static float rm[51];
mn11r_c(&n, x, xe, a, b, g, h__, &fstep, &ipar, &maxk, &f, &fe, &kount,
io, rm, &ierr);
printf("\n %5i \n", ierr);
printf("\n %5i \n", kount);
printf("\n %5i \n", maxk);
for (i = 0; i <= 5; i += 5) {
printf("\n %14.6f %14.6f %14.6f %14.6f %14.6f \n",
x[i], x[i+1], x[i+2], x[i+3], x[i+4]);
}
printf("\n %16.7e \n", f);
return 0;
} /* main */
Результаты:
ierr = 0
kount = 193
maxk = 306
x(i) = (1.0053, 0.999574, 1.000782, 0.995092, 1.025024,
1.001971, 0.975006, 1.199397, 0.800848, 0.998825)
f = - 473.2299