//---------------------------------------------------------------------------
#include <Classes.hpp>
//
#include <windows.h>
#include <vcl.h>
#include <stdio.h>
#include <fstream.h>
#pragma hdrstop
#include "Main.h"
#include "misc.hpp"
//#include "about.hpp"
#include "fruc.h"
//#include "gomsolv.h"
#include "gsolv_c.h"
#include "PrgForm.h"
//---------------------------------------------------------------------------
TMainForm *MainForm;
//---------------------------------------------------------------------------
#pragma package(smart_init)

TSolveThread::TSolveThread( PSimplexTable ast, PBoolVector aZ, int an, int anb,
    						       int aalg, bool aEachStep, TStrings *aS ) : TThread( true )
{
 FreeOnTerminate = true;

 st = ast;
 Z = aZ;
 n = an;
 nb = anb;
 alg = aalg;
 EachStep = aEachStep;
 S = aS;


 HaveError = false;
}

__fastcall TSolveThread::~TSolveThread()
{
 delete[] st;
 delete[] Z;
}


void TSolveThread::Jstep( PIntVector basic, int an, int ncut )
{
 int i,j;
 int col,row;
 int haveneg;
 TFruc f;

 do{
  // Найти отрицательный элемент в 1ом столбце
  haveneg = 0;
  for( i=1; (i <= an)&&(!haveneg); i++ )
   haveneg = (st[(nb+1)*i].sign() < 0);
  row = i-1;

  if(haveneg)
  {
   // Ищем положительное отношение
   for( i=1; i <= nb; i++ )
   {
    f = st[(nb+1)*row+i];
    if( f.x == 0 )continue;
    if( ((-st[i])/f).sign() >= 0 )break;
   }
   if( i > nb )throw Exception( "Целевая функция неограничена" );

   // Ищем направляющий элемент в строке row
   TFruc min = (-st[i])/st[(nb+1)*row+i];

   col = i++;
   for( ; i <= nb; i++ )
   {
    if ( st[(nb+1)*row+i].sign() < 0 )
    {
     f = st[(nb+1)*row+i];
     if( f.x == 0 )continue;
     f = (-st[i])/f;
     if( f < min )
     {
      min = f;
      col = i;
     }
    }
   }

   if( EachStep )
    if( ncut > 0 )PrintTable( basic, an-1, ncut, row, col );else
     PrintTable( basic, an, 0, row, col );

   f = st[(nb+1)*row+col];

   // Делаем шаг Жорданова исключения
   for( i = 0; i <= an; i++ )
    for( j = 0; j <= nb; j++ )
    {
     if( i == row || j == col )continue;

     st[(nb+1)*i+j] = st[(nb+1)*i+j] - (st[(nb+1)*i+col]*st[(nb+1)*row+j])/f;
    }

   for( i = 0; i <= an; i++ )
    st[(nb+1)*i+col] = st[(nb+1)*i+col]/(-f);

   for( i = 0; i <= nb; i++ )
    st[(nb+1)*row+i] = 0;
   st[(nb+1)*row+col] = -1;

   if( ncut > 0 )
   {
    basic[col-1] = ncut;
    ncut = 0;
    an--;
   }else basic[col-1] = row;
  }
 }while(haveneg);
}

void __fastcall TSolveThread::Execute()
{
 int i,j;
 int col,row, cols;

 int haveneg;
 int haveint;
 int NVar=n, an, ncut;
 int hl, hj[30], ii, r, q, i1;
  __int64 lambda;
 TFruc f, min, M, aa, bb;
 bool  flag;
 float a, b;
 int color=0;
 float b1,b2,b3;

 //Sleep( 5000 );
 PIntVector basic = new int[nb];
 PSimplexTable s = new TFruc[(nb+1)*(n+2)];

 MainForm->Image1->Canvas->Brush->Color=clWhite;
 MainForm->Image1->Canvas->FillRect(Rect(0,0,MainForm->Image1->Width,MainForm->Image1->Height));



 MainForm->Image1->Canvas->Pen->Color=clBlack;
 MainForm->Image1->Canvas->MoveTo(30,MainForm->Image1->Height);
 MainForm->Image1->Canvas->LineTo(30,10);
 MainForm->Image1->Canvas->LineTo(27,20);
 MainForm->Image1->Canvas->LineTo(33,20);
 MainForm->Image1->Canvas->LineTo(30,10);
 MainForm->Image1->Canvas->TextOut(15,7,"x2");

 MainForm->Image1->Canvas->MoveTo(0,356);
 MainForm->Image1->Canvas->LineTo(458,356);
 MainForm->Image1->Canvas->LineTo(448,353);
 MainForm->Image1->Canvas->LineTo(448,359);
 MainForm->Image1->Canvas->LineTo(458,356);
 MainForm->Image1->Canvas->TextOut(453,363,"x1");

 MainForm->Image1->Canvas->TextOut(20,363,0);

 for (i=1;i<=7;i++)
  {
   MainForm->Image1->Canvas->MoveTo(30+50*i,357);
   MainForm->Image1->Canvas->LineTo(30+50*i,354);
   MainForm->Image1->Canvas->TextOut(28+50*i,363,i);

   MainForm->Image1->Canvas->MoveTo(29,356-50*(i-1));
   MainForm->Image1->Canvas->LineTo(32,356-50*(i-1));
   if (i!=1)
    MainForm->Image1->Canvas->TextOut(20,350-50*(i-1),i-1);
  }

  MainForm->Image1->Canvas->Pen->Style=TPenStyle(0);
  MainForm->Image1->Canvas->Pen->Color=clGray;
  for (i=1;i<=7;i++)
   {
    MainForm->Image1->Canvas->MoveTo(30+50*i,356);
    MainForm->Image1->Canvas->LineTo(30+50*i,356-50*6);
    if (i!=7)
    {
     MainForm->Image1->Canvas->MoveTo(30,356-50*i);
     MainForm->Image1->Canvas->LineTo(30+50*7,356-50*i);
    }
   }
  MainForm->Image1->Canvas->Pen->Style=TPenStyle(0);

  MainForm->Image1->Canvas->TextOut(398,15,"Очерёдность");
  MainForm->Image1->Canvas->TextOut(402,30,"отсечений");
  for (i=0;i<6;i++)
  {
   switch (i+1)
   {
    case 1:
     MainForm->Image1->Canvas->Pen->Color=clRed;
    break;
    case 2:
     MainForm->Image1->Canvas->Pen->Color=clGreen;
    break;
    case 3:
     MainForm->Image1->Canvas->Pen->Color=clFuchsia;
    break;
    case 4:
     MainForm->Image1->Canvas->Pen->Color=clLime;
    break;
    case 5:
     MainForm->Image1->Canvas->Pen->Color=clBlack;
    break;
    case 6:
     MainForm->Image1->Canvas->Pen->Color=clAqua;
    break;
   }

    MainForm->Image1->Canvas->TextOut(410,64+i*20,i+1);
    MainForm->Image1->Canvas->MoveTo(420,70+i*20);
    MainForm->Image1->Canvas->LineTo(460,70+i*20);
    MainForm->Image1->Canvas->MoveTo(420,71+i*20);
    MainForm->Image1->Canvas->LineTo(460,71+i*20);

  }

/*
  MainForm->Image1->Canvas->Pen->Color=TColor(250);
  MainForm->Image1->Canvas->Brush->Color=TColor(250);
//  MainForm->Image1->Canvas->Ellipse(30+50*x1,356-50*x2,2,2);;
  MainForm->Image1->Canvas->Ellipse(200,200,20,20);
  MainForm->Image1->Canvas->Pen->Color=TColor(850);
*/

  MainForm->Image1->Canvas->Pen->Color=clBlue;
  for (i=(nb+1);i<=n;i++)
   {
    aa=-st[(nb+1)*i+1]/st[(nb+1)*i+2];
    bb=st[(nb+1)*i]/st[(nb+1)*i+2];
    a=(float)aa.x/(float)aa.y;
    b=(float)bb.x/(float)bb.y;
    MainForm->Image1->Canvas->MoveTo(30,356-50*(a*0+b));
    MainForm->Image1->Canvas->LineTo(30+50*7,356-50*(a*7+b));
    MainForm->Image1->Canvas->MoveTo(31,356-50*(a*0+b));
    MainForm->Image1->Canvas->LineTo(31+50*7,356-50*(a*7+b));

   }

   MainForm->Image1->Canvas->Pen->Color=clBlack;

 if ( alg==3 )
 { try{ // catch

   try{ // finally

  // строим исходную таблицу - целочисленную и l-нормальную

 for( i = 0; i < nb; i++ ) basic[i] = i+1;
 r=0;
 do{
  // Найти отрицательный элемент в 1й строке
  haveneg = 0;
  for( i=1; (i <= nb)&&(!haveneg); i++ )
   haveneg = (st[i].sign() < 0);
  col = i-1;
  if (haveneg)
  {   // Proverayem, est li dopolnitelnay stroka v ishodnoy table
    f.x=1;
    f.y=1;
    flag=0;
    for (i=(nb+1); i<=n; i++)
    { for (j=1; j<=nb; j++)
      { flag=(st[(nb+1)*i+j]==f);
        if (!flag) break;
      }
      if (flag) break;
    }
    if (i<=n)
    { row=i;
      an=n;
      ncut=0;
    }
    else
    { if (r==0)
      {// Vvodim dopolnitelnuy peremennuy (shag simplex metoda)
       // Postroenie ishodnogo l-psevdoplana
    for (i=1; i<=nb; i++)
       s[i]=-1;
    for (i=1; i<=n; i++)
      for (j=0; j<=nb; j++)
        s[(nb+1)*i+j]=st[(nb+1)*i+j];
    do
    { flag=0;
      for (i=1; i<=n; i++)
        if (s[(nb+1)*i].sign() < 0)
        { row=i;
          flag=1;
          break;
        }
    if (i<=n) // Stroim ishodn. oporn. plan
    { for (j=1; (j<=nb)&&(s[(nb+1)*row+j].sign()>0); j++);
      if (j>nb) throw Exception ("Система ограничений не совместна");
      cols=j;
      //Choice razresh. stroku
      for (i=1; i<=n; i++)
        if ((s[(nb+1)*i+cols].sign()>0)&&(s[(nb+1)*i].sign()>0))
         {min=s[(nb+1)*i]/s[(nb+1)*i+cols];
          row=i;
          break;
         }
      for (i=row+1; i<=n; i++)
      { f=s[(nb+1)*i+cols];
        if ((f.sign()>0)&&(s[(nb+1)*i].sign()>0))
        { f=s[(nb+1)*i]/f;
          if (f<min)
          { min=f;
            row=i;
          }
        }
      }
     // Shag Jordanova isklucheniay
     f = s[(nb+1)*row+cols];
     for( i = 0; i <= n; i++ )
      for( j = 0; j <= nb; j++ )
      {
       if( i == row || j == cols )continue;
       s[(nb+1)*i+j] = s[(nb+1)*i+j] - (s[(nb+1)*i+cols]*s[(nb+1)*row+j])/f;
      }

     for( i = 0; i <= n; i++ )
      s[(nb+1)*i+cols] = (-s[(nb+1)*i+cols])/f;

     for( i = 0; i <= nb; i++ )
       s[(nb+1)*row+i] = 0;
     s[(nb+1)*row+cols] = -1;
     }
    } while (flag);
    do
    { flag=0;
      for( i=1; (i <= nb)&&(!flag); i++ )
       flag = (s[i].sign() < 0);
      if (flag)
      {cols = i-1;
       //Choice razresh. stroku
       for (i=1; i<=n; i++)
        if ((s[(nb+1)*i+cols].sign()>0)&&(s[(nb+1)*i].sign()>0))
         {min=s[(nb+1)*i]/s[(nb+1)*i+cols];
          row=i;
          break;
         }
      if (i>n) throw Exception ("Задача неразрешима");
      for (i=row+1; i<=n; i++)
      { f=s[(nb+1)*i+cols];
        if ((f.sign()>0)&&(s[(nb+1)*i].sign()>0))
        { f=s[(nb+1)*i]/f;
          if (f<min)
          { min=f;
            row=i;
          }
        }
      }
     // Shag Jordanova isklucheniay
     f = s[(nb+1)*row+cols];
     for( i = 0; i <= n; i++ )
      for( j = 0; j <= nb; j++ )
      {
       if( i == row || j == cols )continue;
       s[(nb+1)*i+j] = s[(nb+1)*i+j] - (s[(nb+1)*i+cols]*s[(nb+1)*row+j])/f;
      }

     for( i = 0; i <= n; i++ )
      s[(nb+1)*i+cols] = (-s[(nb+1)*i+cols])/f;

     for( i = 0; i <= nb; i++ )
       s[(nb+1)*row+i] = 0;
     s[(nb+1)*row+cols] = -1;

      }
     } while (flag);

////////////////////////////////////////////////////////////
     // Find the M
     f=s[0];
     if (f.x%f.y==0) M=f;
       else M=f.x/f.y+1;  }
     st[(nb+1)*(n+1)]=M;
     for (i=1; i<=nb; i++)
       st[(nb+1)*(n+1)+i]=1;
     row=n+1;
     ncut=-1;
     an=n;
    }
    // Find the napravl. element v stroke row
   min = (-st[col])/st[(nb+1)*row+col];

   for( i=1; i <= nb; i++ )
   {
    f = st[(nb+1)*row+i];
    if( f.x == 0 )continue;
    f = (-st[i])/f;
    if( (f.sign() > 0)&&(f < min) )
    {
     min = f;
     col = i;
    }
   }
   if( EachStep )
    PrintTable( basic, an, ncut, row, col );

   // Delaem Shag Jordanova iskluchenia
   f = st[(nb+1)*row+col];
   for( i = 0; i <= an; i++ )
    for( j = 0; j <= nb; j++ )
    {
     if( i == row || j == col )continue;
     st[(nb+1)*i+j] = st[(nb+1)*i+j] - (st[(nb+1)*i+col]*st[(nb+1)*row+j])/f;
    }

   for( i = 0; i <= an; i++ )
    st[(nb+1)*i+col] = (-st[(nb+1)*i+col])/f;

   for( i = 0; i <= nb; i++ )
    st[(nb+1)*row+i] = 0;
   st[(nb+1)*row+col] = -1;

   basic[col-1] = row;
   r--;
  }
  }while(haveneg);

  // проверка решения на допустимость
  do { haveneg=0;
       for (i=1; (i<=n)&&(!haveneg); i++)
         haveneg=(st[(nb+1)*i].sign()<0);
       if (haveneg)
         { NVar++;
//           Jstep3(basic, n+1, NVar);
  ncut=NVar;
  an=n+1;
  haveneg=0;
  for (i=1; (i<an)&&(!haveneg); i++)
    haveneg=(st[(nb+1)*i].sign()<0);
    row=i-1;
  // Ищем отрицательные элементы в строке row
  for (i=1; (i<=nb)&&(st[(nb+1)*row+i].sign()>=0); i++);
  if (i>nb) throw Exception ("problem have not solve");
  col=i;
  // Выбираем направляющий столбец

  ////////////////////////////////////////////////////

   TFruc min = st[i];
   for( ; i <= nb; i++ )
   {
    if ( st[(nb+1)*row+i].sign() < 0 )
    {
     f = st[i];
 //    if( f.x == 0 )continue;
     if( f < min )
     {
      min = f;
      col = i;
     }
    }
   }
  // Choice the lambda
   j=0;
   i=0;
   for (j=1; j<=nb; j++)
     { for (i=0; (i<row)&&(st[(nb+1)*i+j].sign()<=0); i++);
       hj[j-1]=i;
      }
   hl=hj[col-1];
 //  lambda=-st[(nb+1)*row+col].x;
   //////////////////////////////////////////////////////
   ii=0;
   PIntVector zi=new int[nb];
   for (j=1; j<=nb; j++)
     if ((st[(nb+1)*row+j].sign()<0)&&(j!=col)&&(hj[j-1]==hl))
      { zi[ii]=j;
        ii++;
      }
   if (ii==0) lambda=-st[(nb+1)*row+col].x;
    else
    { PIntVector zj=new int[nb];
      ii--;
      for (i=0; i<=ii; i++)
      { j=zi[i];
      //1
        if (st[(nb+1)*hl+j]==st[(nb+1)*hl+col])
        { zj[j-1]=1;
          continue;
        }
      //2
        f.x=1; f.y=1;
        if (st[(nb+1)*hl+col]>f)
        { q = st[(nb+1)*hl+j].x/st[(nb+1)*hl+col].x;
          f = st[(nb+1)*hl+col].x * q;
          r = st[(nb+1)*hl+j].x - f.x;
          if ((r < st[(nb+1)*hl+col].x) && (r!=0))
            { zj[j-1]=q;
              continue;
            }
        }
      //3
         for (i1=hl; ((i1<=n)&&(st[(nb+1)*i1+j].x==q*st[(nb+1)*i1+col].x)); i1++);
         if (st[(nb+1)*i1+j].x>q*st[(nb+1)*i1+col].x)
           {zj[j-1]=q;
            continue;
           }
      //4
         else {zj[j-1]=q-1;
               continue;
              }
      }
      TFruc max=-st[(nb+1)*row+zi[0]];
      max.y=max.y*zj[0];
      for (i=0; i<=ii; i++)
      { f=-st[(nb+1)*row+zi[i]];
        f.y=f.y*zj[zi[i]-1];
        if (f > max)
          max=f;
      }
      if (-st[(nb+1)*row+col].x > max.x) lambda=-st[(nb+1)*row+col].x;
        else lambda=max.x;
    }
   // Stroim integer pravilnoe otsechenie
   for (j=0; j<=nb; j++)
      { f.x=st[(nb+1)*row+j].x;
        f.y=lambda;
        if (f.x%f.y==0) st[(nb+1)*an+j]=f.x/f.y;
         else {if (f.sign()<0) st[(nb+1)*an+j]=f.x/f.y-1;
                  else st[(nb+1)*an+j]=f.x/f.y;
              }
      }
    st[(nb+1)*(an+1)].x = lambda;
    row=an;
    if (EachStep)
    PrintTable( basic, an-1, ncut,row, col);

    if (nb==2)
     {
      color++;
      Picture(color);
     }

    // Делаем шаг Жорданова исключения
   row=an;
   f=st[(nb+1)*row+col];
   for( i = 0; i <= an; i++ )
    for( j = 0; j <= nb; j++ )
    {
     if( i == row || j == col )continue;

     st[(nb+1)*i+j] = st[(nb+1)*i+j] - (st[(nb+1)*i+col]*st[(nb+1)*row+j])/f;
    }

   for( i = 0; i <= an; i++ )
    st[(nb+1)*i+col] = st[(nb+1)*i+col]/(-f);

   for( i = 0; i <= nb; i++ )
    st[(nb+1)*row+i] = 0;
   st[(nb+1)*row+col] = -1;

   if( ncut > 0 )
   {
    basic[col-1] = ncut;
    ncut = 0;
    an--;
   }else basic[col-1] = row;

         }
     } while (haveneg);
  if( EachStep )
    PrintTable( basic, n, 0, -1, -1 );

  MainForm->Image1->Canvas->Pen->Color=clRed;
  MainForm->Image1->Canvas->Brush->Color=clRed;
  MainForm->Image1->Canvas->Ellipse(27+50*st[3].x,353-50*st[6].x,33+50*st[3].x,359-50*st[6].x);
  MainForm->Image1->Canvas->Pen->Color=clBlack;


  PrintSolve();
 }
 __finally
  {
   delete[] basic;
  }

 }
  catch( Exception &e )
  {
   Msg = e.Message;
   HaveError = true;
  }
  } // if (alg == 3)

 else
 {
try{ // catch

try{ // finally

 for( i = 0; i < nb; i++ )basic[i] = i+1;


 do{
  // Найти отрицательный элемент в 1й строке
  haveneg = 0;
  for( i=1; (i <= nb)&&(!haveneg); i++ )
   haveneg = (st[i].sign() < 0);
  col = i-1;

  if(haveneg)
  {
   // Ищем в столбце col положительный элемент
   for( i=1; (i <= n)&&(st[(nb+1)*i+col].sign() <= 0); i++ );
   if( i > n )throw Exception( "Система ограничений несовместна" );
   row = i;
   for( i=row+1; (i <= n)&&(st[(nb+1)*i+col].sign() <= 0); i++ );
   if( i <= n )row=i;

   // Ищем направляющий элемент в строке row
   TFruc min = (-st[col])/st[(nb+1)*row+col];

   for( i=1; i <= nb; i++ )
   {
    f = st[(nb+1)*row+i];
    if( f.x == 0 )continue;
    f = (-st[i])/f;
    if( (f.sign() > 0)&&(f < min) )
    {
     min = f;
     col = i;
    }
   }

   if( EachStep )
    PrintTable( basic, n, 0, row, col );

   // Делаем шаг Жорданового исключения
   f = st[(nb+1)*row+col];
   for( i = 0; i <= n; i++ )
    for( j = 0; j <= nb; j++ )
    {
     if( i == row || j == col )continue;
     st[(nb+1)*i+j] = st[(nb+1)*i+j] - (st[(nb+1)*i+col]*st[(nb+1)*row+j])/f;
    }

   for( i = 0; i <= n; i++ )
    st[(nb+1)*i+col] = (-st[(nb+1)*i+col])/f;

   for( i = 0; i <= nb; i++ )
    st[(nb+1)*row+i] = 0;
   st[(nb+1)*row+col] = -1;

   basic[col-1] = row;
  }
 }while(haveneg);

 Jstep( basic, n, 0 );





 do{
// Проверка решения на целочисленность
  haveint = 1;
  for( i = 0; i < nb; i++ )haveint &= Z[i];
  if( haveint )haveint = (st[0].x%st[0].y == 0);else haveint = 1;

  for( i = 1; (i <= nb)&&(haveint); i++ )
  {
   f = st[(nb+1)*i];
   haveint = (Z[i-1]&&(f.x%f.y == 0))||(!Z[i-1]);
  }
  i--;
  if( !haveint )
  {
   // Отсечение
   switch(alg)
   {
    case algGomoryI:
     for( j = 0; j <= nb; j++ )
      st[(n+1)*(nb+1)+j]=-(!(st[(nb+1)*i+j]));
     if (nb==2)
      {
       color++;
       Picture(color);
      }
     break;
    case algGomoryII:
     st[(n+1)*(nb+1)]=-(!(st[(nb+1)*i]));
     for( j = 1; j <= nb; j++ )
     {
       if( Z[basic[j-1]] )
       //Для целочисленных переменных

       if(st[(nb+1)*i+j].x > st[(nb+1)*i].x)
        st[(n+1)*(nb+1)+j]=-(!(st[(nb+1)*i]))/(-(!(st[(nb+1)*i]))+1)*(-(!st[(nb+1)*i+j])+1);
       else
        st[(n+1)*(nb+1)+j]=-(!(st[(nb+1)*i+j]));
      else
       //Для нецелочисленных переменных
       if( st[(nb+1)*i+j].sign() < 0 )
        st[(n+1)*(nb+1)+j]=-(!(st[(nb+1)*i]))/(-(!(st[(nb+1)*i]))+1)*(-st[(nb+1)*i+j]);
       else
        st[(n+1)*(nb+1)+j]=-(st[(nb+1)*i+j]);
     }
     if (nb==2)
      {
       color++;
       Picture(color);
      }
   }
   NVar++;

   Jstep( basic, n+1, NVar );
  }
 }while(!haveint);


  MainForm->Image1->Canvas->Pen->Color=clRed;
  MainForm->Image1->Canvas->Brush->Color=clRed;
  MainForm->Image1->Canvas->Ellipse(27+50*(float)st[3].x/(float)st[3].y,
                  353-50*(float)st[6].x/(float)st[6].y,
                  33+50*(float)st[3].x/(float)st[3].y,
                  359-50*(float)st[6].x/(float)st[6].y);
  MainForm->Image1->Canvas->Pen->Color=clBlack;




 if( EachStep )
    PrintTable( basic, n, 0, -1, -1 );

 PrintSolve();
}
__finally
 {
  delete[] basic;
 }

}
 catch( Exception &e )
 {
  Msg = e.Message;
  HaveError = true;
 }
 } // else (alg == 1 || 2)
}

void TSolveThread::PrintTable( PIntVector basic, int an, int ncut,
                 int r, int s )
{
 int i,j;
 AnsiString str1;

 str1 = AnsiString("        1    ");
 for( i=0; i<nb; i++ )
  str1 += Format( "   -x%d    ", ARRAYOFCONST(((int)basic[i])) );
 S->Add( str1 );

 for( i=0; i<=an; i++ )
 {
  str1 = Format( "x%d ", ARRAYOFCONST(((int)i)) );
  for( j=0; j<=nb; j++ )
  {if (st[i*(nb+1)+j].y!=1)
    str1 += Format( " %4d/%-3d ", ARRAYOFCONST(((int)st[i*(nb+1)+j].x,(int)st[i*(nb+1)+j].y)) );
   else
    str1 += Format( " %4d     ", ARRAYOFCONST(((int)st[i*(nb+1)+j].x)) );
  }
  S->Add( str1 );
 }

 if( ncut > 0 )
 {
  S->Add( "Отсечение" );
  str1 = Format( "x%d ", ARRAYOFCONST(((int)ncut)) );
  for( j=0; j<=nb; j++ )
  { if (st[(an+1)*(nb+1)+j].y!=1)
     str1 += Format( " %4d/%-3d ", ARRAYOFCONST(((int)st[(an+1)*(nb+1)+j].x,(int)st[(an+1)*(nb+1)+j].y)) );
    else
     str1 += Format( " %4d     ", ARRAYOFCONST(((int)st[(an+1)*(nb+1)+j].x)) );
  }
  S->Add( str1 );
  if (alg==3)
   { str1 = Format( "lambda =  %d", ARRAYOFCONST(((int)st[(nb+1)*(an+2)].x)));
     S->Add( str1 );
   }
 }
 if (ncut==-1)
 { S->Add("Вспомогательная переменная");
   str1 = Format( "x%d ", ARRAYOFCONST(((int)(an+1))) );
   for( j=0; j<=nb; j++ )
   { if (st[(an+1)*(nb+1)+j].y!=1)
      str1 += Format( " %4d/%-3d ", ARRAYOFCONST(((int)st[(an+1)*(nb+1)+j].x,(int)st[(an+1)*(nb+1)+j].y)) );
     else
      str1 += Format( " %4d     ", ARRAYOFCONST(((int)st[(an+1)*(nb+1)+j].x)) );
   }
   S->Add( str1 );

 }
 if( r >= 0 && s >= 0 )
  S->Add( Format( "Разрешающий элемент (%d, %d)", ARRAYOFCONST(((int)r, (int)s)) ) );

 S->Add( "" );
}

void TSolveThread::PrintSolve()
{
 AnsiString str;

 S->Add( "Ответ" );
 if (st[0].y!=1)
  S->Add( Format( " целевая функция = %d/%d", ARRAYOFCONST(((int)st[0].x,(int)st[0].y)) ) );
 else
  S->Add( Format( " целевая функция = %d", ARRAYOFCONST(((int)st[0].x)) ) );

 str = " (";
 for( int i=1; i<=nb; i++ )
 {if (st[i*(nb+1)].y!=1)
   str += Format( "%d/%d", ARRAYOFCONST(((int)st[i*(nb+1)].x,(int)st[i*(nb+1)].y)) );
  else
   str += Format( "%d", ARRAYOFCONST(((int)st[i*(nb+1)].x)) );
  if( i < nb )str += ",";
 }
 str += ")";
 S->Add( str );
}


void __fastcall TSolveThread::Picture(int color)
{
 int i;
 float b1,b2,b3,x1,x2;
 TFruc stt[8],rr1,rr2;
 rr1.x=1;



 for (i=0;i<=2;i++)
  {
   if (i==0)
   {
    stt[i]=st[3+i];
    stt[i+3]=st[6+i];
    stt[i+6]=st[30+i];
   }
   else
   {
    stt[i]=-st[3+i];
    stt[i+3]=-st[6+i];
    stt[i+6]=-st[30+i];
   }
  }

  if (stt[1].x!=0)
  {
   stt[0]=-stt[0]/stt[1];
   stt[2]=-stt[2]/stt[1];
   stt[1]=rr1/stt[1];
   stt[3]=stt[3]+stt[4]*stt[0];
   stt[5]=stt[5]+stt[4]*stt[2];
   stt[4]=stt[4]*stt[1];
    stt[3]=-stt[3]/stt[5];
    stt[4]=-stt[4]/stt[5];
    stt[5]=rr1/stt[5];
   stt[0]=stt[0]+stt[2]*stt[3];
   stt[1]=stt[1]+stt[2]*stt[4];
   stt[2]=stt[2]*stt[5];
   stt[6]=stt[6]+stt[7]*stt[0]+stt[8]*stt[3];
   rr2=stt[7];
   stt[7]=stt[7]*stt[1]+stt[8]*stt[4];
   stt[8]=rr2*stt[2]+stt[8]*stt[5];
  }
  else
  {
   stt[0]=-stt[0]/stt[2];
   stt[2]=rr1/stt[2];
   stt[3]=stt[3]+stt[5]*stt[0];
   stt[5]=stt[5]*stt[2];
   stt[3]=-stt[3]/stt[4];
   stt[5]=-stt[5]/stt[4];
   stt[4]=rr1/stt[4];
   stt[6]=stt[6]+stt[7]*stt[3]+stt[8]*stt[0];
   rr2=stt[7];
   stt[7]=stt[7]*stt[4]+stt[8]*stt[2];
   stt[8]=rr2*stt[5];
  }

      switch(color%6)
      {
       case 1:
        MainForm->Image1->Canvas->Pen->Color=clRed;
       break;
       case 2:
        MainForm->Image1->Canvas->Pen->Color=clGreen;
       break;
       case 3:
        MainForm->Image1->Canvas->Pen->Color=clFuchsia;
       break;
       case 4:
        MainForm->Image1->Canvas->Pen->Color=clLime;
       break;
       case 5:
        MainForm->Image1->Canvas->Pen->Color=clBlack;
       break;
       case 0:
        MainForm->Image1->Canvas->Pen->Color=clAqua;
       break;
      }


      b1=(float)stt[6].x/(float)stt[6].y;
      b2=(float)stt[7].x/(float)stt[7].y;
      b3=(float)stt[8].x/(float)stt[8].y;
      if (b3!=0)
      {
       b1=-b1/b3;
       b2=-b2/b3;
       if (b2!=0)
       {
        MainForm->Image1->Canvas->MoveTo(30,356-50*b1);
        MainForm->Image1->Canvas->LineTo(30+50*7,356-50*(b2*7+b1));
        MainForm->Image1->Canvas->MoveTo(31,356-50*b1);
        MainForm->Image1->Canvas->LineTo(31+50*7,356-50*(b2*7+b1));
        MainForm->Image1->Canvas->MoveTo(29,356-50*b1);
        MainForm->Image1->Canvas->LineTo(29+50*7,356-50*(b2*7+b1));
       }
       else
       {
        MainForm->Image1->Canvas->MoveTo(30,356-50*b1);
        MainForm->Image1->Canvas->LineTo(30+50*7,356-50*(b2*7+b1));
        MainForm->Image1->Canvas->MoveTo(30,355-50*b1);
        MainForm->Image1->Canvas->LineTo(31+50*7,355-50*(b2*7+b1));
       }

      }
      else
      {
       b1=-b1/b2;
       MainForm->Image1->Canvas->MoveTo(30+b1*50,356);
       MainForm->Image1->Canvas->LineTo(30+50*b1,356-50*7);
       MainForm->Image1->Canvas->MoveTo(31+b1*50,356);
       MainForm->Image1->Canvas->LineTo(31+50*b1,356-50*7);

      }




}

