Contents
function [x,Out] = yzsimplex(A,b,c,bas,nbs,opts) % simplex method for standard LP: min{c'*x: A*x=b, x >= 0} % INPUT: % A = constraint coefficient matrix % b = constraint right-hand side vector % c = objective coefficient vector % bas = initial basic indices % nbs = initial nonbasic indices % opts = parameter options structure % opts.maxit = maximum iterations allowed % opts.prule = pivot rule for choosing entering variables % prule = 1: min-value (most negative) rule % prule = 2: smallest subscript rule % opts.frep = prequency of printout % opts.x = initial basic feasible solution % % OUTPUT: % x = final basic feasible solution if it exists % Out = output options structure % Out.info = character string containing status info: % info(1) = 'm' (e.g., info = 'maxiter reached') % info(1) = 'u' (e.g., info = 'unbounded LP') % info(1) = 'o' (e.g., info = 'optimum obtained') % 1st letter must be the above 3 (lower or upper case) % Out.iter = iterations taken % Out.bas = final basic indices % Out.nbs = final nonbasic indices [m,n] = size(A); if isfield(opts,'maxit'); maxit = opts.maxit; else maxit = m*n; end if isfield(opts,'prule'); prule = opts.prule; else prule = 1; end if isfield(opts,'freq'); freq = opts.freq; else freq = inf; end if isfield(opts,'x'); x = opts.x; else x = []; end info = 'maxiter reached'; for iter = 1:maxit
Extract and factorize basic submatrix
A_B = A(:,bas); [L, U] = lu(A_B); if isempty(x); x = zeros(n,1); x(bas) = U \ (L \ b); x(nbs) = 0; end
computer y and sN
%y = A_B' \ c_B and sN = c_N - A_N'*y y = L' \ (U' \ c(bas)); sN = c(nbs) - A(:,nbs)'*y; if ~mod(iter,freq) fprintf('Iter %4i: Obj = %.8e',iter,c'*x); fprintf(' basis: '); fprintf('%d,', bas(1:3)); fprintf('\n') end
check optimality
if all(sN >= -eps*100) if mod(iter,freq) fprintf('Iter %4i: Obj = %.8e\n',iter,c'*x); end info = 'optimum obtained'; break; end
find entering variable local/global indices
[ie_local,ie_global] = get_enter(sN,nbs,prule);
compute direction and check unboundedness
%d = A_B \ A(:,ie_global); d = U \ (L \ A(:,ie_global)); if all(d <= eps) info = 'unbounded'; break; end
find leaving variable local/global indices and step
[il_local,il_global,step] = get_leave(x(bas),d,bas);
update x
x(bas) = x(bas) - step*d; x(ie_global) = step; x(il_global) = 0;
update partition
bas(il_local) = ie_global; nbs(ie_local) = il_global;
end if freq; fprintf('%s\n',info); end Out.info = info; Out.iter = iter; Out.basis = bas; Out.nonbas = nbs; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ie_local,ie_global] = get_enter(sN, nbs, prule) % Find entering variable's local and global indices % INPUT: % sN = sN vector in lecture notes % nbs = indices for the nonbasics % prule = pivot rule % OUTPUT: % ie_local = local index for entering variable in bas % ie_global = global index for entering variable in x switch prule case 1; % min-value rule [~,ie_local] = min(sN); case 2 % smallest-subscript rule I_neg = find(sN < 0); [~, imin] = min(nbs(I_neg)); ie_local = I_neg(imin); otherwise error('pivot rule must be 1 or 2'); end % find global index ie_global = nbs(ie_local); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [il_local,il_global,step] = get_leave(xB,d,bas) % performing ratio test to determine leaving variable % local and global indices, and the step length % % INPUT: % xB = basic variables % d = direction vector % bas = basic indices % OUTPUT: % il_local = local index for leaving variable in bas % il_global = global index for leaving variable in x % step = step length (how large entering variable can be) tol = eps; % tolerance ipos = find(d > tol); % find indices for which d > 0 ratio = xB(ipos)./d(ipos); % compute ratios for those d > 0 [step, imin] = min(ratio); % find the min ratio and index il_local = ipos(imin); % leaving variable local index il_global = bas(il_local); % leaving variable blobal index