Newsgroups: comp.lang.apl
Path: watmath!watserv2.uwaterloo.ca!torn!spool.mu.edu!howland.reston.ans.net!zaphod.mps.ohio-state.edu!swrinde!elroy.jpl.nasa.gov!decwrl!csus.edu!sfsuvax1.sfsu.edu!vpcsc4
From: vpcsc4@sfsuvax1.sfsu.edu (Emmett McLean)
Subject: Re: Triadic Operators in J? (2 Simplex Algorithm J verbs)
Message-ID: <1993Apr13.035344.8102@csus.edu>
Sender: news@csus.edu
Organization: San Francisco State University
References: <1993Apr12.212007.6986@csi.uottawa.ca> <WEG.93Apr12172139@mace.cc.purdue.edu>
Date: Tue, 13 Apr 1993 03:53:44 GMT
Lines: 127

NB.  As for your question, you might make the cost function and
NB.  matrix one table, with the coefficients from the cost function
NB.  corresponding to row zero of the table.  
NB. 
NB.  0!:2 this file
NB.  
NB.  Except for a minor change in the final expression of simplex,
NB.  this is Gene McDonnell's rendition of the simplex algorithm - as 
NB.  I described it to him. I found it to be helpful when I was
NB.  first learning how to glue verbs together.

NB.  The "simplex" verb below gives the same result that your "smpx"
NB.  gives on your sample table a.  
NB. 
NB.  It uses indices rather than boolean vectors to do pivot selection. 
NB.  This keeps things scalar, removing the need for ''$ .  
NB. 
NB.  It uses an outer product (*/) to obtain the subtrahend table, which 
NB.  simplifies things notationally (compared to your *"0 1).  
NB. 
NB.  It uses verb power (^:) to obtain iteration, rather than your
NB.  explicit branching; using infinite power works fine on your table a.  
NB. 
NB.  You can examine the sequence of intermediate results by executing:
NB.     a
NB.     step a
NB.     step step a (or step ^:2 a)
NB.     etc.  
NB. 
 NB. select column index based on righthand variables 
 NB. (objective) in top row  
 xc=.(i. <./)@(}:@{. , 0:)                            
 NB. select factors1 column using column index      
 factors1=.xc {"1 ]                               
 NB. select row index based on factors1 
 xr=.>:@(i. <./@(0&< # ]))@(}.@({:"1 % factors1))                     
 NB. pivot element selected by row,column index pair 
 pivot=.<@(xr ; xc) { ]                              
 NB. adjust factors1 and replace pivot element 
 factors=.(,:'((<:%])@pivot y.) (xr y.) } (factors1 % pivot) y.') :''
 NB. perform one simplex step: subtract from argument 
 NB. the outerproduct of factors with selected row 
 step=.- (factors */ xr { ])
 NB. solve simplex problem by infinite powering of step;
 NB. if infeasible, return table of all zeros 
 NB. determine if any of the shadow costs are negative
 interationCondition =. _1&e.@*@}:@(0&{) 
 while =. ^:

 simplex=. step while interationCondition :: ($ $ 0:)
 
   a =.     _1 _2 _3 _5  0 0 0  0
   a =. a ,: 4  3  2  4  1 0 0 10
   a =. a ,  10 2  6  8  0 1 0 20 
   a =. a ,  20 1  5  5  0 0 1 30 

   step a

   simplex a

NB. 	From RLWBROWN@VM1.YorkU.CA Sat Aug  1 02:40 EDT 1992
NB. 	Date:         Sat, 01 Aug 92 02:36:53 EDT
NB. 	From: Richard Brown <RLWBROWN@VM1.YorkU.CA>
NB. 	Subject:      Re: I think this one's for you.
NB. 	To: "L.J. Dickey" <ljdickey@math>
NB. 	
NB. 	Dear Lee:
NB. 	I tried sending the following message directly to Emmett but
NB. 	it didn't get through.  Perhaps you would be willing to
NB. 	forward it to him.  Thanks.
NB. 	                              Richard
NB. 	------------------original message----------------------------
NB. 	Dear Emmett:
NB. 	
NB. 	In the following code, the verb pivot is like your verb
NB. 	iterate.  Then the verb smplx is defined using the power
NB. 	conjunction ^: .   Let w be a verb such that w(m) is either
NB. 	0 or 1.  Then v^:w m applies verb v to m while w(m) is 1.
NB. 	This is the 'while' conditional that your wanted.
NB. 	                   Your comments are welcome,
NB. 	                     Richard Brown
NB. 
NB. 	--------------cut here and read this script into J--------------------
	
	NB. Simplex Algorithm in J (version 4.1)
	NB. by Richard L.W. Brown, York University, North York, CANADA
	
	NB. Let T be the initial simplex tableau.
	NB. Assume this form of T: (see OR by H. Taha)
	NB. Top row of T is objective function, to be maximized, signs changed.
	NB. Top row has zeros for all basic variables.
	NB. Values of variables (RHS's of equations) are in right border of T.
	NB. Example:
	NB. maximize z=12x1 + 13x2 such that 4x1 + 5x2 <= 10 and 8x1 + 7x2 <= 16
	NB. and x1,x2>=0.
	]T=.3 5$ _12 _13 0 0 0    4 5 1 0 10     8 7 0 1 16
	
	NB. LM(vector)=Location of Minimum of vector
	NB. PC(T)=Pivot Column of tableau T
	NB. (T)PR(C)=row number of Pivot Row of T where C is pivot column
	NB. pivot(T)=new tableau after one pivot operation on T
	NB. morpiv(T)=1 if more pivots are needed, else 0
	
	LM=.i.<./
	PC=.{"1~LM&}:@{.
	PR=.'' : '(LM p#({:"1 x.)%y.){(p=.0<y.)#i.$y.'
	pivot=.'y.-(C-r=i.$C)*/R%r{C[R=.r{y.[r=.y.PR C=.PC y.' : ''
	morpiv=.'+./(0>{.y.)*.+./0<}.y.' : ''
	Rsimplex =.pivot^:morpiv
	
	Rsimplex T
	
	NB. Thus x1 is basic with value 0.83333, x2 is basic with value 1.33333
	NB. and z=27.333. (The slack variables x3 and x4 are nonbasic and hence 0.)
	
	NB. We can do the process manually step by step:
	T
	pivot T
	pivot^:2 T
	
	NB. The morpiv test is slighly better than the usual simplex method
	NB. because the usual test will only detect an unbounded problem if
	NB. the current pivot column is unbounded whereas morpiv is a
	NB. global test (i.e. ALL columns) for optimality or unboundedness.

    NB. Thanks to Eugene and Richard!!!
   <'Emmett'
