Текст подпрограммы и версий
ml08r_c.zip
Тексты тестовых примеров
tml08r_c.zip

Подпрограмма:  ml08r_c

Назначение

Решение задачи линейного программирования с двухсторонними ограничениями на переменные симплекс - методом с использованием метода отражений. Матрица условий хранится компактно.

Математическое описание

Решается задача линейного пpoгpaммирования:

      min (c, x)  ( или  max  (c, x) )
      A x  =  b ,
      0 ≤ x ≤ α , 

где A - матрица размерности  m на n,  x,  c и  α - векторы длины  n, b - вектоp длины  m.

Hа каждой итерации симплекс - метода базисная матрица B представляется в виде произведения матриц отражения и правой треугольной матрицы.

Ненулевые элементы матрицы условий A задаются в виде одномерного массива, каждый элемент которого содержит очередной (по столбцам) ненулевой элемент  ai j матрицы A, индексы  i в том же порядке задаются в целочисленном массиве NS.

Вектоp T длины  n содержит коэффициенты линейной формы, а таблица ненулевых элементов матрицы A по столбцам задается в целом массиве NT, т.е. NT(J) содержит число ненулевых элементов в J - ом столбце матрицы A.

Введен вспомогательный вектоp SUM длины  n с компонентами SUМ j = - (a1 j +... + am j), где  ai j - элементы матрицы А. Вектоp  b дополняется компонентой  bm + 1 = 0.

Компоненты вектоpа  α верхних ограничений на переменные задаются в одномерном массиве ALFA. Номера компонент вектоpа α, отличных от + ∞, задаются вектоpом NALFA.

Точность вычислений характеризуется величиной невязки r = ( - b1 - ... - bm) - (SUM, x).

Дж.Данциг, Линейное программирование. Его применения и обобщения. Изд - во "Прогресс", M., 1966.

В.В.Воеводин, Вычислительные основы линейной алгебры. Изд - во "Наука", M., 1977.

Использование

    int ml08r_c (real *a, shortint *ns, integer *da, real *b,
            integer *m, real *t, shortint *nt, integer *n, real *sum, real *x, 
            integer *p, real *eps, real *xk, real *z, real *alfa, integer *kv, 
        shortint *nalfa, shortint *nx)

Параметры

a - вещественный вектоp длины da, содержащий ненулевые элементы матрицы условий;
ns - целый вектоp, в котором перечислены номера строк ненулевых элементов матрицы A;
da - число ненулевых элементов в матрице условий (тип: целый);
b - вещественный рабочий массив размерности m на m, где m = m + 1;
m - число стpок в расширенной матрице, pавное m + 1 (тип: целый);
t - вещественный вектоp длины  n, содержащий коэффициенты линейной формы;
nt - целый вектоp длины  n, содержащий количества ненулевых элементов матрицы по столбцам;
n - число столбцов матрицы условий (тип: целый);
sum - вещественный вектоp длины  n, содержащий сумму элементов матрицы по столбцам с обратным знаком;
x - вещественный вектоp длины m; на входе x (i) =  bi,  i = 1,..., m; на выходе x (i) - ненулевые компоненты решения для i = 1, 2,..., m - 1, x (m) - минимальное (максимальное) значение линейной формы;
p - целая переменная; при обращении к подпрограмме задается равной 1, если требуется найти максимум линейной формы, и не равной 1 в противном случае; на выходе:
p= 1 - если найдено решение,
p= 2 - если задача несовместна,
p= 3 - если значение линейной формы неограничено,
p= 4 - если базисная матрица плохо обусловлена;
eps - заданная абсолютная погрешность вычислений (тип: вещественный);
xk - вещественный рабочий вектоp длины m;
z - вещественный рабочий вектоp длины m;
alfa - вещественный вектоp длины kv, содержащий отличные от  + ∞ компоненты вектоpа верхних ограничений  α;
kv - длина вектоpа alfa, равная числу отличных от  + ∞ компонент вектоpа  α (тип: целый).
nalfa - целый двухбайтовый вектоp длины  kv, содержащий номера компонент вектоpа верхних ограничений  α; отличных от  + ∞;
nx - целый двухбайтовый вектоp длины  m, содержащий на выходе из подпрограммы номера ненулевых компонент решения.

Версии: нет

Вызываемые подпрограммы: нет

Замечания по использованию

 

Задача должна быть приведена к виду, в котоpом компоненты вектоpа  b неотрицательны.

На выходе из подпрограммы в массиве nx (i = 1, 2,..., m - 1) стоит номеp J (i) компоненты решения, для которой  0 < xJ (i) = x (i) < αJ (i).

Если при выходе из подпрограммы элемент nalfa (J) массива nalfa содержит число (k + 1600), то в оптимальном плане  xk = αk. Остальные компоненты решения равны нулю.

Вектоp  α не должен содержать нулевых компонент, и хотя бы одна его компонента должна быть отлична от  + ∞.

Используются служебные подпрограммы: ml0801_c, ml0802_c, ml0803_c, ml0804_c, ml0805_c, ml0806_c, ml0807_c, ml0808_c, ml0809_c, ml0810_c, ml0811_c, ml0812_c, ml0813_c, ml0814_c, ml0815_c, ml0816_c, ml0817_c, ml0818_c, ml0819_c, ml0820_c, ml0821_c, ml0822_c, mlu33_c, mlu34_c.

Программа рекомендуется для решения задач, требующих высокую точность вычислений.
Значение p = 4 на выходе из подпрограммы чаще всего означает, что следует увеличить значение eps, т.е. снизить требуемую точность.

Пример использования

int main(void)
{
    /* Initialized data */
    static float a[10] = { 1.f,2.f,1.f,2.f,1.f,2.f,3.f,5.f,1.f,1.f };
    static float x[4] = { 15.f,20.f,10.f,0.f };
    static int p = 1;
    static int m = 4;
    static int n = 4;
    static float eps = .01f;
    static shortint nt[4] = { 3,3,3,1 };
    static float t[4] = { 1.f,2.f,3.f,-1.f };
    static shortint ns[10] = { 1,2,3,1,2,3,1,2,3,3 };
    static float sum[4] = { -4.f,-5.f,-9.f,-1.f };
    static float alfa[2] = { 2.f,3.f };
    static shortint nalfa[2] = { 1,3 };
    static int kv = 2;
    static int da = 10;

    /* Local variables */
    extern int ml08r_c(float *, shortint *, int *, float *, int *, float *,
                       shortint *, int *, float *, float *, int *, float *,
                       float *, float *, float *, int *, shortint *,
                       shortint *);
    static float b[16] /* was [4][4] */, z__[4], xk[4];
    static shortint nx[4];

    ml08r_c(a, ns, &da, b, &m, t, nt, &n, sum, x, &p, &eps, xk, z__, alfa,
            &kv, nalfa, nx);

    printf("\n %5i %5i %5i %5i %5i \n", nx[0], nx[1], nx[2], nx[3], nx[4]);
    printf("\n %12.5e %12.5e %12.5e %12.5e %12.5e \n",
           x[0], x[1], x[2], x[3], x[4]);
    printf("\n %5i %5i \n", nalfa[0], nalfa[1]);
    printf("\n %5.1f %5.1f \n", alfa[0], alfa[1]);
    return 0;
} /* main */


Результаты:

              x  =  (2.43,  2.71,  0.43,  14.57)
           nx  =  (2, 3, 4)
    nalfa  =  (163852, 3)

   Таким образом:
        x  =  (2.,  2.43,  2.71,  0.43)
  (c, x)  =  14.57