
- •Задача распределения капиталовложений
- •Аннотация
- •Содержание
- •Введение
- •1.Постановка задачи.
- •2. Построение аналитической модели
- •3.Обзор численных методов решения задач лп
- •3.1.Алгоритм симплекс-метода для задачи на минимум
- •3.2.Двойственный симплекс-метод
- •Вычислительная схема двойственного симплекс – метода
- •3.3.Метод Гомори
- •4.Расчётная часть
- •5.Алгоритм программы
- •6.Описание программы
- •Список использованных источников
- •Приложение а.
Список использованных источников
Дегтярев Ю.И. Исследование операций. - М.: Высшая школа, 1986. – 224с.
Зайченко Ю.П. Исследование операций. - Киев: Высшая школа, 1979.
Методика по математическому программированию в электронном виде.
Приложение а.
Листинг программы
Основная функция решения
bool TForm1::RSimpM()
{
PerNBas.Length=n;
PerBas.Length=n+1;
SimpTab.Length=n+1;
for(int i=0;i<SimpTab.Length;i++)
{
SimpTab[i].Length=n+2;
for(int j=0;j<SimpTab[0].Length;j++)
SimpTab[i][j]=0;
}
PerBas[0]="Y";
for(int i=1; i<PerBas.Length;i++)
{
PerBas[i]="Z"+IntToStr(i);
PerNBas[i-1]="X"+IntToStr(i);
}
for(int i=1;i<SimpTab.Length;i++)
{
SimpTab[i][0]=StrToFloat(SGCi->Cells[i][1]);
SimpTab[i][1]=StrToFloat(SGBi->Cells[i][1]);
}
SimpTab[0][1]=StrToFloat(EK->Text);
for(int i=2;i<SimpTab[0].Length;i++)
SimpTab[0][i]=1;
for(int i=1;i<SimpTab.Length;i++)
SimpTab[i][i+1]=1;
if(!SimpM(SimpTab,PerBas,PerNBas))return false;
if(!MG())return false;
return true;
}
void TForm1::OutR()
{
int n1=n+1;
SGXi->ColCount=n1;
for(int i=0;i<PerBas.Length;i++)
if(PerBas[i].c_str()[0]=='X')
{
SGXi->Cells[StrToInt(&PerBas[i][2])][1]=FloatToStr(SimpTab[0][i+1]);
SGXi->Cells[StrToInt(&PerBas[i][2])][0]=PerBas[i];
}
for(int i=0;i<PerNBas.Length;i++)
if(PerNBas[i].c_str()[0]=='X')
{
SGXi->Cells[StrToInt(&PerNBas[i][2])][1]=0;
SGXi->Cells[StrToInt(&PerNBas[i][2])][0]=PerNBas[i];
}
LS->Caption=FloatToStr(-SimpTab[0][0]);
PerNBas.Length=0;
PerBas.Length=0;
for(int i=0;i<SimpTab.Length;i++)
SimpTab[i].Length=0;
SimpTab.Length=0;
}
Симплекс метод
bool TForm1::SimpM(DynamicArray<DynamicArray<long double> > &SimpTab,DynamicArray<AnsiString> &PerBas,DynamicArray<AnsiString> &PerNBas)
{
bool Opt=PrOpt(SimpTab) ? true : false;
bool NResh=PrNResh(SimpTab) ? true : false;
while(!(Opt||NResh))
{
int VStolb=VedStolb(SimpTab);
int VStr=VedStr(SimpTab,VStolb);
SimpPreobr(SimpTab,PerBas,PerNBas,VStolb,VStr);
Opt=PrOpt(SimpTab) ? true : false;
NResh=PrNResh(SimpTab) ? true : false;
}
return Opt;
}
Проверка на оптимальность
bool TForm1::PrOpt(DynamicArray<DynamicArray<long double> > &SimpTab)
{
for(int i=1;i<SimpTab.Length;i++)
if(SimpTab[i][0]>0)return false;
return true;
}
Проверка на неразрешимость
bool TForm1::PrNResh(DynamicArray<DynamicArray<long double> > &SimpTab)
{
bool a;
for(int i=1;i<SimpTab.Length;i++)
if(SimpTab[i][0]>0)
{
a=true;
for(int j=1;j<SimpTab[i].Length;j++)
if(SimpTab[i][j]>0)
{
a=false;
break;
}
}
return a;
}
Выбор ведущего столбца
int TForm1::VedStolb(DynamicArray<DynamicArray<long double> > &SimpTab)
{
int I=0;
long double q=0;
for(int i=1;i<SimpTab.Length;i++)
if(SimpTab[i][0]>q)
{
q=SimpTab[i][0];
I=i;
}
return I;
}
Выбор ведущей строки
int TForm1::VedStr(DynamicArray<DynamicArray<long double> > &SimpTab, int vs)
{
int VStr;
long double min;
for(int i=1;i<SimpTab[0].Length;i++)
{
if(SimpTab[vs][i]>0)
{
min=SimpTab[0][i]/SimpTab[vs][i];
VStr=i;
break;
}
}
Проверка на целочисленность
int TForm1::XsMaxDrobCh()
{
long double q=0,w=0;
int I=0;
for(int i=1;i<SimpTab[0].Length;i++)
if(PerBas[i-1].c_str()[0]=='X'/*||(PerBas[i-1].c_str()[0]=='Z')*/)
{
q=SimpTab[0][i]-floorl(SimpTab[0][i]);
if(q>w)
{
w=q;
I=i;
}
}
return I;
}
Метод Гомори
bool TForm1::MG()
{
int DrStr=XsMaxDrobCh();
if(DrStr!=0)
while(DrStr!=0)
{
for(int i=0;i<SimpTab.Length;i++)
{
SimpTab[i].Length=SimpTab[i].Length+1;
SimpTab[i][SimpTab[i].High]=floorl(SimpTab[i][DrStr])-SimpTab[i][DrStr];
}
PerBas.Length=PerBas.Length+1;
PerBas[PerBas.High]="S";
if(!DSimpM(SimpTab,PerBas,PerNBas)){
return false; }
for(int i=1;i<=PerBas.Length;i++)
if(PerBas[i-1].c_str()[0]=='S')
for(int j=0;j<SimpTab.Length;j++)
SimpTab[j][i]=0;
DrStr=XsMaxDrobCh();
}
return true;
}
Двойственный симплекс метод
bool TForm1::DSimpM(DynamicArray<DynamicArray<long double> > &SimpTab,DynamicArray<AnsiString> &PerBas,DynamicArray<AnsiString> &PerNBas)
{
bool Opt=DPrOpt(SimpTab) ? true : false;
bool NResh=DPrNResh(SimpTab) ? true : false;
while(!(Opt||NResh))
{
int VStr=DVedStr(SimpTab);
int VStolb=DVedStolb(SimpTab,VStr);
SimpPreobr(SimpTab,PerBas,PerNBas,VStolb,VStr);
Opt=DPrOpt(SimpTab) ? true : false;
NResh=DPrNResh(SimpTab) ? true : false;
}
return Opt;
}
Проверка на оптимальность (двойственный метод)
bool TForm1::DPrOpt(DynamicArray<DynamicArray<long double> > &SimpTab)
{
for(int i=1;i<SimpTab[0].Length;i++)
if(SimpTab[0][i]<0)return false;
return true;
}
Проверка на неразрешимость (двойственный метод)
bool TForm1::DPrNResh(DynamicArray<DynamicArray<long double> > &SimpTab)
{
bool a;
for(int i=1;i<SimpTab[0].Length;i++)
if(SimpTab[0][i]<0)
{
a=true;
for(int j=1;j<SimpTab.Length;j++)
if(SimpTab[j][i]<0)
{
a=false;
break;
}
}
return a;
}
Выбор ведущей строки (двойственный метод)
int TForm1::DVedStr(DynamicArray<DynamicArray<long double> > &SimpTab)
{
int I=0;
long double q=0;
for(int i=1;i<SimpTab[0].Length;i++)
if(SimpTab[0][i]<q)
{
q=SimpTab[0][i];
I=i;
}
return I;
}
Выбор ведущего столбца (двойственный метод)
int TForm1::DVedStolb(DynamicArray<DynamicArray<long double> > &SimpTab, int vs)
{
int VStolb;
long double min;
for(int i=1;i<SimpTab.Length;i++)
{
if(SimpTab[i][vs]<0)
{
min=SimpTab[i][0]/SimpTab[i][vs];
VStolb=i;
break;
}
}
long double a;
for(int i=VStolb;i<SimpTab.Length;i++)
{
if(SimpTab[i][vs]<0)
{
a=SimpTab[i][0]/SimpTab[i][vs];
if(min>a)
{
min=a;
VStolb=i;
}
}
}
return VStolb;
}
Преобразование симплексной таблицы
void TForm1::SimpPreobr(DynamicArray<DynamicArray<long double> > &SimpTab,DynamicArray<AnsiString> &PerBas,DynamicArray<AnsiString> &PerNBas, int VStolb, int VStr)
{
int VStr1=VStr-1;
int VStolb1=VStolb-1;
AnsiString Per=PerBas[VStr1];
PerBas[VStr1]=PerNBas[VStolb1];
PerNBas[VStolb1]=Per;
SimpTab[VStolb][VStr]=1/SimpTab[VStolb][VStr];
for(int i=0;i<SimpTab.Length;i++)
if(i!=VStolb)
for(int j=0;j<SimpTab[0].Length;j++)
if(j!=VStr)
SimpTab[i][j]=SimpTab[i][j]-(SimpTab[i][VStr]*
SimpTab[VStolb][j]*SimpTab[VStolb][VStr]);
for(int i=0;i<SimpTab.Length;i++)
{
if(i!=VStolb)SimpTab[i][VStr]*=SimpTab[VStolb][VStr];
}
for(int i=0;i<SimpTab[0].Length;i++)
{
if(i!=VStr)SimpTab[VStolb][i]*=-SimpTab[VStolb][VStr];
}
}