//carga un problema que es un dump del simplex de una corrida simsee estándar

unit udump_simsee_1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Math, xMatDefs, matreal,
  ubibfun_onl, udescripcionproblema_onl, usimplex,
  uExcelFile, uMIPSImplex, uListaViolacionesPermitidasSimplex;

var
   my_idvar, my_ivae, my_ires : NInt;
   x_opt, mi_func_opt : NReal;
   xf: TExcelFile;
   kfilx: integer; // fila de las x: en la planilla
   spx : TSimplex;

procedure opt_nvers(var ivar, ivae, ires: NInt);
procedure opt_cargue(p: TProblema_onl);
procedure ResolverReferenciasYCargarSimplex;

implementation

procedure opt_nvers(var ivar, ivae, ires: NInt);
begin
     //guardo donde comienzan mis variables
     my_idvar := ivar;
     my_ivae := ivae;
     my_ires := ires;

     xf:= TExcelFile.Create('', false, true, false);
   //  xf.Abrir( 'C:\simsee\debug\uc2.xls' );
   xf.Abrir('C:\simsee\debug\Simplex_PLANTEO_1_678_0.xls');
   ResolverReferenciasYCargarSimplex;
   //  xf.VisibleOn;


     ivar := ivar + spx.nc-1;
     ires := ires + spx.nf-1;

end;

procedure opt_cargue(p: Tproblema_onl);
var
   mf : TFunc_CombinacionLineal;
   vc : TVectR;
   vIdvars : TDAOFNInt;
   res: TFunc_CombinacionLineal;

begin
     p.spx:=spx;

  //Vuelco el simplex al archivo 'ProblemaEjemplo.xlt' para verificar
  //que el problema armado sea el que quería
  // spx.DumpSistemaToXLT('Problema_uactor1.xlt', '');
end;



procedure ResolverReferenciasYCargarSimplex;
var
	jcol: integer;
	buscando: boolean;
	r: string;
	cnt_Variables, cnt_Restricciones: integer;

	k, j: integer;
  ivae1, ivae2: String;

	lstve: TDAOfNInt;
  xlstAcoplesVEnts: TDAOfAcoplesVEnts;
	NEnteras, nViolacionesPermitidas, nViolacionesUsadas, cnt_RestrRedundantes: integer;
  ficha: TFichaViolacionPermitida;
  nIvars: Integer;
  iVars: TDAofNInt;
  listaViolacionesPermitidas: TListaViolacionesPermitidasSimplex;
begin
	kfilx:= 1;
	jcol:= 1;

  xf.ActivoHoja_numero( 1 );

  kfilx:= 2;
  r:=	 xf.readStr( kfilx, 1);
  if pos('NEnteras:', r ) = 1 then
  begin
  	NEnteras:= xf.readInt( kfilx, 2 );
	  setlength( lstve, NEnteras );
  	for k:= 0 to high( lstve ) do
	  	lstve[k]:= xf.readInt( kfilx, 3+k );
    //paso la lista de variables enteras y el ivae VarAcoplada ResAcoplada
    kfilx:= kfilx + 2;
    setLength( xlstAcoplesVEnts, NEnteras);
    for k:= 0 to high(xlstAcoplesVEnts) do
    begin
      j:= 1;
      ivae1:= xf.readStr( kfilx, 1 );
      ivae2:= xf.readStr( kfilx + j, 1 );
      while (ivae1 = ivae2) do
      begin
        inc(j);
        ivae2:= xf.readStr( kfilx + j, 1 );
      end;
      setLength(xlstAcoplesVEnts[k], j);
      for j:= 0 to high(xlstAcoplesVEnts[k]) do
      begin
        xlstAcoplesVEnts[k][j].ivar:= xf.readInt( kfilx + j, 2 );
        xlstAcoplesVEnts[k][j].ires:= xf.readInt( kfilx + j, 3 );
      end;
      kfilx:= kfilx + length(xlstAcoplesVEnts[k]);
    end;
  end
  else
    NEnteras:= 0;

  //cnt_varfijas
  kfilx:= kfilx + 1;
  cnt_RestrRedundantes:= xf.ReadInt( kfilx, 2 );
  kfilx:= kfilx + 1;
  listaViolacionesPermitidas:= TListaViolacionesPermitidasSimplex.Create;
  nViolacionesUsadas:= xf.ReadInt( kfilx, 2 );
  kfilx:= kfilx + 2;//cnt_ViolacionesUsadas, violacionesPermitidas
  nViolacionesPermitidas:= xf.ReadInt( kfilx, 2 );
  listaViolacionesPermitidas.Capacity:= nViolacionesPermitidas;
  kfilx:= kfilx + 1;//ivar	ires	usada
  for k:= 1 to nViolacionesPermitidas do
  begin
    nIvars:= xf.ReadInt( kfilx + k, 4 );
    SetLength(iVars, nIvars);
    for j:= 0 to high(iVars) do
      iVars[j]:= xf.ReadInt( kfilx + k, 5 + j );

    ficha:= TFichaViolacionPermitida.Create( xf.ReadInt( kfilx + k, 1), iVars);
    ficha.usada:= xf.ReadInt( kfilx + k, 2 ) <> 0;
    ficha.iViolacionAUsar:= xf.ReadInt( kfilx + k, 3 );
    listaViolacionesPermitidas.Add(ficha);
  end;

	buscando:= true;
	kfilx:= 1;
	jcol:= 1;
  xf.ActivoHoja_numero( 1 );
	while buscando and (kfilx < 100) do
	begin
		r:=	xf.ReadStr( kfilx, 1);
		if pos('x:', r ) = 1 then
			buscando:= false
		else
			inc( kfilx );
	end;

	if buscando then
		raise Exception.Create('No encontré la fila del asl x: ' );

	// contamos las variables
	cnt_Variables:= 0;
	jcol:= 2;
	r:= xf.ReadStr( kfilx, jcol );
	while r <> '' do
	begin
		inc( cnt_Variables );
		inc( jcol );
		r:= xf.ReadStr( kfilx, jcol );
	end;

	// contamos las restricciones
	cnt_Restricciones:= 0;
	jcol:= 2;
	r:= xf.ReadStr( kfilx+4, jcol );
	while r <> '' do
	begin
		inc( cnt_Restricciones);
		inc( jcol );
		r:= xf.ReadStr( kfilx+4, jcol );
	end;

  //creamos el simplex
  spx:= TMIPSimplex.Create_init( cnt_Restricciones+1, cnt_Variables+1, NEnteras, NIL, NIL);
  spx.cnt_RestriccionesRedundantes:= cnt_RestrRedundantes;
  spx.violacionesPermitidas.Free;
  spx.violacionesPermitidas:= listaViolacionesPermitidas;
  spx.cnt_ViolacionesUsadas:= nViolacionesUsadas;

  for j:= 1 to cnt_Variables do
    spx.top[j]:= xf.ReadInt( kfilx+5, j + 1 );

  for j:= 1 to cnt_Restricciones do
	  spx.left[j]:= xf.ReadInt( kfilx+6, j + 1 );

  spx.rearmarIndicesiiXiiY;

  // ahora leemos las variables y sus cotas
  spx.cnt_varfijas:= 0;
  for j:= 1 to cnt_Variables do
  begin
	  spx.x_inf.pv[j]:= xf.ReadFloat( kfilx+1, j + 1 );
  	spx.x_sup.pv[j]:= xf.ReadFloat( kfilx+2, j + 1 );
	  spx.flg_x[j]:= xf.ReadInt( kfilx+3, j + 1 );
  	if abs( spx.flg_x[j] ) = 2 then inc (spx.cnt_varfijas );
    spx.nombreVars[j]:= xf.ReadStr( kfilx, j + 1 );
  end;

//  TMIPSimplex(spx).lstAcoplesVEnts:= xlstAcoplesVEnts;
  for j:= 1 to NEnteras do
  begin
    if xlstAcoplesVEnts[j - 1][0].ivar <> -1 then
      TMIPSimplex(spx).set_EnteraConAcoples(j, lstve[j-1], trunc( spx.x_sup.pv[lstve[j-1]] + 0.1),
                                            xlstAcoplesVEnts[j - 1])
    else
      spx.set_entera( j, lstve[j-1], trunc( spx.x_sup.pv[lstve[j-1]] + 0.1) );
  end;

  // cargamos las flg_y
  spx.cnt_igualdades:= 0;
  for j:= 1 to cnt_Restricciones do
  begin
    spx.flg_y[j]:= xf.ReadInt( kfilx+4, j + 1 );
    if abs(spx.flg_y[j]) = 2  then
      inc( spx.cnt_igualdades );
    if spx.iiy[j] > 0 then
      spx.nombreRest[j]:= xf.ReadStr( kfilx + 10 + spx.iiy[j], 1 )
    else
      spx.nombreRest[j]:= xf.ReadStr( kfilx + 10, 1 - spx.iiy[j] )
  end;

  // cargamos la matriz
  for k:= 1 to cnt_Restricciones + 1 do
    for j:= 1 to cnt_Variables + 1 do
    begin
      spx.pon_e(k, j , xf.ReadFloat( kfilx + 10 + k, j + 1 ));
    end;
end;




end.

