glpini02.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /* glpini02.c */
  2. /***********************************************************************
  3. * This code is part of GLPK (GNU Linear Programming Kit).
  4. *
  5. * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  6. * 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
  7. * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
  8. * E-mail: <mao@gnu.org>.
  9. *
  10. * GLPK is free software: you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * GLPK is distributed in the hope that it will be useful, but WITHOUT
  16. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  18. * License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************/
  23. #include "glpapi.h"
  24. struct var
  25. { /* structural variable */
  26. int j;
  27. /* ordinal number */
  28. double q;
  29. /* penalty value */
  30. };
  31. static int fcmp(const void *ptr1, const void *ptr2)
  32. { /* this routine is passed to the qsort() function */
  33. struct var *col1 = (void *)ptr1, *col2 = (void *)ptr2;
  34. if (col1->q < col2->q) return -1;
  35. if (col1->q > col2->q) return +1;
  36. return 0;
  37. }
  38. static int get_column(glp_prob *lp, int j, int ind[], double val[])
  39. { /* Bixby's algorithm assumes that the constraint matrix is scaled
  40. such that the maximum absolute value in every non-zero row and
  41. column is 1 */
  42. int k, len;
  43. double big;
  44. len = glp_get_mat_col(lp, j, ind, val);
  45. big = 0.0;
  46. for (k = 1; k <= len; k++)
  47. if (big < fabs(val[k])) big = fabs(val[k]);
  48. if (big == 0.0) big = 1.0;
  49. for (k = 1; k <= len; k++) val[k] /= big;
  50. return len;
  51. }
  52. static void cpx_basis(glp_prob *lp)
  53. { /* main routine */
  54. struct var *C, *C2, *C3, *C4;
  55. int m, n, i, j, jk, k, l, ll, t, n2, n3, n4, type, len, *I, *r,
  56. *ind;
  57. double alpha, gamma, cmax, temp, *v, *val;
  58. xprintf("Constructing initial basis...\n");
  59. /* determine the number of rows and columns */
  60. m = glp_get_num_rows(lp);
  61. n = glp_get_num_cols(lp);
  62. /* allocate working arrays */
  63. C = xcalloc(1+n, sizeof(struct var));
  64. I = xcalloc(1+m, sizeof(int));
  65. r = xcalloc(1+m, sizeof(int));
  66. v = xcalloc(1+m, sizeof(double));
  67. ind = xcalloc(1+m, sizeof(int));
  68. val = xcalloc(1+m, sizeof(double));
  69. /* make all auxiliary variables non-basic */
  70. for (i = 1; i <= m; i++)
  71. { if (glp_get_row_type(lp, i) != GLP_DB)
  72. glp_set_row_stat(lp, i, GLP_NS);
  73. else if (fabs(glp_get_row_lb(lp, i)) <=
  74. fabs(glp_get_row_ub(lp, i)))
  75. glp_set_row_stat(lp, i, GLP_NL);
  76. else
  77. glp_set_row_stat(lp, i, GLP_NU);
  78. }
  79. /* make all structural variables non-basic */
  80. for (j = 1; j <= n; j++)
  81. { if (glp_get_col_type(lp, j) != GLP_DB)
  82. glp_set_col_stat(lp, j, GLP_NS);
  83. else if (fabs(glp_get_col_lb(lp, j)) <=
  84. fabs(glp_get_col_ub(lp, j)))
  85. glp_set_col_stat(lp, j, GLP_NL);
  86. else
  87. glp_set_col_stat(lp, j, GLP_NU);
  88. }
  89. /* C2 is a set of free structural variables */
  90. n2 = 0, C2 = C + 0;
  91. for (j = 1; j <= n; j++)
  92. { type = glp_get_col_type(lp, j);
  93. if (type == GLP_FR)
  94. { n2++;
  95. C2[n2].j = j;
  96. C2[n2].q = 0.0;
  97. }
  98. }
  99. /* C3 is a set of structural variables having excatly one (lower
  100. or upper) bound */
  101. n3 = 0, C3 = C2 + n2;
  102. for (j = 1; j <= n; j++)
  103. { type = glp_get_col_type(lp, j);
  104. if (type == GLP_LO)
  105. { n3++;
  106. C3[n3].j = j;
  107. C3[n3].q = + glp_get_col_lb(lp, j);
  108. }
  109. else if (type == GLP_UP)
  110. { n3++;
  111. C3[n3].j = j;
  112. C3[n3].q = - glp_get_col_ub(lp, j);
  113. }
  114. }
  115. /* C4 is a set of structural variables having both (lower and
  116. upper) bounds */
  117. n4 = 0, C4 = C3 + n3;
  118. for (j = 1; j <= n; j++)
  119. { type = glp_get_col_type(lp, j);
  120. if (type == GLP_DB)
  121. { n4++;
  122. C4[n4].j = j;
  123. C4[n4].q = glp_get_col_lb(lp, j) - glp_get_col_ub(lp, j);
  124. }
  125. }
  126. /* compute gamma = max{|c[j]|: 1 <= j <= n} */
  127. gamma = 0.0;
  128. for (j = 1; j <= n; j++)
  129. { temp = fabs(glp_get_obj_coef(lp, j));
  130. if (gamma < temp) gamma = temp;
  131. }
  132. /* compute cmax */
  133. cmax = (gamma == 0.0 ? 1.0 : 1000.0 * gamma);
  134. /* compute final penalty for all structural variables within sets
  135. C2, C3, and C4 */
  136. switch (glp_get_obj_dir(lp))
  137. { case GLP_MIN: temp = +1.0; break;
  138. case GLP_MAX: temp = -1.0; break;
  139. default: xassert(lp != lp);
  140. }
  141. for (k = 1; k <= n2+n3+n4; k++)
  142. { j = C[k].j;
  143. C[k].q += (temp * glp_get_obj_coef(lp, j)) / cmax;
  144. }
  145. /* sort structural variables within C2, C3, and C4 in ascending
  146. order of penalty value */
  147. qsort(C2+1, n2, sizeof(struct var), fcmp);
  148. for (k = 1; k < n2; k++) xassert(C2[k].q <= C2[k+1].q);
  149. qsort(C3+1, n3, sizeof(struct var), fcmp);
  150. for (k = 1; k < n3; k++) xassert(C3[k].q <= C3[k+1].q);
  151. qsort(C4+1, n4, sizeof(struct var), fcmp);
  152. for (k = 1; k < n4; k++) xassert(C4[k].q <= C4[k+1].q);
  153. /*** STEP 1 ***/
  154. for (i = 1; i <= m; i++)
  155. { type = glp_get_row_type(lp, i);
  156. if (type != GLP_FX)
  157. { /* row i is either free or inequality constraint */
  158. glp_set_row_stat(lp, i, GLP_BS);
  159. I[i] = 1;
  160. r[i] = 1;
  161. }
  162. else
  163. { /* row i is equality constraint */
  164. I[i] = 0;
  165. r[i] = 0;
  166. }
  167. v[i] = +DBL_MAX;
  168. }
  169. /*** STEP 2 ***/
  170. for (k = 1; k <= n2+n3+n4; k++)
  171. { jk = C[k].j;
  172. len = get_column(lp, jk, ind, val);
  173. /* let alpha = max{|A[l,jk]|: r[l] = 0} and let l' be such
  174. that alpha = |A[l',jk]| */
  175. alpha = 0.0, ll = 0;
  176. for (t = 1; t <= len; t++)
  177. { l = ind[t];
  178. if (r[l] == 0 && alpha < fabs(val[t]))
  179. alpha = fabs(val[t]), ll = l;
  180. }
  181. if (alpha >= 0.99)
  182. { /* B := B union {jk} */
  183. glp_set_col_stat(lp, jk, GLP_BS);
  184. I[ll] = 1;
  185. v[ll] = alpha;
  186. /* r[l] := r[l] + 1 for all l such that |A[l,jk]| != 0 */
  187. for (t = 1; t <= len; t++)
  188. { l = ind[t];
  189. if (val[t] != 0.0) r[l]++;
  190. }
  191. /* continue to the next k */
  192. continue;
  193. }
  194. /* if |A[l,jk]| > 0.01 * v[l] for some l, continue to the
  195. next k */
  196. for (t = 1; t <= len; t++)
  197. { l = ind[t];
  198. if (fabs(val[t]) > 0.01 * v[l]) break;
  199. }
  200. if (t <= len) continue;
  201. /* otherwise, let alpha = max{|A[l,jk]|: I[l] = 0} and let l'
  202. be such that alpha = |A[l',jk]| */
  203. alpha = 0.0, ll = 0;
  204. for (t = 1; t <= len; t++)
  205. { l = ind[t];
  206. if (I[l] == 0 && alpha < fabs(val[t]))
  207. alpha = fabs(val[t]), ll = l;
  208. }
  209. /* if alpha = 0, continue to the next k */
  210. if (alpha == 0.0) continue;
  211. /* B := B union {jk} */
  212. glp_set_col_stat(lp, jk, GLP_BS);
  213. I[ll] = 1;
  214. v[ll] = alpha;
  215. /* r[l] := r[l] + 1 for all l such that |A[l,jk]| != 0 */
  216. for (t = 1; t <= len; t++)
  217. { l = ind[t];
  218. if (val[t] != 0.0) r[l]++;
  219. }
  220. }
  221. /*** STEP 3 ***/
  222. /* add an artificial variable (auxiliary variable for equality
  223. constraint) to cover each remaining uncovered row */
  224. for (i = 1; i <= m; i++)
  225. if (I[i] == 0) glp_set_row_stat(lp, i, GLP_BS);
  226. /* free working arrays */
  227. xfree(C);
  228. xfree(I);
  229. xfree(r);
  230. xfree(v);
  231. xfree(ind);
  232. xfree(val);
  233. return;
  234. }
  235. /***********************************************************************
  236. * NAME
  237. *
  238. * glp_cpx_basis - construct Bixby's initial LP basis
  239. *
  240. * SYNOPSIS
  241. *
  242. * void glp_cpx_basis(glp_prob *lp);
  243. *
  244. * DESCRIPTION
  245. *
  246. * The routine glp_cpx_basis constructs an advanced initial basis for
  247. * the specified problem object.
  248. *
  249. * The routine is based on Bixby's algorithm described in the paper:
  250. *
  251. * Robert E. Bixby. Implementing the Simplex Method: The Initial Basis.
  252. * ORSA Journal on Computing, Vol. 4, No. 3, 1992, pp. 267-84. */
  253. void glp_cpx_basis(glp_prob *lp)
  254. { if (lp->m == 0 || lp->n == 0)
  255. glp_std_basis(lp);
  256. else
  257. cpx_basis(lp);
  258. return;
  259. }
  260. /* eof */