lin.fun 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #import std
  2. #import nat
  3. #import flo
  4. #comment -[
  5. This module contains functions and data structures for solving linear
  6. programming problems by way of a more convenient interface than direct
  7. invocation of the virtual machine's library functions, because it
  8. allows symbolic names for variables, positive and negative solutions,
  9. and costs proportional to magnitudes. A few matrix operations are also
  10. included. Replacement functions implemented in virtual code are
  11. provided in case the virtual machine doesn't have the required
  12. libraries (lapack, umf, and pcx or glpk) but performance and memory
  13. efficiency will suffer considerably.
  14. Copyright (C) 2007-2010 Dennis Furey]-
  15. #library+
  16. #optimize+
  17. ------------------------------------------------ data structures -----------------------------------------------------------
  18. linear_system ::
  19. lower_bounds %geAS # the minimum allowed value for each variable in the solution
  20. upper_bounds %geAS # the maximum allowed value for each variable in the solution
  21. costs %geAS # the proportional contribution of each variable to the objective function to be minimized
  22. taxes %geAS # the proportional contribution of the magnitude of each variable to the objective function
  23. equations %egXSeXS # the equations to be satisfied in the form <(<(coefficient,name)..>,total)..>
  24. integers %gS # the variables constrained to integer values
  25. binaries %gS # the variables constrained to binary values
  26. derivations %egXSm # <name: <(coefficient,name)..>> original variables expressed in terms of standardized variables
  27. ------------------------------------------- general operations on matrices -------------------------------------------------
  28. mmult = iprod*rlD*rK7lD # matrix multiplication
  29. #library-
  30. upper_triangular = # takes a matrix and transforms it to upper triangular form by row reductions
  31. ~&a^& (~&aitB?\~&a ^rlhPlthS2rpCB/~&a ~&fattS2R)^J/~&f ~&a; (not fleq+ abs~~)-<&h; (fleq/eps+ abs+ ~&hh)&& -+
  32. :^/~&h ~&htPtD; * :/0.+ minus^*p/~&rt times*+ ~&rhPlD,
  33. :^\~&t ~&h; :/1.+ vid*+ ~&htD+-
  34. #library+
  35. msolve = # takes a square matrix and a vector to a vector using gauss jordan elimination with pivoting
  36. lapack.|dgesvx -+
  37. ~&i&& ~&xzS+ ~&a^& :^(~&ah,^p/~&athS ~&fattS2R)^J/~&f ~&a; :^/~&h ~&htD; * minus^*p/~&r times*+ ~&rhPlD,
  38. ~&plrNCTS; ~&iyxPzNCTSxPB+ upper_triangular+-
  39. minverse = ~&K7+ msolve^*D/~& ^DlSzyCK9\~& :/1.+ 0.!*+ ~&t
  40. sparso = # storage efficient solution of systems of linear equations in sparse matrix form
  41. %nWeXLeLXMk; umf.|di_a_trp msolve^\~&r ^DrlHS/iol+~&r ~&l; |=&ll; nleq-<&hll; * *+ -:0.!+ ~&lrPrXS
  42. ------------------------------------------- arbitrary precision versions ---------------------------------------------------
  43. mp_solve = # same as msolve but a lot slower and for mpfr (arbitrary precision) numbers
  44. -+
  45. ~&i&& ~&xzS+ ~&a^& :^(~&ah,^p/~&athS ~&fattS2R)^J/~&f ~&a; :^/~&h ~&htD; * mpfr..sub^*p/~&r mpfr..mul*rhPlD,
  46. ~&plrNCTS; ~&iyxPzNCTSxPB+ ~&a^& -+
  47. ~&aitB?\~&a ^rlhPlthS2rpCB/~&a ~&fattS2R,
  48. ^J/~&f ~&a; (not mpfr..lessequal_p+ mpfr..abs~~)-<&h; (mpfr..lessequal_p/1E-16+ mpfr..abs+ ~&hh)&& -+
  49. :^/~&h ~&htPtD; * :/0E0+ mpfr..sub^*p/~&rt mpfr..mul*rhPlD,
  50. :^\~&t ~&h; :/1E0+ mpfr..vid*+ ~&htD+-+-+-
  51. mp_sparso = # replacement function for sparso with mpfr numbers, but no advantage in storage efficiency
  52. %nWEXLELXMk; mp_solve^\~&r ^DrlHS/iol+~&r ~&l; |=&ll; nleq-<&hll; * *+ -:0E0!+ ~&lrPrXS
  53. ------------------------------------------------- linear programming functions ---------------------------------------------
  54. standard_form = # removes finite and negative bounds and unsigned costs from linear systems by variable substitutions
  55. -+
  56. linear_system$l[
  57. taxes: <>!,
  58. upper_bounds: <>!,
  59. lower_bounds: :0.^*js\~&rlnS --+ ~/&rlmrSPSL &l.equations.&lrSPSL,
  60. costs: -+
  61. ^A(~&hn,plus:-0.+ ~&mS)*+ |=&n+ ^T(
  62. ~&l; *= ||~&lNC ~&lmPrD; * ^A/~&rr times+~&lrlPX,
  63. ~&r; *= ||~&lNC ~&lmPrD; * ^A/~&rr times^/~&l abs+~&rl),
  64. %seAesXLXLWMk^H\~&l.(costs,taxes) ~*+ ^/~&+ ~&n;+ -:0!+ ~&rl+-,
  65. equations: (^\~&r ~&l~<{0.,-0.}*~+ ~&l)^*T\~&rr -+
  66. * %esXLeXMk+ ^\~&rr ~&lrlPDlrHS; %esXLMk+ *= ||~&lNC ~&llPrD; * ^\~&rr times+~&lrlPX,
  67. ^D\~&l.equations ^/~&+ ~&r;+ -:0!+ ~&rl+-,
  68. derivations: --+ ~/&l.derivations &rl],
  69. ^/~& -+
  70. %esXLmesXLeXLXMk+ ~&lSLPrSLPX+ * -?
  71. ~&rml;fleq/0.: ~&NiX+ ~&L+ <.
  72. ~&rml~=0.&& ^iNC\~&rml ^H/(:^/~&h+ ~&t;+ ~&l) <.~&/1.,~&/-1.+ --'_bloat'>+ ~&rn,
  73. ~&rmr~=inf&& ^iNC\~&rmr ^H/(:^/~&h+ ~&t;+ ~&l) <.~&/1.,~&/1.+ --'_headroom'>+ ~&rn>,
  74. ~&rmr;fleq\0.: ^/(^ANC/~&rn ^H/~&l ~&iNC/-1.+ --'_complement'+ ~&rn) ~&L+ <.
  75. ~&rmr~=0.&& ^iNC\negative+~&rmr ^H/~&l <.~&/1.,~&/-1.+ --'_bloat'>+ --'_complement'+ ~&rn,
  76. ~&rml~=ninf&& ^iNC\negative+~&rml ^H/~&l <.~&/1.,~&/1.+ --'_headroom'>+ --'_complement'+ ~&rn>,
  77. ^/(^ANC/~&rn ^H/~&l <.~&/1.+ --'_credit',~&/-1.+ --'_debit'>+ ~&rn) ~&L+ <.
  78. ~&rml~=ninf&& ^iNC\~&rml ^H/~&l <.~&/1.+ --'_credit',~&/-1.+ --'_debit',~&/-1.+ --'_bloat'>+ ~&rn,
  79. ~&rmr~=inf&& ^iNC\~&rmr ^H/~&l <.~&/1.+ --'_credit',~&/-1.+ --'_debit',~&/1.+ --'_headroom'>+ ~&rn>?-,
  80. %fOseWAXLMk^D((~&?\~&! *+ !; ^\~&; //+ ~&rrPlw->r &rr:= :/``+ ~&rr)+ ~&lrlPU; *~ -=/`_,~&rr)^(
  81. ~derivations.&nmrSPCSLs,
  82. ^H\~equations.&lrSPSLs ^/~&+ (*+ ^llPlrPrXA)^\-:inf!+~upper_bounds ^/~&+ -:ninf!+ ~lower_bounds)+-,
  83. upper_bounds:= ^Ts(~&DrlAS/1.+ ~binaries,^niK12/~upper_bounds ~binaries),
  84. lower_bounds:= ^Ts(~&DrlAS/0.+ ~binaries,^niK12/~lower_bounds ~binaries)+-
  85. solution = # takes a linear system to a result of type %em
  86. gint~&lnPrE^\~equations.&lSLrS standard_form; -+
  87. %emMk^T\~&r ~&m~<{0.,-0.}*~+ ^DrnPlrmPHAS\~&l %fMk+ plus:-0.++ *+ times^/~&l+ ~&r;+ -:0.!+ ~&r,
  88. %esXLmemXMk^/~&l.derivations %emMk^DlrlPHrrPAS/~&rrr %neXLMk+ mip_solver^(
  89. %nLWMk^H/~*@rrl ~&l.(binaries,integers),
  90. %eLnWeXLeLXXMk^(
  91. %eLMk+ (#:/0.+#) ~&rS+ %neXLMk+ (nleq-<&l)^DlrnPHrmPXS/~&rrl %emMk^T(~&r,gdif~&EbnPO)^\~&l.costs ~&A\*0.+ ~&rl,
  92. ^\%eLMk+~&l.equations.&rS %nWeXLMk+ ~&DSLlrlPXrrPXS+ num+ nleq-<&l*+ ~&DlrrPHrlPXSPS^D/~&rrl ~&l.equations.&lS)),
  93. _linear_system%sSfOWXXMk^/~& ~equations.&lSLrSs; ^/~& -:0!~~+ ~&rlXSiX+ num+-
  94. mip_solver = # takes an argument ((b,i),c,m,y) of type %nLWeLnWeXLeLXXX to a result of type %neXL
  95. ~&Y?l\lp_solver@r ~&ll?\lpsolve..iform@lrPrX ~&lr?\lpsolve..bform@llPrX lpsolve..biform
  96. lp_solver = # lower level interface, takes an argument (c,m,y) of type %eLnWeXLeLXX to a result of type %neXL
  97. lpsolve.|stdform glpk.|simplex glpk.|interior replacement_lp_solver
  98. replacement_lp_solver = # solves it the hard way without calling an external library function
  99. ^|(num,~&); -+
  100. %fnWeXLLneXLXXnLLXMk; @NiX ~&rr->lilB ^\~&rlrtPXP @lrlrhPXPX %neXLeXZfnWeXLLneXLXXnLXXCk -+
  101. ~&r?\~&l ~&l?\~&r %neXLeXZWMk; lesser fleq@br,
  102. ^/~&l (%fneXLXMk; ~&r&& ^/~&r plus:-0.+ times*DlrlPHrrPXS)^/~&rll -+
  103. eql+~&llPrX&& eql+~&lrlrPSs3rX&& %nLnWeXLXneXLXMk; -+
  104. %neXLMk+ -&~&r; ~&i&& all fleq/0.,~&p&-^|/~& sparso,
  105. %nLnWeXLeLXXMk^/~&ll ^\~&rrS ^H\~&lr @rlSPllPX *+ ^\~&r+ ~&l;+ ^|+ ~~ -$^/~& iol+-,
  106. (^/~&l ~&rlrPX; gint~&llPrll2E)^\~&rlrr ~&rrPrlrl3X; %nLnWeXLXMk^/~&l ~&L+ ~&rhlr3lw~|+-+-,
  107. ^(^/-:+~&l ^\num+~&rr |=&lr+ ~&rl,leql?rrPlX\<'bad linear program'>!% %nLLMk+ choices^/~&llS length+ ~&rr)+-