function [k, X, Y, pasos, basicos] = vnsimplex(F, signoX, signoXF, basicos, algoritmo)
%vnsimplex
%   [k, X, Y] = vnsimplex(F)
% 
%   Busca la solución de VN mediante el algoritmo simplex. Se parte de unos
%   procesos básicos. Se resuelve VN para esos procesos y se descartan de
%   los básicos los procesos con pérdidas; si ningún proceso tiene
%   rentabilidad positiva se ha encontrado una solución; en caso contrario
%   se incorpora a los básicos el proceso más rentable y se itera el
%   procedimiento. 
% 
%   [k, X, Y] = vnsimplex(F, signoX, signoXF, basicos, algoritmo)
%      F          recetas en tiempo discreto
%      signoX     signo de las intensidades; por defecto X >= 0
%      signoXF    signo de los balances materiales; por defecto X F(k) = 0
%      basicos    procesos básicos con los que se inicia la iteración
%      algoritmo  número del algoritmo para resolver los problemas básicos
%      k, X, Y    factor, intensidades y valores solución
% 
%   Los códigos para los signos son   0 =    1 >=    2 <=    3 >=<
%   Si basicos = [] escoge como básicos los últimos procesos. 
%   Si algoritmo = [] escoge automáticamente el algoritmo para resolver los 
%   sucesivos sistemas básicos.

%   necesita vn.m, forma0.m

if nargin < 2, signoX = []; end
if nargin < 3, signoXF = []; end
if nargin < 4, basicos = []; end
if nargin < 5, algoritmo = []; end

cero = 1e-12;                                                              %define la precisión del cero
[filas, columnas, ancho] = size(F);                                        %determina el tamaño del problema
if isempty(signoX), signoX = 1; end                                        %si no está definido signoX supone que X >= 0
if size(signoX, 2) == 1, signoX = signoX .* ones(1, filas); end            %si signoX es un escalar lo aplica a todos los procesos
s0 = (signoX==0); s2 = (signoX==2); s3 = (signoX==3);                      %establece los procesos con los que no X >= 0
if isempty(basicos), basicos=filas:-1:max(1,filas-columnas*5); end         %si basicos no está definido pone los últimos procesos
if isempty(algoritmo), algoritmo = -1; end                                 %si algoritmo no está definido elección automática
k = []; X = []; Y = []; Xbas = [];                                         %crea las variables
for pasos = 1:200                                                          %inicia una iteración de hasta 200 pasos
    [k,Xbas,Y]=vn(F(basicos,:,:),signoX(basicos),signoXF,algoritmo,k,Xbas,Y);  %busca una solución de VN para los procesos básicos
    if isempty(k), return; end                                                 %si los básicos no tienen solución interrumpe
    benef = forma0(F, k) * Y;                                                  %calcula los beneficios de todos los procesos
    benef(s0) = -Inf; benef(s2) = -benef(s2); benef(s3) = abs(benef(s3));      %ajusta los beneficios según su signoX
    salida = (benef(basicos) < -cero);                                         %calcula los procesos básicos con pérdidas
    basicos(salida) = []; Xbas(salida) = [];                                   %quita de los básicos los procesos con pérdidas
    [beneficiomax, entrada] = max(benef);                                      %calcula el proceso más rentable de todos
    if beneficiomax <= cero, break; end                                        %si no hay procesos más que rentables sale del bucle
    basicos = [entrada, basicos]; Xbas = [0, Xbas];                            %añade el proceso más rentable a los básicos
end                                                                        %repite el bucle
if pasos>=200, disp('Atención, se superó el máximo de iteraciones'); end   %avisa de que se ha superado el máximo de iteraciones
X = zeros(1,filas); X(basicos) = Xbas;                                     %pone las intensidades de los básicos
