~?!i&32768 ~o=295 ~$>end_of_copyright ~/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ~/Copyright (C) Heinz Spiess, CH-2558 Aegerten, 1997. All rights reserved. ~/ ~/The right to use this macro is granted to all EMME/2 users, provided the ~/following conditions are met: ~/ 1) The macro cannot be sold for a fee (but it can be used and distributed ~/ without charge within consulting projects). ~/ 2) The user is aware that this macro is not a part of the EMME/2 software ~/ licence and there is no explicit or implied warranty or support ~/ provided with this macro. ~/ 3) The comments in this macros must not be removed and any additions or ~/ modification must be appropriately identified as such and give at least ~/ date, name and the reason of the modification. ~/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ~:end_of_copyright ~/========================================================================= ~/ BALZ3X3 1.0 - Simultaneous 2-dim balancing of a 3x3 matrix for each zone ~/ (Heinz Spiess, EMME/2 Support Center, CH-2558 Aegerten - 97-12-09) ~/ ~/ This macro performs for each selected zone a 2-dimensional balancing ~/ of a small 3x3 matrix to solve the following equations for the ~/ dual multiplier values ai and bi which satisfy: ~/ ~/ 1) Tij = ai*bj*Cij 2) Sum Tij = Ai 3) Sum Tij = Bj ~/ j i ~/ ~/ Matrix to be balanced Row Total Row Mult. ~/ +---------+---------+---------+ +---------+ +---------+ ~/ | "C11" | "C12" | "C13" | | "A1" | | "a1" | ~/ |---------|---------|---------| |---------| |---------| ~/ | "C21" | "C22" | "C23" | | "A2" | | "a2" | ~/ |---------|---------|---------| |---------| |---------| ~/ | "C31" | "C32" | "C33" | | "A3" | | "a3" | ~/ +---------+---------+---------+ +---------+ +---------+ ~/ ~/ +---------+---------+---------+ ~/ | "B1" | "B2" | "B3" | Column Total ~/ +---------+---------+---------+ ~/ +---------+---------+---------+ ~/ | "b1" | "b2" | "b3" | Column Multipliers ~/ |---------|---------|---------| ~/ ~/ In order for the model to be feasible, the total productions (A1+A2+A3) ~/ must be equal to the total attraction (B1+B2+B3) for each zone. ~/ Also note that zeros in the Cij values may in certain cases lead to ~/ infeasibilities. ~/ ~/ For each zone the corresponding values of Ai, Bj and Cij are stored in ~/ 15 origin matrices named accordingly (e.g. "A1", "C33", ...). The ~/ resulting dual multipliers for each zone are also stored in 6 origin ~/ vectors using the names "a1", "a2", ... "b3". ~/ ~/ This macro is not mainly intended to be used as is, rather it can ~/ serve as a template to implement similar tasks in a more application ~/ specific way. ~/ ~/ The following items may have to be customized for a particular ~/ application: ~/ - matrix names (substitute the abstract matrix names by locical names) ~/ - constraint matrix and submatrix (default: none) ~/ ~/ Calling sequence: ~/ ~ ~/ where: maximum number of iterations ~/ maximum admissible total constraint violation ~/ ~/========================================================================== ~x=%0% ~?x<1 ~$>end_of_macro 3.21 ~t1=||n|~?q=2|2 / change constraint matrix and submatrix here - if needed ~x=0 / iteration counter ~/ iteration 0: initialize row multipliers to 1 ~+|1|y|"a1"|y||a1 (iter %x%)|n|1|%t1% ~+|1|y|"a2"|y||a2 (iter %x%)|n|1|%t1% ~+|1|y|"a3"|y||a3 (iter %x%)|n|1|%t1% ~+|1|y|"b1"|y||b1 (iter %x%)|n|1|%t1% ~+|1|y|"b2"|y||b2 (iter %x%)|n|1|%t1% ~+|1|y|"b3"|y||b3 (iter %x%)|n|1|%t1% ~:next_iteration ~x+1 ~/ iteration %x%: ~g2=0 ~+|1|y|"b1"|y||b1 (iter %x%)|n "B1"/(put("a1"*"C11"+"a2"*"C21"+"a3"*"C31")+(get(1).eq.0)) +0*put(abs("B1"-"b1"*get(1))+get(puti(2))) ~+|%t1% ~g3=0 ~+|1|y|"b2"|y||b2 (iter %x%)|n "B2"/(put("a1"*"C12"+"a2"*"C22"+"a3"*"C32")+(get(1).eq.0)) +0*put(abs("B2"-"b2"*get(1))+get(puti(3))) ~+|%t1% ~g4=0 ~+|1|y|"b3"|y||b2 (iter %x%)|n "B3"/(put("a1"*"C13"+"a2"*"C23"+"a3"*"C33")+(get(1).eq.0)) +0*put(abs("B3"-"b3"*get(1))+get(puti(4))) ~+|%t1% ~/ column constraint violation: %g2_10% %g3_10% %g4_10% ~g5=0 ~:~+|1|y|"a1"|y||a1 (iter %x%)|n ~:"A1"/(put("b1"*"C11"+"b2"*"C12"+"b3"*"C13")+(get(1).eq.0)) ~:+0*put(abs("A1"-"a1"*get(1))+get(puti(5))) ~:~+|%t1% ~g6=0 ~+|1|y|"a2"|y||a2 (iter %x%)|n "A2"/(put("b1"*"C21"+"b2"*"C22"+"b3"*"C23")+(get(1).eq.0)) +0*put(abs("A2"-"a2"*get(1))+get(puti(6))) ~+|%t1% ~g7=0 ~+|1|y|"a3"|y||a3 (iter %x%)|n "A3"/(put("b1"*"C31"+"b2"*"C32"+"b3"*"C33")+(get(1).eq.0)) +0*put(abs("A3"-"a3"*get(1))+get(puti(7))) ~+|%t1% ~/ row constraint violation: %g6_10% %g7_10% ~g5+%g6% ~g5+%g7% ~?g5<%2% 1 / test max total constraint violation ~$done ~?x<%1% 100 / test maximum iterations ~$next_iteration ~:done ~/========================================================================= ~/ ~/ BALZ3X3 terminated normally after %x% iterations with a total remaining ~/ constraint violation of %g5%. The balanced 3x3 matrices can now be ~/ obtained by the following computations: ~/ ~/ Tij= ai * bj * Cij for i=1,2,3 andj =1,2,3 ~/ ~/========================================================================= q ~:end_of_macro ~o=6