22 #ifdef HAVE_CONFIG_H |
22 #ifdef HAVE_CONFIG_H |
23 #include <lemon/config.h> |
23 #include <lemon/config.h> |
24 #endif |
24 #endif |
25 |
25 |
26 #ifdef HAVE_CPLEX |
26 #ifdef HAVE_CPLEX |
27 #include <lemon/mip_cplex.h> |
27 #include <lemon/lp_cplex.h> |
28 #endif |
28 #endif |
29 |
29 |
30 #ifdef HAVE_GLPK |
30 #ifdef HAVE_GLPK |
31 #include <lemon/mip_glpk.h> |
31 #include <lemon/lp_glpk.h> |
32 #endif |
32 #endif |
33 |
33 |
34 |
34 |
35 using namespace lemon; |
35 using namespace lemon; |
36 |
36 |
37 void solveAndCheck(MipSolverBase& lp, MipSolverBase::SolutionStatus stat, |
37 void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat, |
38 double exp_opt) { |
38 double exp_opt) { |
39 using std::string; |
39 using std::string; |
40 |
40 |
41 lp.solve(); |
41 mip.solve(); |
42 //int decimal,sign; |
42 //int decimal,sign; |
43 std::ostringstream buf; |
43 std::ostringstream buf; |
44 buf << "Primalstatus should be: " << int(stat) |
44 buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type()); |
45 <<" and it is "<<int(lp.mipStatus()); |
|
46 |
45 |
47 |
46 |
48 // itoa(stat,buf1, 10); |
47 // itoa(stat,buf1, 10); |
49 check(lp.mipStatus()==stat, buf.str()); |
48 check(mip.type()==stat, buf.str()); |
50 |
49 |
51 if (stat == MipSolverBase::OPTIMAL) { |
50 if (stat == MipSolver::OPTIMAL) { |
52 std::ostringstream sbuf; |
51 std::ostringstream sbuf; |
53 buf << "Wrong optimal value: the right optimum is " << exp_opt; |
52 buf << "Wrong optimal value: the right optimum is " << exp_opt; |
54 check(std::abs(lp.primalValue()-exp_opt) < 1e-3, sbuf.str()); |
53 check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str()); |
55 //+ecvt(exp_opt,2) |
54 //+ecvt(exp_opt,2) |
56 } |
55 } |
57 } |
56 } |
58 |
57 |
59 void aTest(MipSolverBase& mip) |
58 void aTest(MipSolver& mip) |
60 { |
59 { |
61 //The following example is very simple |
60 //The following example is very simple |
62 |
61 |
63 |
62 |
64 typedef MipSolverBase::Row Row; |
63 typedef MipSolver::Row Row; |
65 typedef MipSolverBase::Col Col; |
64 typedef MipSolver::Col Col; |
66 |
65 |
67 |
66 |
68 |
67 |
69 Col x1 = mip.addCol(); |
68 Col x1 = mip.addCol(); |
70 Col x2 = mip.addCol(); |
69 Col x2 = mip.addCol(); |
88 mip.colLowerBound(x1, 0); |
87 mip.colLowerBound(x1, 0); |
89 |
88 |
90 //Maximization of x1 |
89 //Maximization of x1 |
91 //over the triangle with vertices (0,0),(4/5,2/5),(0,2) |
90 //over the triangle with vertices (0,0),(4/5,2/5),(0,2) |
92 double expected_opt=4.0/5.0; |
91 double expected_opt=4.0/5.0; |
93 solveAndCheck(mip, MipSolverBase::OPTIMAL, expected_opt); |
92 solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt); |
94 |
93 |
95 //Restrict x2 to integer |
94 //Restrict x2 to integer |
96 mip.colType(x2,MipSolverBase::INT); |
95 mip.colType(x2,MipSolver::INTEGER); |
97 expected_opt=1.0/2.0; |
96 expected_opt=1.0/2.0; |
98 solveAndCheck(mip, MipSolverBase::OPTIMAL, expected_opt); |
97 solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt); |
99 |
98 |
100 |
99 |
101 //Restrict both to integer |
100 //Restrict both to integer |
102 mip.colType(x1,MipSolverBase::INT); |
101 mip.colType(x1,MipSolver::INTEGER); |
103 expected_opt=0; |
102 expected_opt=0; |
104 solveAndCheck(mip, MipSolverBase::OPTIMAL, expected_opt); |
103 solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt); |
105 |
104 |
106 |
105 |
107 |
106 |
108 } |
107 } |
109 |
108 |
110 |
109 |
111 int main() |
110 int main() |
112 { |
111 { |
113 |
112 |
114 #ifdef HAVE_GLPK |
113 #ifdef HAVE_GLPK |
115 MipGlpk mip1; |
114 { |
116 aTest(mip1); |
115 MipGlpk mip1; |
|
116 aTest(mip1); |
|
117 } |
117 #endif |
118 #endif |
118 |
119 |
119 #ifdef HAVE_CPLEX |
120 #ifdef HAVE_CPLEX |
120 MipCplex mip2; |
121 try { |
121 aTest(mip2); |
122 MipCplex mip2; |
|
123 aTest(mip2); |
|
124 } catch (CplexEnv::LicenseError& error) { |
|
125 #ifdef LEMON_FORCE_CPLEX_CHECK |
|
126 check(false, error.what()); |
|
127 #else |
|
128 std::cerr << error.what() << std::endl; |
|
129 std::cerr << "Cplex license check failed, lp check skipped" << std::endl; |
|
130 #endif |
|
131 } |
122 #endif |
132 #endif |
123 |
133 |
124 return 0; |
134 return 0; |
125 |
135 |
126 } |
136 } |