180 } |
181 } |
181 |
182 |
182 #endif |
183 #endif |
183 } |
184 } |
184 |
185 |
|
186 void solveAndCheck(LpSolverBase& lp, LpSolverBase::SolutionStatus stat, |
|
187 double exp_opt){ |
|
188 lp.solve(); |
|
189 //int decimal,sign; |
|
190 std::string buf1; |
|
191 // itoa(stat,buf1, 10); |
|
192 check(lp.primalStatus()==stat,"Primalstatus should be "+buf1); |
|
193 |
|
194 if (stat == LpSolverBase::OPTIMAL){ |
|
195 check(std::abs(lp.primalValue()-exp_opt)<1e-3, |
|
196 "Wrong optimal value: the right optimum is "); |
|
197 //+ecvt(exp_opt,2) |
|
198 } |
|
199 } |
|
200 |
185 void aTest(LpSolverBase & lp) |
201 void aTest(LpSolverBase & lp) |
186 { |
202 { |
187 typedef LpSolverBase LP; |
203 typedef LpSolverBase LP; |
188 |
204 |
189 //The following example is taken from the book by Gáspár and Temesi, page 39. |
205 //The following example is very simple |
190 |
206 |
191 typedef LpSolverBase::Row Row; |
207 typedef LpSolverBase::Row Row; |
192 typedef LpSolverBase::Col Col; |
208 typedef LpSolverBase::Col Col; |
193 |
209 |
194 |
210 |
195 Col x1 = lp.addCol(); |
211 Col x1 = lp.addCol(); |
196 Col x2 = lp.addCol(); |
212 Col x2 = lp.addCol(); |
197 |
213 |
198 |
214 |
199 //Constraints |
215 //Constraints |
200 lp.addRow(3*x1+2*x2 >=6); |
216 Row upright=lp.addRow(x1+x2 <=1); |
201 lp.addRow(-1*x1+x2<=4); |
217 lp.addRow(x1+x2 >=-1); |
202 lp.addRow(5*x1+8*x2<=40); |
218 lp.addRow(x1-x2 <=1); |
203 lp.addRow(x1-2*x2<=4); |
219 lp.addRow(x1-x2 >=-1); |
204 //Nonnegativity of the variables |
220 //Nonnegativity of the variables |
205 lp.colLowerBound(x1, 0); |
221 lp.colLowerBound(x1, 0); |
206 lp.colLowerBound(x2, 0); |
222 lp.colLowerBound(x2, 0); |
207 //Objective function |
223 //Objective function |
208 lp.setObj(2*x1+x2); |
224 lp.setObj(x1+x2); |
209 |
225 |
210 lp.max(); |
226 lp.max(); |
211 lp.solve(); |
227 |
212 |
228 //Maximization of x1+x2 |
213 double opt=122.0/9.0; |
229 //over the triangle with vertices (0,0) (0,1) (1,0) |
214 |
230 double expected_opt=1; |
215 if (lp.primalStatus()==LpSolverBase::OPTIMAL){ |
231 solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt); |
216 std::cout<< "Z = "<<lp.primalValue() |
232 |
217 << " (error = " << lp.primalValue()-opt |
233 //Minimization |
218 << "); x1 = "<<lp.primal(x1) |
234 lp.min(); |
219 << "; x2 = "<<lp.primal(x2) |
235 expected_opt=0; |
220 <<std::endl; |
236 solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt); |
221 |
237 |
222 } |
238 //Vertex (-1,0) instead of (0,0) |
223 else{ |
239 lp.colLowerBound(x1, -LpSolverBase::INF); |
224 std::cout<<"Optimal solution not found!"<<std::endl; |
240 expected_opt=-1; |
225 } |
241 solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt); |
226 |
242 |
227 check(lp.primalStatus()==LpSolverBase::OPTIMAL,"Primalstatus should be OPTIMAL"); |
243 //Erase one constraint and return to maximization |
228 |
244 lp.eraseRow(upright); |
229 check(std::abs(lp.primalValue()-opt)<1e-3, |
245 lp.max(); |
230 "Wrong optimal value: the right optimum is 122/9 (13.555555...)"); |
246 expected_opt=LpSolverBase::INF; |
231 |
247 solveAndCheck(lp, LpSolverBase::INFINITE, expected_opt); |
|
248 |
|
249 //Infeasibilty |
|
250 lp.addRow(x1+x2 <=-2); |
|
251 solveAndCheck(lp, LpSolverBase::INFEASIBLE, expected_opt); |
|
252 |
|
253 //Change problem and forget to solve |
|
254 lp.min(); |
|
255 check(lp.primalStatus()==LpSolverBase::UNDEFINED,"Primalstatus should be UNDEFINED"); |
|
256 |
|
257 // lp.solve(); |
|
258 // if (lp.primalStatus()==LpSolverBase::OPTIMAL){ |
|
259 // std::cout<< "Z = "<<lp.primalValue() |
|
260 // << " (error = " << lp.primalValue()-expected_opt |
|
261 // << "); x1 = "<<lp.primal(x1) |
|
262 // << "; x2 = "<<lp.primal(x2) |
|
263 // <<std::endl; |
|
264 |
|
265 // } |
|
266 // else{ |
|
267 // std::cout<<lp.primalStatus()<<std::endl; |
|
268 // std::cout<<"Optimal solution not found!"<<std::endl; |
|
269 // } |
|
270 |
|
271 |
232 |
272 |
233 } |
273 } |
234 |
274 |
235 |
275 |
236 int main() |
276 int main() |