function [sol,flag]=simplexEstandar(A,b,c,indBase)
%% La función [sol,flag]=simplex(A,b,c,indBase)
%% resuelve el problema
%%  min c'x,     S.A.  A.x = b, x>=0
%%
%% CON b>=0 y indBase=indices de las vars. de los vectores base
%%              (vars. holgura o artificiales)
%%
%% y devuelve
%% flag= 0, si no existe solución,
%%     = 1, si la solución es única,
%%     = 2, si existe un segmento de soluciones,
%%     = inf, si la solución es no acotada
%% sol = solucion, en los casos (flag=1 o =2)
%%     = NaN, en otro caso (flag=0 o =inf).
%%

%% EJERCICIO: ¿Cómo detectarías que hay infinitas soluciones?

false=0; true=1;

[n,check]=size(c); if (check~=1),error ('c debe ser columna');end
[m,check]=size(b); if (check~=1),error ('b debe ser columna');end
[mA,nA]=size(A);
if ((n~=nA)|(m~=mA)),
 error(['A debe ser matriz de ',num2str(m),'x',num2str(n)]);
end
if (length(indBase)~=m),
 error ('J debe tener ',num2str(m),' elementos');
end

J=zeros(1,m);
J(1:m)=indBase(1:m);    %VARS BASICAS (seran de holgura)
JN=1:n; JN(J)=[];       % VARS NO BASICAS (resto vars.)

if (rank(A)~=m), % PROBLEMA DEGENERADO
 disp('Problema degenerado: busque v0''*A==0 y quite degeneracion');
 disp(' si v''*b~=0, no tiene solucion');
 error(' si v''*b==0, v_i~=0, elimine la igualdad i-esima');
end

% SUPONEMOS QUE NUESTRO PROBLEMA NO ES DEGENERADO

B = A(:,J);     % VECTORES BASE
x=0*c';         % CALCULA SFB INICIAL
if (rank(B)==m)
 x(J)=B\b;
 if (x<0),      % NO ES SFB (ERROR)
  error('Error imposible obtener SFB inicial');
 else           % ¿DEGENERADA?
  if ( length(find(x==0))>n-m ),
   SFBdegenerada=true;
  else
   SFBdegenerada=false;
  end
 end
else
 error('Error: Mala seleccion de vars holgura o artificiales');
end


continua = true;
while(continua),
 % CONDICION DE ENTRADA EN LA BASE
 cbar = c(JN)'-c(J)'*(B\A(:,JN));
 if (cbar>=0),
  % CRITERIO DE PARADA (OPTIMO ENCONTRADO)
  continua = false;
  flag = 1; sol = x;
 else
  % CRITERIO DE ENTRADA, CBAR NEGATIVO DE MENOR J
  if (SFBdegenerada==false),
   JNneg = find(cbar<0);           % CASO NORMAL
   [value,ind]=min( cbar(JNneg) ); % SELECCIONA MINIMO
   JNselect=JN(JNneg);
   jin = JNselect(ind);            % VARIABLE QUE ENTRA x_jin
  else % SFBdegenerada==true
   JNneg = find(cbar<0);           % REGLA DE BLAND
   ind=1;                          % SELECCIONA EL PRIMERO
   JNselect=JN(JNneg);
   jin = JNselect(ind);            % VARIABLE QUE ENTRA x_jin
   if (jin==7); pause; end
  end
  % AHORA CALCULAREMOS LA DIRECCIÓN DE BÚSQUEDA (FACTIBLE)
  d = 0*c'; d(jin)=1;
  d(J) = -B\A(:,jin);

  if (d(J)>=0),
   % SOLUCION NO ACOTADA
   continua = false;
   flag=inf; sol=inf;
  else
   % AHORA HAY QUE DETERMINAR EL tmax TAL QUE x+tmax*d SIGA
   % SIENDO FACTIBLE (CRITERIO DE SALIDA)
   Jneg = J(d(J)<0);
   [tmax,ind]=min( -x(Jneg)./d(Jneg) );
   % VARIABLE QUE SALE x_jsal
   jsal = Jneg(ind);

   % nuevo vértice
   x = x + tmax*d;
   J(find(J==jsal))=jin; J=sort(J);      % ORDENO POR ESTETICA!!
   JN(find(JN==jin))=jsal; JN=sort(JN);
   B = A(:,J);   % vectores base
   %pause;
  end

 end

end
