Professional Documents
Culture Documents
****************************************************************
!*
LINEAR PROGRAMMING: THE SIMPLEX METHOD
*
!* ------------------------------------------------------------ *
!* SAMPLE RUN:
*
!* Maximize z = x1 + x2 + 3x3 -0.5x4 with conditions:
*
!*
x1 + 2x3 <= 740
*
!*
2x2 - 7x4 <= 0
*
!*
x2 - x3 + 2x4 >= 0.5
*
!*
x1 + x2 + x3 +x4 = 9
*
!*
and all x's >=0.
*
!*
*
!* Number of variables in E.F.: 4
*
!* Number of <= inequalities..: 2
*
!* Number of >= inequalities..: 1
*
!* Number of = equalities.....: 1
*
!* Input Economic Function:
*
!* Coefficient # 1: 1
*
!* Coefficient # 2: 1
*
!* Coefficient # 3: 3
*
!* Coefficient # 4: -0.5
*
!* Constant term..: 0
*
!* Input constraint # 1:
*
!* Coefficient # 1: 1
*
!* Coefficient # 2: 0
*
!* Coefficient # 3: 2
*
!* Coefficient # 4: 0
*
!* Constant term..: 740
*
!* Input constraint # 2:
*
!* Coefficient # 1: 0
*
!* Coefficient # 2: 2
*
!* Coefficient # 3: 0
*
!* Coefficient # 4: -7
*
!* Constant term..: 0
*
!* Input constraint # 3:
*
!* Coefficient # 1: 0
*
!* Coefficient # 2: 1
*
!* Coefficient # 3: -1
*
!* Coefficient # 4: 2
*
!* Constant term..: 0.5
*
!* Input constraint # 4:
*
!* Coefficient # 1: 1
*
!* Coefficient # 2: 1
*
!* Coefficient # 3: 1
*
!* Coefficient # 4: 1
*
!* Constant term..: 9
*
!*
*
!* Input Table:
*
!*
0.00
1.00
1.00
3.00
-0.50
*
!* 740.00
-1.00
0.00
-2.00
0.00
*
!*
0.00
0.00
-2.00
0.00
7.00
*
!*
0.50
0.00
-1.00
1.00
-2.00
*
!*
9.00
-1.00
-1.00
-1.00
-1.00
*
!*
*
!* Maximum of E.F. =
17.02500
*
!* X 1 =
0.000000
*
!* X 2 =
3.325000
*
!* X 3 =
4.725000
*
!* X 4 =
0.950000
*
!*
*
!* ------------------------------------------------------------ *
!* Reference: "Numerical Recipes by W.H. Press, B. P. Flannery, *
!*
S.A. Teukolsky and W.T. Vetterling, Cambridge
*
!*
University Press, 1986".
*
!*
*
!*
F90 Release 1.0 By J-P Moreau, Paris
*
!*
(www.jpmoreau.fr)
*
!****************************************************************
PROGRAM TEST_SIMPLEX
implicit none
integer I,ICASE,J,M,N,M1,M2,M3
integer, parameter :: MMAX=25, NMAX=25
REAL A(MMAX,NMAX)
INTEGER IPOSV(MMAX), IZROV(NMAX)
REAL R
print *,' '
write(*,10,advance='no');
write(*,20,advance='no');
write(*,30,advance='no');
write(*,40,advance='no');
M=M1+M2+M3
read
read
read
read
*,
*,
*,
*,
N
M1
M2
M3
A=0.
print *,'Input Economic Function:'
do i=2,N+1
write(*,50,advance='no') i-1; read *,A(1,i)
end do
write(*,51,advance='no'); read *,A(1,1)
!input constraints
do i=1, M
write(*,60) i
do j=2,N+1
write(*,50,advance='no') j-1; read *, R
A(i+1,j) = -R
end do
write(*,51,advance='no'); read *,A(i+1,1)
end do
print *,' '
print *,' Input Table:'
write(*,100) ((A(I,J),J=1,N+1),I=1,M+1)
call simplx(A,M,N,MMAX,NMAX,M1,M2,M3,ICASE,IZROV,IPOSV)
print *,' '
print *,' Maximum of E.F. = ', A(1,1)
do I=1, N
do J=1, M
if (IPOSV(J).eq.I) then
write(*,110) I, A(J+1, 1)
goto 3
end if
end do
write(*,110) I, 0.0
3 end do
print *,' '
10
20
30
40
50
51
60
format('
format('
format('
format('
format('
format('
format('
')
')
')
')
100 format(5F8.2)
110 format(' X',I2,' = ',F12.6)
END
SUBROUTINE simplx(a,m,n,mp,np,m1,m2,m3,icase,izrov,iposv)
implicit none
INTEGER icase,m,m1,m2,m3,mp,n,np,iposv(m),izrov(n)
REAL a(mp,np)
INTEGER, PARAMETER :: MMAX=100, NMAX=100
REAL, PARAMETER :: EPS=1.E-6
!--------------------------------------------------------------------------------------! USES simp1,simp2,simp3
!Simplex method for linear programming. Input parameters a, m, n, mp, np,
m1, m2, and m3,
!and output parameters a, icase, izrov, and iposv are described above.
!Parameters: MMAX is the maximum number of constraints expected; NMAX is
the maximum
!number of variables expected; EPS is the absolute precision, which
should be adjusted to
!the scale of your variables.
!--------------------------------------------------------------------------------------INTEGER i,ip,ir,is,k,kh,kp,m12,nl1,nl2,l1(NMAX),l2(MMAX),l3(MMAX)
REAL bmax,q1
if(m.ne.m1+m2+m3) pause ' Bad input constraint counts in simplx.'
nl1=n
do k=1,n
l1(k)=k
!Initialize index list of columns admissible for exchange.
izrov(k)=k !Initially make all variables right-hand.
end do
nl2=m
do i=1,m
if(a(i+1,1).lt.0.)pause ' Bad input tableau in simplx, Constants bi
must be nonnegative.'
l2(i)=i
iposv(i)=n+i
!-----------------------------------------------------------------------------------------------!Initial left-hand variables. m1 type constraints are represented by
having their slackv ariable
!initially left-hand, with no artificial variable. m2 type constraints
have their slack
goto 30
!Go to phase two.
end if
call simp2(a,m,n,mp,np,l2,nl2,ip,kp,q1) !Locate a pivot element (phase
one).
if(ip.eq.0)then
!Maximum of auxiliary objective function
is
icase=-1
!unbounded, so no feasible solution
exists.
return
end if
1 call simp3(a,mp,np,m+1,n,ip,kp)
!Exchange a left- and a right-hand variable (phase one), then update
lists.
if(iposv(ip).ge.n+m1+m2+1)then
!Exchanged out an artificial variable
for an
!equality constraint. Make sure it stays
do k=1,nl1
!out by removing it from the l1 list.
if(l1(k).eq.kp) goto 2
end do
2 nl1=nl1-1
do is=k,nl1
l1(is)=l1(is+1)
end do
else
if(iposv(ip).lt.n+m1+1) goto 20
kh=iposv(ip)-m1-n
if(l3(kh).eq.0) goto 20
!Exchanged out an m2 type constraint.
l3(kh)=0
!If its the first time, correct the pivot
column
!or the minus sign and the implicit
end if
!artificial variable.
a(m+2,kp+1)=a(m+2,kp+1)+1.
do i=1,m+2
a(i,kp+1)=-a(i,kp+1)
end do
20 is=izrov(kp)
!Update lists of left- and right-hand
variables.
izrov(kp)=iposv(ip)
iposv(ip)=is
if (ir.ne.0) goto 10
!if still in phase one, go back to 10.
!End of phase one code for finding an initial feasible solution. Now, in
phase two, optimize it.
30 call simp1(a,mp,np,0,l1,nl1,0,kp,bmax) !Test the z-row for doneness.
if(bmax.le.EPS)then
!Done. Solution found. Return with the
good news.
icase=0
return
end if
call simp2(a,m,n,mp,np,l2,nl2,ip,kp,q1)
two).
if(ip.eq.0)then
and return.
icase=1
return
end if
call simp3(a,mp,np,m,n,ip,kp)
variable (phase two),
goto 20
variables and
END
if(i+1.gt.nl2) return
do i=i+1, nl2
ii=l2(i)
if(a(ii+1,kp+1).lt.-EPS)then
q=-a(ii+1,1)/a(ii+1,kp+1)
if(q.lt.q1)then
ip=ii
q1=q
else if (q.eq.q1) then !We have a degeneracy.
do k=1,n
qp=-a(ip+1,k+1)/a(ip+1,kp+1)
q0=-a(ii+1,k+1)/a(ii+1,kp+1)
if(q0.ne.qp)goto 6
end do
6
if(q0.lt.qp) ip=ii
end if
end if
end do
return
END
SUBROUTINE simp3(a,mp,np,i1,k1,ip,kp)
implicit none
INTEGER i1,ip,k1,kp,mp,np
REAL a(mp,np)
!Matrix operations to exchange a left-hand and right-hand variable (see
text).
INTEGER ii,kk
REAL piv
piv=1./a(ip+1,kp+1)
if (i1.ge.0) then
do ii=1,i1+1
if(ii-1.ne.ip)then
a(ii,kp+1)=a(ii,kp+1)*piv
do kk=1,k1+1
if(kk-1.ne.kp)then
a(ii,kk)=a(ii,kk)-a(ip+1,kk)*a(ii,kp+1)
end if
end do
end if
end do
end if
do kk=1,k1+1
if(kk-1.ne.kp) a(ip+1,kk)=-a(ip+1,kk)*piv
end do
a(ip+1,kp+1)=piv
return
END
!end of file tsimplex.f90