glpscl.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /* glpscl.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. /***********************************************************************
  25. * min_row_aij - determine minimal |a[i,j]| in i-th row
  26. *
  27. * This routine returns minimal magnitude of (non-zero) constraint
  28. * coefficients in i-th row of the constraint matrix.
  29. *
  30. * If the parameter scaled is zero, the original constraint matrix A is
  31. * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
  32. *
  33. * If i-th row of the matrix is empty, the routine returns 1. */
  34. static double min_row_aij(glp_prob *lp, int i, int scaled)
  35. { GLPAIJ *aij;
  36. double min_aij, temp;
  37. xassert(1 <= i && i <= lp->m);
  38. min_aij = 1.0;
  39. for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next)
  40. { temp = fabs(aij->val);
  41. if (scaled) temp *= (aij->row->rii * aij->col->sjj);
  42. if (aij->r_prev == NULL || min_aij > temp)
  43. min_aij = temp;
  44. }
  45. return min_aij;
  46. }
  47. /***********************************************************************
  48. * max_row_aij - determine maximal |a[i,j]| in i-th row
  49. *
  50. * This routine returns maximal magnitude of (non-zero) constraint
  51. * coefficients in i-th row of the constraint matrix.
  52. *
  53. * If the parameter scaled is zero, the original constraint matrix A is
  54. * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
  55. *
  56. * If i-th row of the matrix is empty, the routine returns 1. */
  57. static double max_row_aij(glp_prob *lp, int i, int scaled)
  58. { GLPAIJ *aij;
  59. double max_aij, temp;
  60. xassert(1 <= i && i <= lp->m);
  61. max_aij = 1.0;
  62. for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next)
  63. { temp = fabs(aij->val);
  64. if (scaled) temp *= (aij->row->rii * aij->col->sjj);
  65. if (aij->r_prev == NULL || max_aij < temp)
  66. max_aij = temp;
  67. }
  68. return max_aij;
  69. }
  70. /***********************************************************************
  71. * min_col_aij - determine minimal |a[i,j]| in j-th column
  72. *
  73. * This routine returns minimal magnitude of (non-zero) constraint
  74. * coefficients in j-th column of the constraint matrix.
  75. *
  76. * If the parameter scaled is zero, the original constraint matrix A is
  77. * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
  78. *
  79. * If j-th column of the matrix is empty, the routine returns 1. */
  80. static double min_col_aij(glp_prob *lp, int j, int scaled)
  81. { GLPAIJ *aij;
  82. double min_aij, temp;
  83. xassert(1 <= j && j <= lp->n);
  84. min_aij = 1.0;
  85. for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next)
  86. { temp = fabs(aij->val);
  87. if (scaled) temp *= (aij->row->rii * aij->col->sjj);
  88. if (aij->c_prev == NULL || min_aij > temp)
  89. min_aij = temp;
  90. }
  91. return min_aij;
  92. }
  93. /***********************************************************************
  94. * max_col_aij - determine maximal |a[i,j]| in j-th column
  95. *
  96. * This routine returns maximal magnitude of (non-zero) constraint
  97. * coefficients in j-th column of the constraint matrix.
  98. *
  99. * If the parameter scaled is zero, the original constraint matrix A is
  100. * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
  101. *
  102. * If j-th column of the matrix is empty, the routine returns 1. */
  103. static double max_col_aij(glp_prob *lp, int j, int scaled)
  104. { GLPAIJ *aij;
  105. double max_aij, temp;
  106. xassert(1 <= j && j <= lp->n);
  107. max_aij = 1.0;
  108. for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next)
  109. { temp = fabs(aij->val);
  110. if (scaled) temp *= (aij->row->rii * aij->col->sjj);
  111. if (aij->c_prev == NULL || max_aij < temp)
  112. max_aij = temp;
  113. }
  114. return max_aij;
  115. }
  116. /***********************************************************************
  117. * min_mat_aij - determine minimal |a[i,j]| in constraint matrix
  118. *
  119. * This routine returns minimal magnitude of (non-zero) constraint
  120. * coefficients in the constraint matrix.
  121. *
  122. * If the parameter scaled is zero, the original constraint matrix A is
  123. * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
  124. *
  125. * If the matrix is empty, the routine returns 1. */
  126. static double min_mat_aij(glp_prob *lp, int scaled)
  127. { int i;
  128. double min_aij, temp;
  129. min_aij = 1.0;
  130. for (i = 1; i <= lp->m; i++)
  131. { temp = min_row_aij(lp, i, scaled);
  132. if (i == 1 || min_aij > temp)
  133. min_aij = temp;
  134. }
  135. return min_aij;
  136. }
  137. /***********************************************************************
  138. * max_mat_aij - determine maximal |a[i,j]| in constraint matrix
  139. *
  140. * This routine returns maximal magnitude of (non-zero) constraint
  141. * coefficients in the constraint matrix.
  142. *
  143. * If the parameter scaled is zero, the original constraint matrix A is
  144. * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
  145. *
  146. * If the matrix is empty, the routine returns 1. */
  147. static double max_mat_aij(glp_prob *lp, int scaled)
  148. { int i;
  149. double max_aij, temp;
  150. max_aij = 1.0;
  151. for (i = 1; i <= lp->m; i++)
  152. { temp = max_row_aij(lp, i, scaled);
  153. if (i == 1 || max_aij < temp)
  154. max_aij = temp;
  155. }
  156. return max_aij;
  157. }
  158. /***********************************************************************
  159. * eq_scaling - perform equilibration scaling
  160. *
  161. * This routine performs equilibration scaling of rows and columns of
  162. * the constraint matrix.
  163. *
  164. * If the parameter flag is zero, the routine scales rows at first and
  165. * then columns. Otherwise, the routine scales columns and then rows.
  166. *
  167. * Rows are scaled as follows:
  168. *
  169. * n
  170. * a'[i,j] = a[i,j] / max |a[i,j]|, i = 1,...,m.
  171. * j=1
  172. *
  173. * This makes the infinity (maximum) norm of each row of the matrix
  174. * equal to 1.
  175. *
  176. * Columns are scaled as follows:
  177. *
  178. * n
  179. * a'[i,j] = a[i,j] / max |a[i,j]|, j = 1,...,n.
  180. * i=1
  181. *
  182. * This makes the infinity (maximum) norm of each column of the matrix
  183. * equal to 1. */
  184. static void eq_scaling(glp_prob *lp, int flag)
  185. { int i, j, pass;
  186. double temp;
  187. xassert(flag == 0 || flag == 1);
  188. for (pass = 0; pass <= 1; pass++)
  189. { if (pass == flag)
  190. { /* scale rows */
  191. for (i = 1; i <= lp->m; i++)
  192. { temp = max_row_aij(lp, i, 1);
  193. glp_set_rii(lp, i, glp_get_rii(lp, i) / temp);
  194. }
  195. }
  196. else
  197. { /* scale columns */
  198. for (j = 1; j <= lp->n; j++)
  199. { temp = max_col_aij(lp, j, 1);
  200. glp_set_sjj(lp, j, glp_get_sjj(lp, j) / temp);
  201. }
  202. }
  203. }
  204. return;
  205. }
  206. /***********************************************************************
  207. * gm_scaling - perform geometric mean scaling
  208. *
  209. * This routine performs geometric mean scaling of rows and columns of
  210. * the constraint matrix.
  211. *
  212. * If the parameter flag is zero, the routine scales rows at first and
  213. * then columns. Otherwise, the routine scales columns and then rows.
  214. *
  215. * Rows are scaled as follows:
  216. *
  217. * a'[i,j] = a[i,j] / sqrt(alfa[i] * beta[i]), i = 1,...,m,
  218. *
  219. * where:
  220. * n n
  221. * alfa[i] = min |a[i,j]|, beta[i] = max |a[i,j]|.
  222. * j=1 j=1
  223. *
  224. * This allows decreasing the ratio beta[i] / alfa[i] for each row of
  225. * the matrix.
  226. *
  227. * Columns are scaled as follows:
  228. *
  229. * a'[i,j] = a[i,j] / sqrt(alfa[j] * beta[j]), j = 1,...,n,
  230. *
  231. * where:
  232. * m m
  233. * alfa[j] = min |a[i,j]|, beta[j] = max |a[i,j]|.
  234. * i=1 i=1
  235. *
  236. * This allows decreasing the ratio beta[j] / alfa[j] for each column
  237. * of the matrix. */
  238. static void gm_scaling(glp_prob *lp, int flag)
  239. { int i, j, pass;
  240. double temp;
  241. xassert(flag == 0 || flag == 1);
  242. for (pass = 0; pass <= 1; pass++)
  243. { if (pass == flag)
  244. { /* scale rows */
  245. for (i = 1; i <= lp->m; i++)
  246. { temp = min_row_aij(lp, i, 1) * max_row_aij(lp, i, 1);
  247. glp_set_rii(lp, i, glp_get_rii(lp, i) / sqrt(temp));
  248. }
  249. }
  250. else
  251. { /* scale columns */
  252. for (j = 1; j <= lp->n; j++)
  253. { temp = min_col_aij(lp, j, 1) * max_col_aij(lp, j, 1);
  254. glp_set_sjj(lp, j, glp_get_sjj(lp, j) / sqrt(temp));
  255. }
  256. }
  257. }
  258. return;
  259. }
  260. /***********************************************************************
  261. * max_row_ratio - determine worst scaling "quality" for rows
  262. *
  263. * This routine returns the worst scaling "quality" for rows of the
  264. * currently scaled constraint matrix:
  265. *
  266. * m
  267. * ratio = max ratio[i],
  268. * i=1
  269. * where:
  270. * n n
  271. * ratio[i] = max |a[i,j]| / min |a[i,j]|, 1 <= i <= m,
  272. * j=1 j=1
  273. *
  274. * is the scaling "quality" of i-th row. */
  275. static double max_row_ratio(glp_prob *lp)
  276. { int i;
  277. double ratio, temp;
  278. ratio = 1.0;
  279. for (i = 1; i <= lp->m; i++)
  280. { temp = max_row_aij(lp, i, 1) / min_row_aij(lp, i, 1);
  281. if (i == 1 || ratio < temp) ratio = temp;
  282. }
  283. return ratio;
  284. }
  285. /***********************************************************************
  286. * max_col_ratio - determine worst scaling "quality" for columns
  287. *
  288. * This routine returns the worst scaling "quality" for columns of the
  289. * currently scaled constraint matrix:
  290. *
  291. * n
  292. * ratio = max ratio[j],
  293. * j=1
  294. * where:
  295. * m m
  296. * ratio[j] = max |a[i,j]| / min |a[i,j]|, 1 <= j <= n,
  297. * i=1 i=1
  298. *
  299. * is the scaling "quality" of j-th column. */
  300. static double max_col_ratio(glp_prob *lp)
  301. { int j;
  302. double ratio, temp;
  303. ratio = 1.0;
  304. for (j = 1; j <= lp->n; j++)
  305. { temp = max_col_aij(lp, j, 1) / min_col_aij(lp, j, 1);
  306. if (j == 1 || ratio < temp) ratio = temp;
  307. }
  308. return ratio;
  309. }
  310. /***********************************************************************
  311. * gm_iterate - perform iterative geometric mean scaling
  312. *
  313. * This routine performs iterative geometric mean scaling of rows and
  314. * columns of the constraint matrix.
  315. *
  316. * The parameter it_max specifies the maximal number of iterations.
  317. * Recommended value of it_max is 15.
  318. *
  319. * The parameter tau specifies a minimal improvement of the scaling
  320. * "quality" on each iteration, 0 < tau < 1. It means than the scaling
  321. * process continues while the following condition is satisfied:
  322. *
  323. * ratio[k] <= tau * ratio[k-1],
  324. *
  325. * where ratio = max |a[i,j]| / min |a[i,j]| is the scaling "quality"
  326. * to be minimized, k is the iteration number. Recommended value of tau
  327. * is 0.90. */
  328. static void gm_iterate(glp_prob *lp, int it_max, double tau)
  329. { int k, flag;
  330. double ratio = 0.0, r_old;
  331. /* if the scaling "quality" for rows is better than for columns,
  332. the rows are scaled first; otherwise, the columns are scaled
  333. first */
  334. flag = (max_row_ratio(lp) > max_col_ratio(lp));
  335. for (k = 1; k <= it_max; k++)
  336. { /* save the scaling "quality" from previous iteration */
  337. r_old = ratio;
  338. /* determine the current scaling "quality" */
  339. ratio = max_mat_aij(lp, 1) / min_mat_aij(lp, 1);
  340. #if 0
  341. xprintf("k = %d; ratio = %g\n", k, ratio);
  342. #endif
  343. /* if improvement is not enough, terminate scaling */
  344. if (k > 1 && ratio > tau * r_old) break;
  345. /* otherwise, perform another iteration */
  346. gm_scaling(lp, flag);
  347. }
  348. return;
  349. }
  350. /***********************************************************************
  351. * NAME
  352. *
  353. * scale_prob - scale problem data
  354. *
  355. * SYNOPSIS
  356. *
  357. * #include "glpscl.h"
  358. * void scale_prob(glp_prob *lp, int flags);
  359. *
  360. * DESCRIPTION
  361. *
  362. * The routine scale_prob performs automatic scaling of problem data
  363. * for the specified problem object. */
  364. static void scale_prob(glp_prob *lp, int flags)
  365. { static const char *fmt =
  366. "%s: min|aij| = %10.3e max|aij| = %10.3e ratio = %10.3e\n";
  367. double min_aij, max_aij, ratio;
  368. xprintf("Scaling...\n");
  369. /* cancel the current scaling effect */
  370. glp_unscale_prob(lp);
  371. /* report original scaling "quality" */
  372. min_aij = min_mat_aij(lp, 1);
  373. max_aij = max_mat_aij(lp, 1);
  374. ratio = max_aij / min_aij;
  375. xprintf(fmt, " A", min_aij, max_aij, ratio);
  376. /* check if the problem is well scaled */
  377. if (min_aij >= 0.10 && max_aij <= 10.0)
  378. { xprintf("Problem data seem to be well scaled\n");
  379. /* skip scaling, if required */
  380. if (flags & GLP_SF_SKIP) goto done;
  381. }
  382. /* perform iterative geometric mean scaling, if required */
  383. if (flags & GLP_SF_GM)
  384. { gm_iterate(lp, 15, 0.90);
  385. min_aij = min_mat_aij(lp, 1);
  386. max_aij = max_mat_aij(lp, 1);
  387. ratio = max_aij / min_aij;
  388. xprintf(fmt, "GM", min_aij, max_aij, ratio);
  389. }
  390. /* perform equilibration scaling, if required */
  391. if (flags & GLP_SF_EQ)
  392. { eq_scaling(lp, max_row_ratio(lp) > max_col_ratio(lp));
  393. min_aij = min_mat_aij(lp, 1);
  394. max_aij = max_mat_aij(lp, 1);
  395. ratio = max_aij / min_aij;
  396. xprintf(fmt, "EQ", min_aij, max_aij, ratio);
  397. }
  398. /* round scale factors to nearest power of two, if required */
  399. if (flags & GLP_SF_2N)
  400. { int i, j;
  401. for (i = 1; i <= lp->m; i++)
  402. glp_set_rii(lp, i, round2n(glp_get_rii(lp, i)));
  403. for (j = 1; j <= lp->n; j++)
  404. glp_set_sjj(lp, j, round2n(glp_get_sjj(lp, j)));
  405. min_aij = min_mat_aij(lp, 1);
  406. max_aij = max_mat_aij(lp, 1);
  407. ratio = max_aij / min_aij;
  408. xprintf(fmt, "2N", min_aij, max_aij, ratio);
  409. }
  410. done: return;
  411. }
  412. /***********************************************************************
  413. * NAME
  414. *
  415. * glp_scale_prob - scale problem data
  416. *
  417. * SYNOPSIS
  418. *
  419. * void glp_scale_prob(glp_prob *lp, int flags);
  420. *
  421. * DESCRIPTION
  422. *
  423. * The routine glp_scale_prob performs automatic scaling of problem
  424. * data for the specified problem object.
  425. *
  426. * The parameter flags specifies scaling options used by the routine.
  427. * Options can be combined with the bitwise OR operator and may be the
  428. * following:
  429. *
  430. * GLP_SF_GM perform geometric mean scaling;
  431. * GLP_SF_EQ perform equilibration scaling;
  432. * GLP_SF_2N round scale factors to nearest power of two;
  433. * GLP_SF_SKIP skip scaling, if the problem is well scaled.
  434. *
  435. * The parameter flags may be specified as GLP_SF_AUTO, in which case
  436. * the routine chooses scaling options automatically. */
  437. void glp_scale_prob(glp_prob *lp, int flags)
  438. { if (flags & ~(GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP |
  439. GLP_SF_AUTO))
  440. xerror("glp_scale_prob: flags = 0x%02X; invalid scaling option"
  441. "s\n", flags);
  442. if (flags & GLP_SF_AUTO)
  443. flags = (GLP_SF_GM | GLP_SF_EQ | GLP_SF_SKIP);
  444. scale_prob(lp, flags);
  445. return;
  446. }
  447. /* eof */