//---------------------------------------------------------------------------

#include <vcl.h>
#include <time.h>
#include <stdio.h>
#include <dos.h>
#include <sys\timeb.h>
#include <stdlib.h>
#pragma hdrstop
 #include <fstream.h>
#include "Main.h"
#include  <systdate.h>
#include <string.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int n,m,dlin,m2;
double **matrixA;
int *vectorP;
int *nvars;
double **matrixB;
int nomstr;
int nots,M;
bool error;
int **Zvar;
ofstream efs;//( "outdata.txt", ios::trunc );
//==================== Начальные данные для загрузки формы =======================

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

error=false;
DLVar->Visible=false;
PageControl1->ActivePage = TabSheet1;
n=2; m=2;
LFun->Cells[2][0]=AnsiString("x1");
CFun->Cells[1][0]=AnsiString("x1");
LFun->Cells[3][0]=AnsiString("x2");
CFun->Cells[2][0]=AnsiString("x2");
LFun->Cells[0][1]=AnsiString("1");
LFun->Cells[0][2]=AnsiString("2");
LFun->Cells[1][0]=AnsiString("b");
CheckVar->Enabled=false;
}

//=========================Обновление формы====================================

void TForm1::UpdateTables(int n1,int m1)
{
char c1[20],c2[20];
TStringList *str = new TStringList;
//-----------------Обновление по переменным-------------------------------------
if((n1!=n)&&(n1<=300))
{
  n=n1;
  CFun->ColCount=n+1;
  LFun->ColCount=n+2;
  for(int i=1;i<=n+m;i++)
  {
    itoa(i,c1,10);
    c2[1]=NULL;
    c2[0]='x';
    strcat(c2,c1);
    if(i<=n)
    {
      LFun->Cells[i+1][0]=AnsiString(c2);
      CFun->Cells[i][0]=AnsiString(c2);
    }
    str->Add(AnsiString(c2));
  }
  CheckVar->Items=str;
  str->Clear();
}
//-------------------Обновление по ограничениям---------------------------------
if((m1!=m)&&(m1<=300))
{
  m=m1;
  LFun->RowCount=m+1;
  for(int i=1;i<=m;i++) LFun->Cells[0][i]=IntToStr(i);
  for(int i=1;i<=n+m;i++)
  {
    itoa(i,c1,10);
    c2[1]=NULL;
    c2[0]='x';
    strcat(c2,c1);
    str->Add(AnsiString(c2));
  }
  CheckVar->Items=str;
  str->Clear();
}
delete str;
}

//===================Изменено количество переменных=============================

void __fastcall TForm1::VarChange(TObject *Sender)
{
int n1,i,i1;
char* str;
bool flag=true;
i1=Var->GetTextLen();
str=new char[i1];
Var->GetTextBuf(str,i1+1);
for(i=0;i<i1;i++) if((str[i]>57)||(str[i]<48))flag=false;
if(flag==true)
{
  if((Var->Text!="")&&(Var->Text!=0))
  {
    n1=StrToInt(Var->Text);
    UpdateTables(n1,m);
  }
}
else Var->Text=IntToStr(n);
delete(str);
}

//===================Изменено количество ограничений============================

void __fastcall TForm1::LimChange(TObject *Sender)
{
int m1,i,i1;
char* str;
bool flag=true;
i1=Lim->GetTextLen();
str=new char[i1];
Lim->GetTextBuf(str,i1+1);
for(i=0;i<i1;i++) if((str[i]>57)||(str[i]<48))flag=false;
if(flag==true)
{
  if((Lim->Text!="")&&(Lim->Text!=0))
  {
    m1=StrToInt(Lim->Text);
    UpdateTables(n,m1);
  }
}
else Lim->Text=IntToStr(m);
delete(str);
}

//===============Изменение индикатора максимизации-минимизации==================

void __fastcall TForm1::mmaxClick(TObject *Sender)
{
if(mmax->Caption=="max>")
  mmax->Caption=AnsiString("min>");
else
  mmax->Caption=AnsiString("max>");
}

//=======================Загрузка данных из файла===============================

void __fastcall TForm1::openClick(TObject *Sender)
{
int n1,m1;
double d;
int i1;
bool it;
if( OpenDialog->Execute() )
{
  int i,j;
  char* str,st;
  ifstream ifs( OpenDialog->FileName.c_str() );
  ifs >>i1;
  if(i1==1)Metod->Text="Первый алгоритм Гомори";
  if(i1==2)Metod->Text="Второй алгоритм Гомори";
  if(i1==3)Metod->Text="Третий алгоритм Гомори";
  if(i1==4)Metod->Text="Алгоритм Данцига";
  if(i1==5)Metod->Text="Алгоритм Дальтона и Ллевелина";
  ifs >> n1;
  ifs >> m1;
  for( i=1; i<n1+1; i++ ) {ifs >> d; CFun->Cells[i][1]=FloatToStr(d); }
  for(i=1;i<m1+1;i++)
  for(j=1;j<n1+2;j++) {ifs >> d; LFun->Cells[j][i]=FloatToStr(d); }
  Var->Text = IntToStr( n1 );
  Lim->Text = IntToStr( m1 );
  UpdateTables(n1,m1);
  str = new char[100];
  if(i1==2)
  {
    CheckVar->Enabled=true;
    for(i=0;i<n+m;i++) {ifs>>it; CheckVar->Checked[i]=it; }
  }
  else CheckVar->Enabled=false;
  if(Metod->Text=="Алгоритм Дальтона и Ллевелина")
  {
    i=0; DLVar->Clear();
    str="";
    ifs>>str;
    while(str[0]!='.')
    {
      DLVar->Lines->Add(str);
      str="";
      ifs>>str;
    }
    CheckVar->Visible=false;  DLVar->Visible=true;
  }
  else {CheckVar->Visible=true; DLVar->Visible=false; }
  delete(str);
  ifs.close();
}
}

//=========================Сохранение данных====================================

void __fastcall TForm1::saveClick(TObject *Sender)
{
int i,j;
double d;
if( SaveDialog->Execute() )
{
  ofstream ofs( SaveDialog->FileName.c_str(), ios::trunc );
  if(Metod->Text=="Первый алгоритм Гомори")   ofs<<1<<endl;
  if(Metod->Text=="Второй алгоритм Гомори")   ofs<<2<<endl;
  if(Metod->Text=="Третий алгоритм Гомори")   ofs<<3<<endl;
  if(Metod->Text=="Алгоритм Данцига") ofs<<4<<endl;
  if(Metod->Text=="Алгоритм Дальтона и Ллевелина") ofs<<5<<endl;
  ofs << n << endl << m << endl;
  Var->Text=n;
  Lim->Text=m;
  for( i=1; i<n+1; i++ ) {d=StrToFloat(CFun->Cells[i][1]); ofs<<d <<" ";  }
  ofs<<endl;
  for(i=1;i<m+1;i++)
  {
    for(j=1;j<n+2;j++) {d=StrToFloat(LFun->Cells[j][i]); ofs<<d <<" "; }
    ofs<<endl;
  }
  if(Metod->Text=="Второй алгоритм Гомори")
  {for(i=0;i<n+m;i++) ofs<<CheckVar->Checked[i]<<" "; }
  ofs<<endl;
  
  if(Metod->Text=="Алгоритм Дальтона и Ллевелина")
  {
    char* str;
    str = new char[100];
    str=DLVar->Lines->GetText();
    ofs<<str<<endl;
    ofs<<'.';
    delete(str);
  }
  ofs.close();
}
}

//==================Изменение алгоритма для вычисления==========================

void __fastcall TForm1::MetodChange(TObject *Sender)
{
if(Metod->Text=="Второй алгоритм Гомори") CheckVar->Enabled=true;
else CheckVar->Enabled=false;
if(Metod->Text=="Алгоритм Дальтона и Ллевелина")
{CheckVar->Visible=false;  DLVar->Visible=true;  }
else
{CheckVar->Visible=true; DLVar->Visible=false;}
}

//=====================Нажатие кнопки "Решить"==================================

void __fastcall TForm1::goClick(TObject *Sender)
{
efs.open("outdata.txt");
int i,j,m1;
struct  time t1,t2,t3;
AnsiString str;
int q1,q2,q3;
n=StrToInt(Var->Text);
m=StrToInt(Lim->Text);
nvars=new int[n];
m1=m;
m2=m;

//---------Считывание данных для алгоритма Дальтона и Ллевелина-------------

if(Metod->Text=="Алгоритм Дальтона и Ллевелина")
{
  char *str1,st[10];
  char v1,v2;

  Zvar = new int*[n+m];
  for(i=0;i<n+m;i++) {Zvar[i]=new int[41];Zvar[i][0]=1;Zvar[i][1]=0;}
  str1 = new char[100];

  str1="";
  str1=DLVar->Lines->GetText();
  int k;
  i=1;
  while(str1[i]!='.')
  {

    strcpy(st,"          ");

    k=0;
    v1=str1[i];
    st[k]=v1;
    i++;k++;
    while(str1[i]!=':') {v1=str1[i];st[k]=v1; i++; k++; }
    nomstr=atoi(st);
    i++;
     strcpy(st,"          ");
    while((str1[i]!='x')&&(str1[i]!='.'))
    {
      k=0;   strcpy(st,"          ");

      while((str1[i]!='x')&&(str1[i]!=',')&&(str1[i]!='.'))
      {
        v1=str1[i];



        st[k]=v1;


        i++;k++;
      }
      Zvar[nomstr-1][Zvar[nomstr-1][0]+1]=atoi(st);
      Zvar[nomstr-1][0]++;
      if(str1[i]==',')i++;
    }
    if(str1[i]=='x')i++;
  }
  j=0;
  for(i=0;i<n;i++) if(Zvar[i][0]!=1) j++;
  for(i=0;i<n+m;i++)
  m1=m+j;
delete(str1);

}


//---------------------Выделение памяти под симплексную таблицу-----------------
matrixA=new double*[n+m1+3];
dlin=n+m1+1;
for(i=0;i<n+m1+3;i++) matrixA[i]=new double[n+1];

//-------------Выделение памяти под вектор целостных ограничений----------------
if(Metod->Text=="Второй алгоритм Гомори") vectorP=new int[n+m];

//--------------Занесение в матрицу целевой функции-----------------------------
matrixA[0][0]=0;
if(mmax->Caption=="max>")
  for(i=1;i<n+1;i++)
    if(CFun->Cells[i][1]!="")
      matrixA[0][i]=StrToFloat(CFun->Cells[i][1])*(-1);
    else
    matrixA[0][i]=0;
else
for(i=1;i<n+1;i++)
  if(CFun->Cells[i][1]!="")
    matrixA[0][i]=StrToFloat(CFun->Cells[i][1]);
  else
    matrixA[0][i]=0;

//---Заполнение компонент матрицы соответствующих основным переменным-----------
for(i=1;i<n+1;i++)
{
  matrixA[i][0]=0;
  for(j=1;j<n+1;j++)
  if(i!=j) matrixA[i][j]=0;
  else matrixA[i][j]=-1;
}

//---Заполнение компонент матрицы соответствующих дополнительным переменным-----
for(i=0;i<m;i++)
  for(j=0;j<n+1;j++)
    if(LFun->Cells[j+1][i+1]!="")
      matrixA[i+n+1][j]=StrToFloat(LFun->Cells[j+1][i+1]);
    else
      matrixA[i+n+1][j]=0;
   
//--------------Дополнение таблицы новыми ограничениями-------------------------
if(Metod->Text=="Алгоритм Дальтона и Ллевелина")
{
  j=0;
  for(i=0;i<n;i++)
  if(Zvar[i][0]!=1)
  {
    j++;
    matrixA[n+m+j][0]=Zvar[i][Zvar[i][0]];
    for(int i1=1;i1<n+1;i1++)matrixA[n+m+j][i1]=0;
    matrixA[n+m+j][i+1]=1;
  }
  m=m1;
}

//----------Заполнение вектора целочисленных ограничений------------------------
if(Metod->Text=="Второй алгоритм Гомори")
{
  for(i=0;i<n+m;i++)
  if(CheckVar->Checked[i]==true) vectorP[i]=1;
  else vectorP[i]=0;
}
//---начало отчета времени------
gettime(&t1);

//-------------------------Запуск методов решения-------------------------------
if((Metod->Text=="Первый алгоритм Гомори")||
(Metod->Text=="Второй алгоритм Гомори")||
(Metod->Text=="Алгоритм Данцига")||
(Metod->Text=="Третий алгоритм Гомори")||
(Metod->Text=="Алгоритм Дальтона и Ллевелина"))
 Gomory1();
//---конец отчета времени------
gettime(&t2);

//---подсчет интервала времени------
if(t1.ti_hund>t2.ti_hund)
{t2.ti_hund=t2.ti_hund+100; t2.ti_sec=t2.ti_sec-1; }
q3=t2.ti_hund-t1.ti_hund;
if(t1.ti_sec>t2.ti_sec)
{t2.ti_sec=t2.ti_sec+60; t2.ti_min=t2.ti_min-1; }
q2=t2.ti_sec-t1.ti_sec;
if(t1.ti_min>t2.ti_min) t2.ti_min=t2.ti_min+60;
q1=t2.ti_min-t1.ti_min;
str = Format( " min: %02d  ", ARRAYOFCONST((q1)));
str += Format( " sec: %02d  ", ARRAYOFCONST((q2)));
str += Format( " msec: %02d  ", ARRAYOFCONST((q3)));
Res->Lines->Add(str);
PageControl1->ActivePage = TabSheet2;

//----Освобождение памяти---------------
for(i=0;i<n+m1+3;i++) delete matrixA[i];
delete matrixA;
if(Metod->Text=="Второй алгоритм Гомори") delete vectorP;
delete nvars;
if(Metod->Text=="Алгоритм Дальтона и Ллевелина")
{   for(i=0;i<n+m2;i++) {delete(Zvar[i]);}
  delete(Zvar);
}
end:;
m=StrToInt(Lim->Text);
n=StrToInt(Var->Text);
efs.close();
}

//===================Печать симплексной таблицы=================================
 void TForm1::PrintTableB()
{
int i,j;
AnsiString str1;
str1 = AnsiString("      |       1   ");
for( i=0; i<n; i++ )
  str1 += Format( "   |      -x%-3d", ARRAYOFCONST(((int)nvars[i])));
str1+="   |";
Er->Lines->Add( str1 );

str1=" -----|";
for(j=1;j<=n+1;j++) str1+="--------------|";
Er->Lines->Add(str1);
for( i=0; i<dlin; i++ )
{
  str1 = Format( " x%-3d ", ARRAYOFCONST(((int)i)) );
  str1 +="|";
  for( j=0; j<n+1; j++ )
    if(matrixB[i][j]>=0)
      str1 +=Format( "  %-9.5e |",ARRAYOFCONST((matrixB[i][j])) );
    else
      str1 +=Format( " %-9.5e |",ARRAYOFCONST((matrixB[i][j])) );
  Er->Lines->Add( str1 );
  str1=" -----|";
  for(j=1;j<=n+1;j++) str1+="--------------|";
  Er->Lines->Add(str1);
}
}

void TForm1::PrintTable()
{
int i,j;
AnsiString str1;
str1 = AnsiString("      |       1   ");
for( i=0; i<n; i++ )
  str1 += Format( "   |      -x%-3d", ARRAYOFCONST(((int)nvars[i])));
str1+="   |";
Res->Lines->Add( str1 );

str1=" -----|";
for(j=1;j<=n+1;j++) str1+="--------------|";
Res->Lines->Add(str1);
for( i=0; i<dlin; i++ )
{
  str1 = Format( " x%-3d ", ARRAYOFCONST(((int)i)) );
  str1 +="|";
  for( j=0; j<n+1; j++ )
    if(matrixA[i][j]>=0)
      str1 +=Format( "  %-9.5e |",ARRAYOFCONST((matrixA[i][j])) );
    else
      str1 +=Format( " %-9.5e |",ARRAYOFCONST((matrixA[i][j])) );
  Res->Lines->Add( str1 );
  str1=" -----|";
  for(j=1;j<=n+1;j++) str1+="--------------|";
  Res->Lines->Add(str1);
}
}
//--------------------------------------------------------------------------
 void TForm1::PrintTableToFile()
{
int i,j;

Er->Clear();
AnsiString str1;
str1 = AnsiString("      |       1   ");
for( i=0; i<n; i++ )
  str1 += Format( "   |      -x%-3d", ARRAYOFCONST(((int)nvars[i])));
str1+="   |";
Er->Lines->Add( str1 );

str1=" -----|";
for(j=1;j<=n+1;j++) str1+="--------------|";
Er->Lines->Add(str1);
for( i=0; i<dlin; i++ )
{
  str1 = Format( " x%-3d ", ARRAYOFCONST(((int)i)) );
  str1 +="|";
  for( j=0; j<n+1; j++ )
    if(matrixA[i][j]>=0)
      str1 +=Format( "  %-9.5e |",ARRAYOFCONST((matrixA[i][j])) );
    else
      str1 +=Format( " %-9.5e |",ARRAYOFCONST((matrixA[i][j])) );
  Er->Lines->Add( str1 );
  str1=" -----|";
  for(j=1;j<=n+1;j++) str1+="--------------|";
  Er->Lines->Add(str1);
}
efs<<Er->Lines->GetText();

}

//=======================Печать отсечения=======================================

void TForm1::PrintOtsech()
{
AnsiString str1;
int j;
str1="Отсечение:";
Res->Lines->Add(str1);
str1=" -----|";
for(j=1;j<=n+1;j++) str1+="--------------|";
Res->Lines->Add(str1);
str1 = Format( " x%-3d ", ARRAYOFCONST((nots)) );
str1 +="|";
for( j=0; j<n+1; j++ )
  if(matrixA[n+m+1][j]>=0)
    str1 +=Format( "  %-9.5e |",ARRAYOFCONST((matrixA[n+m+1][j])) );
  else
    str1 +=Format( " %-9.5e |",ARRAYOFCONST((matrixA[n+m+1][j])) );
Res->Lines->Add( str1 );
str1=" -----|";
for(j=1;j<=n+1;j++) str1+="--------------|";
Res->Lines->Add(str1);
}
//----------------------------------------------------------------------------
 void TForm1::PrintOtsechToFile()
{
AnsiString str1;
int j;
Er->Clear();
str1="Отсечение:";
Er->Lines->Add(str1);
str1=" -----|";
for(j=1;j<=n+1;j++) str1+="--------------|";
Er->Lines->Add(str1);
str1 = Format( " x%-3d ", ARRAYOFCONST((nots)) );
str1 +="|";
for( j=0; j<n+1; j++ )
  if(matrixA[n+m+1][j]>=0)
    str1 +=Format( "  %-9.5e |",ARRAYOFCONST((matrixA[n+m+1][j])) );
  else
    str1 +=Format( " %-9.5e |",ARRAYOFCONST((matrixA[n+m+1][j])) );
Er->Lines->Add( str1 );
str1=" -----|";
for(j=1;j<=n+1;j++) str1+="--------------|";
Er->Lines->Add(str1);
efs<<Er->Lines->GetText();

}

//==============Проверка исходной таблицы на l-нормальность=====================

bool TForm1::LNorm()
{
int i,j;
bool flag;
flag=true;
//i=1;
for(i=1;i<n+1;i++)
{

  for(j=0;j<dlin;j++) if(matrixA[j][i]!=0) break;
  if(matrixA[j][i]<=0) {flag=false; }

}
return(flag);
}

//================Жорданово исключение в l методе===============================
void TForm1::LGiskl(int k1,int k2)
{
bool flag;
int i,j,i1;
for(i=0;i<dlin;i++)
  for(j=0;j<n+1;j++)
    if((i!=k1)&&(j!=k2))
      matrixA[i][j]=matrixA[i][j]-(matrixA[k1][j]*matrixA[i][k2])/matrixA[k1][k2];
for(i=0;i<dlin;i++)
{
  if(i!=k1)
  matrixA[i][k2]=(-1)*matrixA[i][k2]/matrixA[k1][k2];
}
for(i=0;i<n+1;i++) matrixA[k1][i]=0;
matrixA[k1][k2]=-1;
i=nvars[k2-1];
if(k1<=n+m) nvars[k2-1]=k1;
else  nvars[k2-1]=nots;
AnsiString str1;

  if(k1<=n+m) str1 = Format( "(x%d , ", ARRAYOFCONST((k1)) );
  else  str1 = Format( "(x%d , ", ARRAYOFCONST((nots)) );
  str1 += Format( "x%d)", ARRAYOFCONST((i)) );
if(CIter->Checked==true)
{
  Res->Lines->Add(str1);
  Res->Lines->Add("");
}
if(Out->Checked==true)
{
  Er->Clear();
  Er->Lines->Add(str1);
  efs<<Er->Lines->GetText()<<endl;
  efs<<endl;
}



}

//===============Нахождение оптимального решения l-методом======================

void TForm1::Lmetod()
{
int k1,k2,i,j;
bool flag,flag1;
double f1,f2;
flag=true;
for(i=1;i<dlin;i++) { if(matrixA[i][0]<0){ flag=false;break;} }
if(flag==false)
{
  do
  {
    k1=i;
    for(i=k1;i<dlin;i++) if(matrixA[i][0]<matrixA[k1][0]) k1=i;
    flag1=false;
    for(i=1;i<n+1;i++)
      if((matrixA[k1][i]<0)&&(fabs(matrixA[k1][i])>10e-10))
      {flag1=true;break;}
    if(flag1==false)
      {MessageDlg( "Задача неразрешима", mtError, TMsgDlgButtons() << mbOK, 0 );
    error=true;goto end;}//Несовместная система
    k2=i;
    for(i=k2;i<n+1;i++)
    if((matrixA[k1][i]<0)&&(fabs(matrixA[k1][i])>10e-10))
    {
      for(j=0;j<dlin;j++)
      {
        f1=matrixA[k1][i]; f2=matrixA[k1][k2];
        if(f1<0)f1=-f1; if(f2<0)f2=-f2;
        if((matrixA[j][i]/f1)<(matrixA[j][k2]/f2)) {k2=i;break;}
        else break;
      }
    }
    LGiskl(k1,k2);
    flag=true;
    for(i=1;i<dlin;i++) if(matrixA[i][0]<0) {flag=false;break;}
    if(CIter->Checked==true)
      {PrintTable(); Res->Lines->Add(""); }
    if(Out->Checked==true)
    {
      PrintTableToFile();
      efs<<endl;
    }
  }
  while(flag==false);
}
end:;

}

//==============Проверка таблицы на целочисленность=============================

bool TForm1::Cel()
{
int i,j;
int module;
bool flag,flag1;
flag=true;
if(Metod->Text=="Алгоритм Дальтона и Ллевелина")
{
  for(i=1;i<n+m2+1;i++)
  {
    if(Zvar[i-1][0]!=1)
    {
      flag=false;
      for(j=1;j<=Zvar[i-1][0];j++)
      {
        if(fabs(matrixA[i][0]-double(Zvar[i-1][j]))<10e-10)
        {flag=true;break;}
      }
      if(flag==false)break;
    }
    else flag=true;
  }
}
else
{
  if(Metod->Text=="Второй алгоритм Гомори")
  {
    for(i=1;i<n+m+1;i++)
    {
      module=matrixA[i][0];
      if(module+1-matrixA[i][0]<10e-10) {module++;matrixA[i][0]=module;}
      if(fabs(module-matrixA[i][0])>=10e-10)
      if((vectorP[i-1]==1)||(i==0)){flag=false;break;}
    }
  }
  else
  {
    for(i=1;i<n+m+1;i++)
    {
      module=matrixA[i][0];
      if(module+1-matrixA[i][0]<10e-10) {module++; matrixA[i][0]=module;}
      if(fabs(module-matrixA[i][0])>=10e-10){flag=false;break;}
    }
  }
}
nomstr=i;
return(flag);
}

//=========================Построение отсечений=================================

void TForm1::Otsechenie()
{
int i,j,i1,module,module0;

//-----------------------Для первого алгоритма----------------------------------
if(Metod->Text=="Первый алгоритм Гомори")
{
  for(i=0;i<n+1;i++)
  {

    if( matrixA[nomstr][i]>0) module=matrixA[nomstr][i];
    else module=matrixA[nomstr][i]-1;

    matrixA[n+m+1][i]=0;
    matrixA[n+m+1][i]=-fabs(module-matrixA[nomstr][i]);

  }
}

//-----------------------Для второго алгоритма----------------------------------
if(Metod->Text=="Второй алгоритм Гомори")
{


   if( matrixA[nomstr][0]>0) module0=matrixA[nomstr][0];
    else module0=matrixA[nomstr][0]-1;

  matrixA[n+m+1][0]=-fabs(module0-matrixA[nomstr][0]);
  for(i=1;i<n+1;i++)
  {

     if( matrixA[nomstr][i]>0) module=matrixA[nomstr][i];
    else module=matrixA[nomstr][i]-1;

    if((nvars[i-1]<=n+m)&&(vectorP[nvars[i-1]-1]==1))
    {
      if(fabs(matrixA[nomstr][i]-module)<=fabs(matrixA[nomstr][0]-module0))
      { matrixA[n+m+1][i]=-fabs(module-matrixA[nomstr][i]); }
      else
      {
        matrixA[n+m+1][i]=
       -fabs(module0-matrixA[nomstr][0])*
       (1-fabs(-module+matrixA[nomstr][i]))/
       (1-fabs(-module0+matrixA[nomstr][0]));
      }
    }
    else
    {
      if(matrixA[nomstr][i]>=0)
      {matrixA[n+m+1][i]=-matrixA[nomstr][i]; }
      else
      {
        matrixA[n+m+1][i]=
       -(fabs(-module0+matrixA[nomstr][0]))*
       (-fabs(module-matrixA[nomstr][i]))/
        (1-fabs(-module0+matrixA[nomstr][0]));
      }
    }
  }
}

//-------------------Для алгоритма Данцига----------------
if(Metod->Text=="Алгоритм Данцига")
{
  matrixA[n+m+1][0]=-1;
  for(i=1;i<n+1;i++) { matrixA[n+m+1][i]=-1; }
}
if(Metod->Text=="Алгоритм Дальтона и Ллевелина")
{
  for(i=1;i<=Zvar[nomstr-1][0];i++)
  if(matrixA[nomstr][0]<Zvar[nomstr-1][i])break;
  i--;
  matrixA[n+m+1][0]=-(matrixA[nomstr][0]-Zvar[nomstr-1][i]);
  for(j=1;j<n+1;j++)
    if(matrixA[nomstr][j]>=0) matrixA[n+m+1][j]=-matrixA[nomstr][j];
    else
      matrixA[n+m+1][j]=
    -(matrixA[nomstr][0]-Zvar[nomstr-1][i])*(-matrixA[nomstr][j])/
     (Zvar[nomstr-1][i+1]-matrixA[nomstr][0]);
}

j=n+m+1;
for( i1=0;i1<n;i1++) if(nvars[i1]>=j) j=nvars[i1]+1;
nots=j;
}

//================Проверка на допустимость для Третьего алгоритма Гомори========

bool TForm1::Dop()
{
int i;
bool flag;
flag=true;
for(i=1;i<n+m+1;i++) {if(matrixA[i][0]<0){flag=false; break;}}
nomstr=i;
return(flag);
}

//===================Отсечение для Третьего алгоритма Гомори====================

void TForm1::Otsechenie3()
{
int module;
int i,j,i1;
double alfa;
alfa=matrixA[nomstr][1];
for(i=2;i<n+1;i++)
if(matrixA[nomstr][i]<alfa) alfa=matrixA[nomstr][i];
alfa=-alfa;
for(i=0;i<n+1;i++)
{
  module=matrixA[nomstr][i]/alfa;
  if(module-(matrixA[nomstr][i]/alfa)>10e-10) module--;
  matrixA[n+m+1][i]=module;
}

j=n+m+1;
for( i1=0;i1<n;i1++) if(nvars[i1]>=j) j=nvars[i1]+1;
nots=j;
}

//====================Построение l-нормальной===================================

void TForm1::Normal()
{
int i,j,ist,k1,k2,i1;
bool flag;
int module;
double b,f1,f2;
if(LNorm()==false)
{
  flag=false;

//-------------------Поиск разрешающей строки в таблице-------------------------
  for(i=1;i<n+m+1;i++) if(matrixA[i][0]>0)
  {
    flag=true;
    for(j=1;j<n+1;j++) if(matrixA[i][j]!=1) {flag=false;break;}
    if(flag==true)break;
  }

//----------Нахождение оптимального плана и добавление нового ограничения-------
  if(flag!=true)
  {
    matrixB=new double*[n+m+1];
    for(i=0;i<n+m+1;i++) matrixB[i]=new double[n+1];
    for(i=0;i<n+m+1;i++) for(j=0;j<n+1;j++) matrixB[i][j]=matrixA[i][j];
    for(i=1;i<n+1;i++) matrixB[0][i]=-1;

//+++++++++++++++++++++++++++++++++++++++++
       int  j1=1;
       flag=true;
        for(i=1;i<m+n+1;i++) if(matrixB[i][0]<0){k1=i;flag=false;break;}
    while(flag==false)
    {
       k2=0;
      for(i=1;i<n+1;i++)
      if(matrixB[k1][i]<0){k2=i;break;}
      if(k2==0)
      {
      MessageDlg( "Задача неразрешима", mtError, TMsgDlgButtons() << mbOK, 0 );
        error=true;goto end;
      }//Неразрешима таблица
      k1=0;
      for(i=1;i<m+n+1;i++)
      if((matrixB[i][k2]!=0)&&(matrixB[i][0]/matrixB[i][k2]>0)){break;}
      k1=i;
      for(i=1;i<m+n+1;i++)
      if(matrixB[i][k2]!=0)
      {
      if((matrixB[i][0]/matrixB[i][k2]<matrixB[k1][0]/matrixB[k1][k2])
      &&(matrixB[i][0]/matrixB[i][k2]>0))
      k1=i;
      }

      for(i=0;i<n+m+1;i++) for(j=0;j<n+1;j++) if((i!=k1)&&(j!=k2))
      matrixB[i][j]=matrixB[i][j]-(matrixB[k1][j]*matrixB[i][k2])/matrixB[k1][k2];
      for(i=0;i<n+m+1;i++)
      {
        if(i!=k1)
        matrixB[i][k2]=(-1)*matrixB[i][k2]/matrixB[k1][k2];
      }

      for(i=0;i<n+1;i++) matrixB[k1][i]=0;
      matrixB[k1][k2]=-1;
      flag=true;
      for(i=1;i<m+n+1;i++) if(matrixB[i][0]<0) {k1=i;Er->Lines->Add("12345678910");flag=false;break;}
       PrintTableB();
       j1++;


    }


 //+++++++++++++++++++++++++++++++++++++
    flag=true;
    for(i=1;i<n+1;i++) if(matrixB[0][i]<0) flag=false;
    while(flag==false)
    {
      k2=1;
      for(i=2;i<n+1;i++) if(matrixB[0][i]<matrixB[0][k2]) k2=i;
      k1=0;
      for(i=1;i<m+n+1;i++) if(matrixB[i][k2]>0) {k1=i;break;}
      if(k1==0)
      {
      MessageDlg( "Задача неразрешима", mtError, TMsgDlgButtons() << mbOK, 0 );
        error=true;goto end;
      }//Неразрешима таблица
      for(i=k1+1;i<m+n+1;i++) if(matrixB[i][k2]>0)
      if(matrixB[i][0]/matrixB[i][k2]<matrixB[k1][0]/matrixB[k1][k2])
      k1=i;
      for(i=0;i<n+m+1;i++) for(j=0;j<n+1;j++) if((i!=k1)&&(j!=k2))
      matrixB[i][j]=matrixB[i][j]-(matrixB[k1][j]*matrixB[i][k2])/matrixB[k1][k2];
      for(i=0;i<n+m+1;i++)
      {
        if(i!=k1)
        matrixB[i][k2]=(-1)*matrixB[i][k2]/matrixB[k1][k2];
      }

     for(i=0;i<n+1;i++) matrixB[k1][i]=0;
     matrixB[k1][k2]=-1;
      flag=true;
      for(i=1;i<n+1;i++) if(matrixB[0][i]<0) {flag=false;break;}
       PrintTableB();
    }
    module=matrixB[0][0];
    matrixA[m+n+1][0]=module+1;
    for(i=1;i<n+1;i++) matrixA[n+m+1][i]=1;
    m++;
    dlin=m+n+1;
    Res->Lines->Add(matrixB[0][0]);
    for(i=0;i<n+m;i++) delete(matrixB[i]);
    delete(matrixB);
    if(CIter->Checked==true)
    {
      Res->Lines->Add("");
      Res->Lines->Add("Дополним еще одним ограничением:");
      PrintTable();
    }
    if(Out->Checked==true)
    {
      efs<<endl;
      efs<<"Дополним еще одним ограничением:"<<endl;
      PrintTableToFile();
    }
  }
  
  if(flag==true) k1=i;
  else
  k1=n+m;
  k2=1;
  for(i=1;i<n+1;i++)
  {
    for(j=1;j<n+m+1;j++)
    if((matrixA[j][i])>=(matrixA[k2][i]))
    break;
    else
    if((matrixA[j][i])<(matrixA[k2][i])) {k2=j;break;}
  }
  LGiskl(k1,k2);
   
      if(CIter->Checked==true)
  {
    Res->Lines->Add("l-нормальная таблица:");
    PrintTable();
  }
  if(Out->Checked==true)
  {
    efs<<"l-нормальная таблица:"<<endl;
    PrintTableToFile();
  }
}
end:

}

//===========================Решение задачи=====================================

void TForm1::Gomory1()
{
int module;
  double f1,f2;
double b;
int i,j,ist,k1,k2,i1;
bool flag,flag1;
for( i = 0; i < n; i++ ) nvars[i] = i+1;
//----------------------Вывод исходной таблицы----------------------------------
Res->Clear();
if(Metod->Text=="Первый алгоритм Гомори")
Res->Lines->Add("Решение задачи по первому алгоритму Гомори:");
if(Metod->Text=="Второй алгоритм Гомори")
Res->Lines->Add("Решение задачи по второму алгоритму Гомори:");
if(Metod->Text=="Третий алгоритм Гомори")
Res->Lines->Add("Решение задачи по третьему алгоритму Гомори:");
if(Metod->Text=="Алгоритм Данцига")
Res->Lines->Add("Решение задачи по алгоритму Данцига:");
if(Metod->Text=="Алгоритм Дальтона и Ллевелина")
Res->Lines->Add("Решение задачи по алгоритму Дальтона и Ллевелина:");
Res->Lines->Add("");
Res->Lines->Add("Исходная таблица:");
PrintTable();
if(Out->Checked==true)
{
  efs<<endl<<"Исходная таблица:"<<endl;
  PrintTableToFile();
}
Normal();

if(Metod->Text!="Третий алгоритм Гомори")
{
  if(error!=true) Lmetod();
  int i2=0;

  while(Cel()==false)
  {
    Otsechenie();
      if(CIter->Checked==true) { PrintOtsech(); }
    if(Out->Checked==true){PrintOtsechToFile();}
    
    k1=n+m+1;
    flag1=false;
     for(i=1;i<n+1;i++)
      if((matrixA[k1][i]<0)&&(fabs(matrixA[k1][i])>10e-10))
      {flag1=true;break;}
    if(flag1==false)
      {MessageDlg( "Задача неразрешима", mtError, TMsgDlgButtons() << mbOK, 0 );
    error=true;goto end;}//Несовместная система
    k2=i;
    
    dlin++;
    for(i=k2;i<n+1;i++)
    {
    if((matrixA[k1][i]<0)&&(fabs(matrixA[k1][i])>10e-10))
    {
      for(j=0;j<dlin;j++)
      {
        f1=matrixA[k1][i]; f2=matrixA[k1][k2];
        if(f1<0)f1=-f1; if(f2<0)f2=-f2;
        if((matrixA[j][i]/f1)<(matrixA[j][k2]/f2)) {k2=i;break;}
        else break;
      }
    }
    }
    LGiskl(k1,k2);
    dlin--;
     if(CIter->Checked==true) { PrintTable(); }
    if(Out->Checked==true){PrintTableToFile();}
    Lmetod();
    Res->Lines->Add("");

    if(Metod->Text=="Алгоритм Данцига")if(i2>40) break;
    i2++;
    if(error==true) break;
  }
}
if(Metod->Text=="Третий алгоритм Гомори")
{
  int  i2=0;
  while(Dop()==false)
  {
    Otsechenie3();
    if(CIter->Checked==true) {PrintOtsech(); }
    if(Out->Checked==true){PrintOtsechToFile();}
    k1=n+m+1;
    flag1=false;
    for(i=1;i<n+1;i++)
    if(matrixA[nomstr][i]<0) {flag1=true;break;}
    if(flag1==false)
    {
     MessageDlg( "Задача неразрешима", mtError, TMsgDlgButtons() << mbOK, 0 );
     error=true;goto end;
    }//Несовместная система
    k2=i;
    dlin++;
    for(i=k2;i<n+1;i++) if(matrixA[nomstr][i]<0)
      for(j=0;j<dlin;j++)
      {
        if((matrixA[j][i])<(matrixA[j][k2]))
          {k2=i;break;}
        else
          break;
      }
    LGiskl(k1,k2);
    dlin--;
    if(CIter->Checked==true) { PrintTable(); }
    if(Out->Checked==true){PrintTableToFile();}
    if(error==true) break;
    if(i2>40) break;
    i2++;
  }
}
end: ;
if(CIter->Checked==false)
{
  Res->Lines->Add("");
  PrintTable();
}
if(Out->Checked==true)
{
  efs<<endl;
 PrintTableToFile();
}
Res->Lines->Add("Значение целевой функции:");
Res->Lines->Add(matrixA[0][0]);
if(Out->Checked==true)
{
  efs<<"Значение целевой функции:"<<endl;
  efs<<matrixA[0][0]<<endl;
}
error=false;

}





//---------------------------------------------------------------------------


void __fastcall TForm1::CFunSetEditText(TObject *Sender, int ACol,
      int ARow, const AnsiString Value)
{
double a;
try
{
if((CFun->Cells[ACol][ARow]!="")&&(CFun->Cells[ACol][ARow]!="-"))
a=StrToFloat(CFun->Cells[ACol][ARow]);
}
catch(Exception &e ) {CFun->Cells[ACol][ARow]="";}

}
//---------------------------------------------------------------------------


void __fastcall TForm1::LFunSetEditText(TObject *Sender, int ACol,
      int ARow, const AnsiString Value)
{
double a;
try
{
if((LFun->Cells[ACol][ARow]!="")&&(LFun->Cells[ACol][ARow]!="-"))
a=StrToFloat(LFun->Cells[ACol][ARow]);
}
catch(Exception &e ) {LFun->Cells[ACol][ARow]="";}

}
//---------------------------------------------------------------------------


