% 子问题求解程序 subsolv.m % function [xmma,ymma,zmma,lamma,xsimma,etamma,mumma,zetmma,smma] = ... subsolv(m,n,epsimin,low,upp,alfa,beta,p0,q0,P,Q,a0,a,b,c,d); % % 使用该函数求解MMA生成的子问题可以写成: % % minimize SUM[ p0j/(uppj-xj) + q0j/(xj-lowj) ] + a0*z + % + SUM[ ci*yi + 0.5*di*(yi)^2 ], % % subject to SUM[ pij/(uppj-xj) + qij/(xj-lowj) ] - ai*z - yi <= bi, % alfaj <= xj <= betaj, yi >= 0, z >= 0. % 然后使用拉格朗日的方法求解子问题的对偶问题 % Input: m, n, low, upp, alfa, beta, p0, q0, P, Q, a0, a, b, c, d. % Output: xmma,ymma,zmma, slack variables and Lagrange multiplers. % een = ones(n,1); eem = ones(m,1); epsi = 1; epsvecn = epsi*een; epsvecm = epsi*eem; x = 0.5*(alfa+beta); y = eem; z = 1; lam = eem; xsi = een./(x-alfa); xsi = max(xsi,een); eta = een./(beta-x); eta = max(eta,een); mu = max(eem,0.5*c); zet = 1; s = eem; itera = 0; while epsi > epsimin epsvecn = epsi*een; epsvecm = epsi*eem; ux1 = upp-x; xl1 = x-low; ux2 = ux1.*ux1; xl2 = xl1.*xl1; uxinv1 = een./ux1; xlinv1 = een./xl1; plam = p0 + P'*lam ; qlam = q0 + Q'*lam ; gvec = P*uxinv1 + Q*xlinv1; dpsidx = plam./ux2 - qlam./xl2 ; rex = dpsidx - xsi + eta; rey = c + d.*y - mu - lam; rez = a0 - zet - a'*lam; relam = gvec - a*z - y + s - b; rexsi = xsi.*(x-alfa) - epsvecn; reeta = eta.*(beta-x) - epsvecn; remu = mu.*y - epsvecm; rezet = zet*z - epsi; res = lam.*s - epsvecm; residu1 = [rex' rey' rez]'; residu2 = [relam' rexsi' reeta' remu' rezet res']'; residu = [residu1' residu2']'; residunorm = sqrt(residu'*residu); residumax = max(abs(residu)); ittt = 0; while residumax > 0.9*epsi & ittt < 100 ittt=ittt + 1; itera=itera + 1; ux1 = upp-x; xl1 = x-low; ux2 = ux1.*ux1; xl2 = xl1.*xl1; ux3 = ux1.*ux2; xl3 = xl1.*xl2; uxinv1 = een./ux1; xlinv1 = een./xl1; uxinv2 = een./ux2; xlinv2 = een./xl2; plam = p0 + P'*lam ; qlam = q0 + Q'*lam ; gvec = P*uxinv1 + Q*xlinv1; GG = P*spdiags(uxinv2,0,n,n) - Q*spdiags(xlinv2,0,n,n); dpsidx = plam./ux2 - qlam./xl2 ; delx = dpsidx - epsvecn./(x-alfa) + epsvecn./(beta-x); dely = c + d.*y - lam - epsvecm./y; delz = a0 - a'*lam - epsi/z; dellam = gvec - a*z - y - b + epsvecm./lam; diagx = plam./ux3 + qlam./xl3; diagx = 2*diagx + xsi./(x-alfa) + eta./(beta-x); diagxinv = een./diagx; diagy = d + mu./y; diagyinv = eem./diagy; diaglam = s./lam; diaglamyi = diaglam+diagyinv; if m < n blam = dellam + dely./diagy - GG*(delx./diagx); bb = [blam' delz]'; Alam = spdiags(diaglamyi,0,m,m) + GG*spdiags(diagxinv,0,n,n)*GG'; AA = [Alam a a' -zet/z ]; solut = AA\bb; dlam = solut(1:m); dz = solut(m+1); dx = -delx./diagx - (GG'*dlam)./diagx; else diaglamyiinv = eem./diaglamyi; dellamyi = dellam + dely./diagy; Axx = spdiags(diagx,0,n,n) + GG'*spdiags(diaglamyiinv,0,m,m)*GG; azz = zet/z + a'*(a./diaglamyi); axz = -GG'*(a./diaglamyi); bx = delx + GG'*(dellamyi./diaglamyi); bz = delz - a'*(dellamyi./diaglamyi); AA = [Axx axz axz' azz ]; bb = [-bx' -bz]'; solut = AA\bb; dx = solut(1:n); dz = solut(n+1); dlam = (GG*dx)./diaglamyi - dz*(a./diaglamyi) + dellamyi./diaglamyi; end dy = -dely./diagy + dlam./diagy; dxsi = -xsi + epsvecn./(x-alfa) - (xsi.*dx)./(x-alfa); deta = -eta + epsvecn./(beta-x) + (eta.*dx)./(beta-x); dmu = -mu + epsvecm./y - (mu.*dy)./y; dzet = -zet + epsi/z - zet*dz/z; ds = -s + epsvecm./lam - (s.*dlam)./lam; xx = [ y' z lam' xsi' eta' mu' zet s']'; dxx = [dy' dz dlam' dxsi' deta' dmu' dzet ds']'; stepxx = -1.01*dxx./xx; stmxx = max(stepxx); stepalfa = -1.01*dx./(x-alfa); stmalfa = max(stepalfa); stepbeta = 1.01*dx./(beta-x); stmbeta = max(stepbeta); stmalbe = max(stmalfa,stmbeta); stmalbexx = max(stmalbe,stmxx); stminv = max(stmalbexx,1); steg = 1/stminv; xold = x; yold = y; zold = z; lamold = lam; xsiold = xsi; etaold = eta; muold = mu; zetold = zet; sold = s; itto = 0; resinew = 2*residunorm; while resinew > residunorm & itto < 50 itto = itto+1; x = xold + steg*dx; y = yold + steg*dy; z = zold + steg*dz; lam = lamold + steg*dlam; xsi = xsiold + steg*dxsi; eta = etaold + steg*deta; mu = muold + steg*dmu; zet = zetold + steg*dzet; s = sold + steg*ds; ux1 = upp-x; xl1 = x-low; ux2 = ux1.*ux1; xl2 = xl1.*xl1; uxinv1 = een./ux1; xlinv1 = een./xl1; plam = p0 + P'*lam ; qlam = q0 + Q'*lam ; gvec = P*uxinv1 + Q*xlinv1; dpsidx = plam./ux2 - qlam./xl2 ; rex = dpsidx - xsi + eta; rey = c + d.*y - mu - lam; rez = a0 - zet - a'*lam; relam = gvec - a*z - y + s - b; rexsi = xsi.*(x-alfa) - epsvecn; reeta = eta.*(beta-x) - epsvecn; remu = mu.*y - epsvecm; rezet = zet*z - epsi; res = lam.*s - epsvecm; residu1 = [rex' rey' rez]'; residu2 = [relam' rexsi' reeta' remu' rezet res']'; residu = [residu1' residu2']'; resinew = sqrt(residu'*residu); steg = steg/2; end residunorm=resinew; residumax = max(abs(residu)); steg = 2*steg; end epsi = 0.1*epsi; end xmma = x; ymma = y; zmma = z; lamma = lam; xsimma = xsi; etamma = eta; mumma = mu; zetmma = zet; smma = s;