You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
10 KiB

  1. /* glpapi10.c (solution checking routines) */
  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, 2011, 2013 Andrew Makhorin, Department for Applied
  7. * Informatics, Moscow Aviation Institute, Moscow, Russia. All rights
  8. * reserved. 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 "env.h"
  24. #include "prob.h"
  25. void glp_check_kkt(glp_prob *P, int sol, int cond, double *_ae_max,
  26. int *_ae_ind, double *_re_max, int *_re_ind)
  27. { /* check feasibility and optimality conditions */
  28. int m = P->m;
  29. int n = P->n;
  30. GLPROW *row;
  31. GLPCOL *col;
  32. GLPAIJ *aij;
  33. int i, j, ae_ind, re_ind;
  34. double e, sp, sn, t, ae_max, re_max;
  35. if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP))
  36. xerror("glp_check_kkt: sol = %d; invalid solution indicator\n",
  37. sol);
  38. if (!(cond == GLP_KKT_PE || cond == GLP_KKT_PB ||
  39. cond == GLP_KKT_DE || cond == GLP_KKT_DB ||
  40. cond == GLP_KKT_CS))
  41. xerror("glp_check_kkt: cond = %d; invalid condition indicator "
  42. "\n", cond);
  43. ae_max = re_max = 0.0;
  44. ae_ind = re_ind = 0;
  45. if (cond == GLP_KKT_PE)
  46. { /* xR - A * xS = 0 */
  47. for (i = 1; i <= m; i++)
  48. { row = P->row[i];
  49. sp = sn = 0.0;
  50. /* t := xR[i] */
  51. if (sol == GLP_SOL)
  52. t = row->prim;
  53. else if (sol == GLP_IPT)
  54. t = row->pval;
  55. else if (sol == GLP_MIP)
  56. t = row->mipx;
  57. else
  58. xassert(sol != sol);
  59. if (t >= 0.0) sp += t; else sn -= t;
  60. for (aij = row->ptr; aij != NULL; aij = aij->r_next)
  61. { col = aij->col;
  62. /* t := - a[i,j] * xS[j] */
  63. if (sol == GLP_SOL)
  64. t = - aij->val * col->prim;
  65. else if (sol == GLP_IPT)
  66. t = - aij->val * col->pval;
  67. else if (sol == GLP_MIP)
  68. t = - aij->val * col->mipx;
  69. else
  70. xassert(sol != sol);
  71. if (t >= 0.0) sp += t; else sn -= t;
  72. }
  73. /* absolute error */
  74. e = fabs(sp - sn);
  75. if (ae_max < e)
  76. ae_max = e, ae_ind = i;
  77. /* relative error */
  78. e /= (1.0 + sp + sn);
  79. if (re_max < e)
  80. re_max = e, re_ind = i;
  81. }
  82. }
  83. else if (cond == GLP_KKT_PB)
  84. { /* lR <= xR <= uR */
  85. for (i = 1; i <= m; i++)
  86. { row = P->row[i];
  87. /* t := xR[i] */
  88. if (sol == GLP_SOL)
  89. t = row->prim;
  90. else if (sol == GLP_IPT)
  91. t = row->pval;
  92. else if (sol == GLP_MIP)
  93. t = row->mipx;
  94. else
  95. xassert(sol != sol);
  96. /* check lower bound */
  97. if (row->type == GLP_LO || row->type == GLP_DB ||
  98. row->type == GLP_FX)
  99. { if (t < row->lb)
  100. { /* absolute error */
  101. e = row->lb - t;
  102. if (ae_max < e)
  103. ae_max = e, ae_ind = i;
  104. /* relative error */
  105. e /= (1.0 + fabs(row->lb));
  106. if (re_max < e)
  107. re_max = e, re_ind = i;
  108. }
  109. }
  110. /* check upper bound */
  111. if (row->type == GLP_UP || row->type == GLP_DB ||
  112. row->type == GLP_FX)
  113. { if (t > row->ub)
  114. { /* absolute error */
  115. e = t - row->ub;
  116. if (ae_max < e)
  117. ae_max = e, ae_ind = i;
  118. /* relative error */
  119. e /= (1.0 + fabs(row->ub));
  120. if (re_max < e)
  121. re_max = e, re_ind = i;
  122. }
  123. }
  124. }
  125. /* lS <= xS <= uS */
  126. for (j = 1; j <= n; j++)
  127. { col = P->col[j];
  128. /* t := xS[j] */
  129. if (sol == GLP_SOL)
  130. t = col->prim;
  131. else if (sol == GLP_IPT)
  132. t = col->pval;
  133. else if (sol == GLP_MIP)
  134. t = col->mipx;
  135. else
  136. xassert(sol != sol);
  137. /* check lower bound */
  138. if (col->type == GLP_LO || col->type == GLP_DB ||
  139. col->type == GLP_FX)
  140. { if (t < col->lb)
  141. { /* absolute error */
  142. e = col->lb - t;
  143. if (ae_max < e)
  144. ae_max = e, ae_ind = m+j;
  145. /* relative error */
  146. e /= (1.0 + fabs(col->lb));
  147. if (re_max < e)
  148. re_max = e, re_ind = m+j;
  149. }
  150. }
  151. /* check upper bound */
  152. if (col->type == GLP_UP || col->type == GLP_DB ||
  153. col->type == GLP_FX)
  154. { if (t > col->ub)
  155. { /* absolute error */
  156. e = t - col->ub;
  157. if (ae_max < e)
  158. ae_max = e, ae_ind = m+j;
  159. /* relative error */
  160. e /= (1.0 + fabs(col->ub));
  161. if (re_max < e)
  162. re_max = e, re_ind = m+j;
  163. }
  164. }
  165. }
  166. }
  167. else if (cond == GLP_KKT_DE)
  168. { /* A' * (lambdaR - cR) + (lambdaS - cS) = 0 */
  169. for (j = 1; j <= n; j++)
  170. { col = P->col[j];
  171. sp = sn = 0.0;
  172. /* t := lambdaS[j] - cS[j] */
  173. if (sol == GLP_SOL)
  174. t = col->dual - col->coef;
  175. else if (sol == GLP_IPT)
  176. t = col->dval - col->coef;
  177. else
  178. xassert(sol != sol);
  179. if (t >= 0.0) sp += t; else sn -= t;
  180. for (aij = col->ptr; aij != NULL; aij = aij->c_next)
  181. { row = aij->row;
  182. /* t := a[i,j] * (lambdaR[i] - cR[i]) */
  183. if (sol == GLP_SOL)
  184. t = aij->val * row->dual;
  185. else if (sol == GLP_IPT)
  186. t = aij->val * row->dval;
  187. else
  188. xassert(sol != sol);
  189. if (t >= 0.0) sp += t; else sn -= t;
  190. }
  191. /* absolute error */
  192. e = fabs(sp - sn);
  193. if (ae_max < e)
  194. ae_max = e, ae_ind = m+j;
  195. /* relative error */
  196. e /= (1.0 + sp + sn);
  197. if (re_max < e)
  198. re_max = e, re_ind = m+j;
  199. }
  200. }
  201. else if (cond == GLP_KKT_DB)
  202. { /* check lambdaR */
  203. for (i = 1; i <= m; i++)
  204. { row = P->row[i];
  205. /* t := lambdaR[i] */
  206. if (sol == GLP_SOL)
  207. t = row->dual;
  208. else if (sol == GLP_IPT)
  209. t = row->dval;
  210. else
  211. xassert(sol != sol);
  212. /* correct sign */
  213. if (P->dir == GLP_MIN)
  214. t = + t;
  215. else if (P->dir == GLP_MAX)
  216. t = - t;
  217. else
  218. xassert(P != P);
  219. /* check for positivity */
  220. #if 1 /* 08/III-2013 */
  221. /* the former check was correct */
  222. /* the bug reported by David Price is related to violation
  223. of complementarity slackness, not to this condition */
  224. if (row->type == GLP_FR || row->type == GLP_LO)
  225. #else
  226. if (row->stat == GLP_NF || row->stat == GLP_NL)
  227. #endif
  228. { if (t < 0.0)
  229. { e = - t;
  230. if (ae_max < e)
  231. ae_max = re_max = e, ae_ind = re_ind = i;
  232. }
  233. }
  234. /* check for negativity */
  235. #if 1 /* 08/III-2013 */
  236. /* see comment above */
  237. if (row->type == GLP_FR || row->type == GLP_UP)
  238. #else
  239. if (row->stat == GLP_NF || row->stat == GLP_NU)
  240. #endif
  241. { if (t > 0.0)
  242. { e = + t;
  243. if (ae_max < e)
  244. ae_max = re_max = e, ae_ind = re_ind = i;
  245. }
  246. }
  247. }
  248. /* check lambdaS */
  249. for (j = 1; j <= n; j++)
  250. { col = P->col[j];
  251. /* t := lambdaS[j] */
  252. if (sol == GLP_SOL)
  253. t = col->dual;
  254. else if (sol == GLP_IPT)
  255. t = col->dval;
  256. else
  257. xassert(sol != sol);
  258. /* correct sign */
  259. if (P->dir == GLP_MIN)
  260. t = + t;
  261. else if (P->dir == GLP_MAX)
  262. t = - t;
  263. else
  264. xassert(P != P);
  265. /* check for positivity */
  266. #if 1 /* 08/III-2013 */
  267. /* see comment above */
  268. if (col->type == GLP_FR || col->type == GLP_LO)
  269. #else
  270. if (col->stat == GLP_NF || col->stat == GLP_NL)
  271. #endif
  272. { if (t < 0.0)
  273. { e = - t;
  274. if (ae_max < e)
  275. ae_max = re_max = e, ae_ind = re_ind = m+j;
  276. }
  277. }
  278. /* check for negativity */
  279. #if 1 /* 08/III-2013 */
  280. /* see comment above */
  281. if (col->type == GLP_FR || col->type == GLP_UP)
  282. #else
  283. if (col->stat == GLP_NF || col->stat == GLP_NU)
  284. #endif
  285. { if (t > 0.0)
  286. { e = + t;
  287. if (ae_max < e)
  288. ae_max = re_max = e, ae_ind = re_ind = m+j;
  289. }
  290. }
  291. }
  292. }
  293. else
  294. xassert(cond != cond);
  295. if (_ae_max != NULL) *_ae_max = ae_max;
  296. if (_ae_ind != NULL) *_ae_ind = ae_ind;
  297. if (_re_max != NULL) *_re_max = re_max;
  298. if (_re_ind != NULL) *_re_ind = re_ind;
  299. return;
  300. }
  301. /* eof */