Решение целочисленной задачи линейного программирования - Курсовая работа

бесплатно 0
4.5 106
Постановка линейной целочисленной задачи. Метод отсекающих плоскостей. Дробный алгоритм решения полностью целочисленных задач. Эффективность отсечения Гомори. Сравнение вычислительных возможностей метода отсекающих плоскостей и метода ветвей и границ.

Скачать работу Скачать уникальную работу

Чтобы скачать работу, Вы должны пройти проверку:


Аннотация к работе
Среди практически важных задач отыскания условного экстремума линейной функции важное место занимают задачи с требованием целочисленности всех переменных. Существуют различные методы решения таких задач, и заметное место среди них занимают методы отсечения., п) из которых обладает по j-ой характеристике показателем и полезностью , найти такой набор, который позволяет максимизировать эффективность использования ресурсов величины . Математическая модель этой задачи может быть представлена следующим образом: в области, определенной условиями (3) найти решение , при котором максимизируется (минимизируется) значение целевой функции Допустимое решение, при котором функция (4) достигает наибольшего (наименьшего) значения, называется оптимальным решением. Казалось бы, что естественный путь решения целочисленной задачи состоит в решении соответствующей линейной задачи с последующим округлением компонент ее оптимального плана до ближайших целых чисел.Представленный ниже пример раскрывает смысл понятия “отсекающая плоскость”. Рассмотрим следующую линейную задачу целочисленного программирования: В области, определенной условиями Область допустимых решений задачи с ослабленными ограничениями, получаемой путем отбрасывания требования целочисленности переменных, изображена на рис. В основе метода отсекающих плоскостей лежит преобразование области допустимых решений задачи с ослабленными ограничениями в выпуклый многогранник, экстремальная точка которого является оптимальным решением исходной целочисленной задачи.Например, ограничение можно записать в виде неравенства в котором дроби отсутствуют. В этом случае дробный алгоритм позволяет обнаружить отсутствие допустимого решения даже тогда, когда задача, записанная в исходных переменных, имеет допустимое целочисленное решение. На первом шаге решается задача с ослабленными ограничениями, не содержащими условия целочисленности переменных. В противном случае следует ввести дополнительные ограничения, порождающие (вместе с исходными ограничениями) новую задачу линейного программирования, решение которой оказывается целочисленным и совпадает с оптимальным решением исходной целочисленной задачи. Пусть последняя симплексная таблица задачи с ослабленными ограничениями имеет следующий вид: Базисные переменные Решение (свободные члены) Свободные переменныеИз изложенного выше следует, что вид неравенства, определяющего некоторое отсечение, зависит от выбора производящей строки. Эффективность отсечения характеризуется размерами области, отсекаемой от многогранника допустимых решений, что математически можно выразить следующим образом. Будем говорить, что отсечение (1) более эффективно, чем отсечение (2), если и для всех j, причем по крайней мере в одном случае выполняется строгое неравенство.После применения симплекс-метода для этой же задачи, но с ослабленными ограничениями, получаемой путем отбрасывания требования целочисленности переменных, имеем из исходной симплекс-таблицы следующую: Базисные переменные Решение (свободные члены) Свободные переменные То есть отсечение будем строить на основе производящей i-ой строки, которой соответствует Введем отсечения, соответствующие производящим строкам с базисными переменными и целевой функции L: (L-строка) Получаем новую таблицу: Базисные переменные Решение (свободные члены) Свободные переменные Вычисляются отношения коэффициентов L-строки к соответствующим коэффициентам-строки(столбец свободных членов не рассматривается).Попробуем охарактеризовать поведение алгоритмов метода отсекающих плоскостей и метода ветвей и границ при решении задач целочисленного линейного программирования. В качестве меры продолжительности вычислений рассмотрим количество симплексных итераций I и количество дополнительных линейных ограничений D. Сравним выше указанные методы при решении следующей целочисленной задачи: В области, определенной условиями При использовании метода отсекающих плоскостей (см. приложение 2): x[1]=1 (погрешность 1.788139e-07) x[2]=1 (погрешность 5.960464e-07) x[3]=8 (погрешность 1.000000e-16) x[4]=0 (погрешность 1.000000e-16) При использовании метода ветвей и границ: x[1]=1 (погрешность 5.960464e-08) x[2]=1 (погрешность 5.960464e-08) x[3]=8 (погрешность 1.000000e-16) x[4]=0 (погрешность 1.000000e-16)В данной работе был рассмотрен метод отсекающих плоскостей и представлена программа на языке программирования С , реализующая данный метод. Также приведен конкретный пример решения полностью целочисленной задачи выше указанным методом. Сравнительный анализ вычислительных возможностей метода отсекающих плоскостей и метода ветвей и границ показал, что использование второго из них становится гораздо более эффективным с увеличением количества переменных и количества неравенств задачи, при небольшой же размерности задачи предпочтительней первый метод.

План
СОДЕРЖАНИЕ

ВВЕДЕНИЕ

1. Постановка линейной целочисленной задачи

2. Описания метода отсекающих плоскостей

2.1 Идея метода

2.2 Дробный алгоритм решения полностью целочисленных задач

2.3 Эффективность отсечения Гомори

3. Использование метода отсекающих плоскостей для решения одной задачи линейного целочисленного программирования

4. Сравнение вычислительных возможностей метода отсекающих плоскостей и метода ветвей и границ

ЗАКЛЮЧЕНИЕ

СПИСОК ИСПОЛЬЗУЕМОЙ ЛИТЕРАТУРЫ

Приложение 1. Листинг программы

Приложение 2. Результат работы программы

Вывод
В данной работе был рассмотрен метод отсекающих плоскостей и представлена программа на языке программирования С , реализующая данный метод.

Также приведен конкретный пример решения полностью целочисленной задачи выше указанным методом. При этом использовались условия наиболее эффективного отсечения. В результате было введено два дополнительных ограничения и после чего получен целочисленный ответ.

Сравнительный анализ вычислительных возможностей метода отсекающих плоскостей и метода ветвей и границ показал, что использование второго из них становится гораздо более эффективным с увеличением количества переменных и количества неравенств задачи, при небольшой же размерности задачи предпочтительней первый метод.

При реализации метода отсекающих плоскостей возникают трудности, носящие технический характер. В настоящий момент можно говорить о решении с помощью этого метода задач не более чем среднего размера (сотни переменных и десятки ограничений).

Более того, опыт показывает, что даже некоторые задачи сравнительно небольшой размерности не могут быть решены с помощью метода отсекающих плоскостей. Известны случаи, когда непреднамеренное изменение порядка следования ограничений делало несложную исходную задачу поистине гигантской по объему вычислений.

Наиболее общий вывод о возможностях использования метода отсечений заключается в признании того факта, что указанный метод не обеспечивают эффективного решения общей задачи целочисленного программирования. Однако некоторые идеи метода отсечений оказываются полезными для совершенствования других алгоритмов решения целочисленных задач.

Список литературы
1. Таха Х., Введение в исследование операций: В 2-х книгах. Кн. 1. М.: Мир, 1985. 479с.

2. Подбельский В. В. и Фомин С. С. Программирование на языке Си. М.: “Финансы и статистика”, 2000. 599с.

3. Лященко И.Н. Линейное и нелинейное программирование, М.: Наука, - 1985.

4. Санович К.М. Исследование операций, М.: Наука, - 1989.

Листинг программы

#include

#include

#include

#include void main()

{ float dr(float);

float zz,*x,**a,alk,*ai,*aj,**f;

int simpiter=0,p,n=4,m=4,i=0,j=0,k=0,l=0,q=0,xx;

clrscr();

x=new float[m 1];//m - k-vo peremennyh ai=new float[n m 100];

aj=new float[m n 100];

a=new float*[n m 100];

for(i=0;i<n m 100;i )

{ a[i]=new float[m 1];

} f=new float*[n m 1];

for(i=0;i<n 1;i )

{ f[i]=new float[m 1];

}

/* a[0][0]=0; a[0][1]=2;a[0][2]=3;

a[1][0]=11; a[1][1]=3;a[1][2]=-1;

a[2][0]=6; a[2][1]=-2;a[2][2]=3;*/ a[0][0]=0; a[0][1]=2;a[0][2]=3; a[0][3]=12;a[0][4]=3;

a[1][0]=13; a[1][1]=4;a[1][2]=1; a[1][3]=1;a[1][4]=1;

a[2][0]=17; a[2][1]=-2;a[2][2]=-3; a[2][3]=1;a[2][4]=1;

a[3][0]=15; a[3][1]=-2;a[3][2]=1; a[3][3]=2;a[3][4]=2;

a[4][0]=18; a[4][1]=2;a[4][2]=4; a[4][3]=-1;a[4][4]=1;

for(i=0;i<n 1;i )

{ for(j=0;j<m 1;j ) cout<<a[i][j]<<" ";

cout<<"

";

} for(i=1;i<=m;i ) x[i]=i;

i=1;

while(i<n 1)

{ if(a[i][0]<0)

{ for(j=1;j<m 1;j )

{

if(a[i][j]>=0) q ;

else {

k=j;

break;

}

} if(q==m) goto A;

else

{

j=i;

zz=a[i][0]/a[i][k];

for(l=1;l<n 1;l )

if((a[l][0]/a[l][k]>0)&&(zz>(a[l][0]/a[l][k])))

{

zz=a[l][0]/a[l][k];

j=l;

}

alk=a[j][k];

l=j;

for(xx=1;xx<m 1;xx )

{

if(x[xx]==k) {

x[xx]=l*10;

continue;

}

if(x[xx]==10*l) {

x[xx]=k;

continue;

}

}

simpiter ;

alk=a[i][k];

l=i;

for(j=0;j<m 1;j )

ai[j]=a[l][j];

for(j=0;j<n 1;j )

aj[j]=a[j][k];

for(i=0;i<n 1;i )

for(j=0;j<m 1;j )

a[i][j]=a[i][j] ai[j]*(-aj[i])/alk;

for(j=0;j<m 1;j )

a[l][j]=ai[j]/alk;

for(j=0;j<n 1;j )

a[j][k]=-aj[j]/alk;

a[l][k]=1/alk;

} for(i=0;i<n 1;i )

{

for(j=0;j<m 1;j )

cout<<a[i][j]<<" ";

cout<<"

";

} i=0;

} i ;

} j=1;

while(j<m 1)

{ if(a[0][j]>0)

{ q=0;

for(i=1;i<n 1;i )

{

if(a[i][j]<=0) q ;

else {

k=i;

break;

}

} if(q==n) goto C;

else

{

i=k;

for(l=1;l<n 1;l )

if((a[l][j]>0)&&(a[l][0]>0)&&((a[i][0]/a[i][j])>(a[l][0]/a[l][j]))) i=l;

l=i;

k=j;

for(xx=1;xx<m 1;xx )

{

if(x[xx]==k) {

x[xx]=l*10;

continue;

}

if(x[xx]==10*l) {

x[xx]=k;

continue;

}

}

simpiter ;

alk=a[i][k];

for(j=0;j<m 1;j )

ai[j]=a[l][j];

for(j=0;j<n 1;j )

aj[j]=a[j][k];

for(i=0;i<n 1;i )

for(j=0;j<m 1;j )

a[i][j]=a[i][j] ai[j]*(-aj[i])/alk;

for(j=0;j<m 1;j )

a[l][j]=ai[j]/alk;

for(j=0;j<n 1;j )

a[j][k]=-aj[j]/alk;

a[l][k]=1/alk;

} j=0;

} j ;

} for(p=1;;p )

{ q=1;

for(xx=1;xx<m 1;xx )

{ if (fabs(dr(a[int(x[xx]/10)][0]))<0.001) q ;

} if (q==m 1) break;

alk=0;

for(xx=1;xx<m 1;xx ) if((x[xx]>=10)&&(dr(a[int(x[xx]/10)][0])>=alk))

{

alk=dr(a[int(x[xx]/10)][0]);

q=int(x[xx]/10);

} cout<<"

"<<alk<<" "<<q<<"

";

for(j=1;j<m 1;j )

{ a[n p][j]=-dr(a[q][j]);

} a[n p][0]=-alk;

alk=1000000;

for(j=1;j<m 1;j ) if ((a[n p][j]<0)&&(a[0][j]/a[n p][j]<alk))

{

alk=a[0][j]/a[n p][j];

k=j;

} l=n p;

for(i=0;i<n p 1;i )

{ for(j=0;j<m 1;j )

cout<<a[i][j]<<" ";

cout<<"

";

} for(xx=1;xx<m 1;xx )

{ if(x[xx]==k)

{

x[xx]=l*10;

continue;

}

} alk=a[l][k];

simpiter ;

for(j=0;j<m 1;j ) ai[j]=a[l][j];

for(j=0;j<n p 1;j ) aj[j]=a[j][k];

for(i=0;i<n p 1;i ) for(j=0;j<m 1;j )

a[i][j]=a[i][j] ai[j]*(-aj[i])/alk;

for(j=0;j<m 1;j ) a[l][j]=ai[j]/alk;

for(j=0;j<n p 1;j ) a[j][k]=-aj[j]/alk;

a[l][k]=1/alk;

cout<<"

";

} for(i=0;i<n p;i )

{ for(j=0;j<m 1;j ) cout<<a[i][j]<<" ";

cout<<"

";

} for(xx=1;xx<m 1;xx )

{ if(x[xx]<10) printf("

x[%d]=0 погрешность=0.000000e 00",xx);

if(x[xx]>=10) printf("

x[%d]=%d погрешность=%e", xx, int

(a[int(x[xx]/10)][0] 0.1) ,a[int(x[xx]/10)][0]- int(a[int(x[xx]/10)][0] 0.1));

} cout<<"

Максимум функции z="<<-a[0][0];

cout<<"

Количество симплексных итераций: I="<<simpiter;

cout<<"

Количество дополнительных ограничений: D="<<p-1;

goto B;

A: cout<<"net dopustimih resheniy";

goto B;

C: cout<<"net optimalnih resheniy";

B: getch();

} float dr(float y)

{ float y1;

if (y>=0) y1=y-int(y 0.00001);

else y1=y-int(y-0.00001) 1;

if (fabs(y1-1)<0.00001) y1=0;

return y1;

}

Результат работы программы x[1]=1 (погрешность 1.788139e-07) x[2]=1 (погрешность 5.960464e-07) x[3]=8 (погрешность 1.000000e-16) x[4]=0 (погрешность 0.000000e-16)

Максимум функции z=101.

Количество симплексных итераций: I=5

Количество дополнительных ограничений: D=1

Размещено на .ru

Вы можете ЗАГРУЗИТЬ и ПОВЫСИТЬ уникальность
своей работы


Новые загруженные работы

Дисциплины научных работ





Хотите, перезвоним вам?