1 /* npp.c (LP/MIP preprocessing) */
2
3 /***********************************************************************
4 * This code is part of GLPK (GNU Linear Programming Kit).
5 * Copyright (C) 2017 Free Software Foundation, Inc.
6 * Written by Andrew Makhorin <mao@gnu.org>.
7 *
8 * GLPK is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GLPK is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 * License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
20 ***********************************************************************/
21
22 #include "env.h"
23 #include "npp.h"
24
glp_npp_alloc_wksp(void)25 glp_prep *glp_npp_alloc_wksp(void)
26 { /* allocate the preprocessor workspace */
27 glp_prep *prep;
28 prep = npp_create_wksp();
29 return prep;
30 }
31
glp_npp_load_prob(glp_prep * prep,glp_prob * P,int sol,int names)32 void glp_npp_load_prob(glp_prep *prep, glp_prob *P, int sol, int names)
33 { /* load original problem instance */
34 if (prep->sol != 0)
35 xerror("glp_npp_load_prob: invalid call sequence (original ins"
36 "tance already loaded)\n");
37 if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP))
38 xerror("glp_npp_load_prob: sol = %d; invalid parameter\n",
39 sol);
40 if (!(names == GLP_ON || names == GLP_OFF))
41 xerror("glp_npp_load_prob: names = %d; invalid parameter\n",
42 names);
43 npp_load_prob(prep, P, names, sol, GLP_OFF);
44 return;
45 }
46
glp_npp_preprocess1(glp_prep * prep,int hard)47 int glp_npp_preprocess1(glp_prep *prep, int hard)
48 { /* perform basic LP/MIP preprocessing */
49 if (prep->sol == 0)
50 xerror("glp_npp_preprocess1: invalid call sequence (original i"
51 "nstance not loaded yet)\n");
52 if (prep->pool == NULL)
53 xerror("glp_npp_preprocess1: invalid call sequence (preprocess"
54 "ing already finished)\n");
55 if (!(hard == GLP_ON || hard == GLP_OFF))
56 xerror("glp_npp_preprocess1: hard = %d; invalid parameter\n",
57 hard);
58 return npp_process_prob(prep, hard);
59 }
60
glp_npp_build_prob(glp_prep * prep,glp_prob * Q)61 void glp_npp_build_prob(glp_prep *prep, glp_prob *Q)
62 { /* build resultant problem instance */
63 if (prep->sol == 0)
64 xerror("glp_npp_build_prob: invalid call sequence (original in"
65 "stance not loaded yet)\n");
66 if (prep->pool == NULL)
67 xerror("glp_npp_build_prob: invalid call sequence (resultant i"
68 "nstance already built)\n");
69 npp_build_prob(prep, Q);
70 return;
71 }
72
glp_npp_postprocess(glp_prep * prep,glp_prob * Q)73 void glp_npp_postprocess(glp_prep *prep, glp_prob *Q)
74 { /* postprocess solution to resultant problem */
75 if (prep->pool != NULL)
76 xerror("glp_npp_postprocess: invalid call sequence (resultant "
77 "instance not built yet)\n");
78 if (!(prep->m == Q->m && prep->n == Q->n && prep->nnz == Q->nnz))
79 xerror("glp_npp_postprocess: resultant instance mismatch\n");
80 switch (prep->sol)
81 { case GLP_SOL:
82 if (glp_get_status(Q) != GLP_OPT)
83 xerror("glp_npp_postprocess: unable to recover non-optim"
84 "al basic solution\n");
85 break;
86 case GLP_IPT:
87 if (glp_ipt_status(Q) != GLP_OPT)
88 xerror("glp_npp_postprocess: unable to recover non-optim"
89 "al interior-point solution\n");
90 break;
91 case GLP_MIP:
92 if (!(glp_mip_status(Q) == GLP_OPT || glp_mip_status(Q) ==
93 GLP_FEAS))
94 xerror("glp_npp_postprocess: unable to recover integer n"
95 "on-feasible solution\n");
96 break;
97 default:
98 xassert(prep != prep);
99 }
100 npp_postprocess(prep, Q);
101 return;
102 }
103
glp_npp_obtain_sol(glp_prep * prep,glp_prob * P)104 void glp_npp_obtain_sol(glp_prep *prep, glp_prob *P)
105 { /* obtain solution to original problem */
106 if (prep->pool != NULL)
107 xerror("glp_npp_obtain_sol: invalid call sequence (resultant i"
108 "nstance not built yet)\n");
109 switch (prep->sol)
110 { case GLP_SOL:
111 if (prep->p_stat == 0 || prep->d_stat == 0)
112 xerror("glp_npp_obtain_sol: invalid call sequence (basic"
113 " solution not provided yet)\n");
114 break;
115 case GLP_IPT:
116 if (prep->t_stat == 0)
117 xerror("glp_npp_obtain_sol: invalid call sequence (inter"
118 "ior-point solution not provided yet)\n");
119 break;
120 case GLP_MIP:
121 if (prep->i_stat == 0)
122 xerror("glp_npp_obtain_sol: invalid call sequence (MIP s"
123 "olution not provided yet)\n");
124 break;
125 default:
126 xassert(prep != prep);
127 }
128 if (!(prep->orig_dir == P->dir && prep->orig_m == P->m &&
129 prep->orig_n == P->n && prep->orig_nnz == P->nnz))
130 xerror("glp_npp_obtain_sol: original instance mismatch\n");
131 npp_unload_sol(prep, P);
132 return;
133 }
134
glp_npp_free_wksp(glp_prep * prep)135 void glp_npp_free_wksp(glp_prep *prep)
136 { /* free the preprocessor workspace */
137 npp_delete_wksp(prep);
138 return;
139 }
140
141 /* eof */
142