aboutsummaryrefslogtreecommitdiffstats
path: root/native/src/linprog/cplex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'native/src/linprog/cplex.cpp')
-rw-r--r--native/src/linprog/cplex.cpp168
1 files changed, 168 insertions, 0 deletions
diff --git a/native/src/linprog/cplex.cpp b/native/src/linprog/cplex.cpp
new file mode 100644
index 0000000..b5565d4
--- /dev/null
+++ b/native/src/linprog/cplex.cpp
@@ -0,0 +1,168 @@
1#define IL_STD // required by CPLEX when using STL classes.
2
3#include <ilcplex/ilocplex.h>
4
5#include "cpu_time.h"
6
7#include "linprog/cplex.h"
8
9class CPLEXSolution : public Solution
10{
11private:
12 IloEnv ilo_env;
13 IloEnv& get_env()
14 {
15 return ilo_env;
16 }
17
18 IloNumArray cplex_values;
19
20 const LinearProgram &linprog;
21
22 bool solved;
23
24 void solve_model(unsigned int max_num_vars,
25 double var_lb, double var_ub);
26
27 IloObjective make_objective(const IloNumVarArray& vars);
28 IloRangeArray make_constraints(const IloNumVarArray& vars);
29
30 IloRange make_constraint(const IloNumVarArray &vars,
31 const LinearExpression *exp, double bound,
32 bool is_exact_bound);
33
34public:
35 CPLEXSolution(const LinearProgram &lp, unsigned int max_num_vars,
36 double var_lb = 0.0, double var_ub = 1.0);
37 ~CPLEXSolution();
38
39 double get_value(unsigned int var) const
40 {
41 return cplex_values[var];
42 }
43
44 bool is_solved() const
45 {
46 return solved;
47 }
48};
49
50CPLEXSolution::CPLEXSolution(const LinearProgram& lp, unsigned int max_num_vars,
51 double var_lb, double var_ub)
52 : ilo_env(),
53 cplex_values(get_env(), max_num_vars),
54 linprog(lp),
55 solved(false)
56{
57 get_env().setNormalizer(IloFalse);
58 get_env().setOut(get_env().getNullStream());
59
60 if (max_num_vars > 0)
61 solve_model(max_num_vars, var_lb, var_ub);
62 else
63 // Trivial case: no variables.
64 solved = true;
65}
66
67
68void CPLEXSolution::solve_model(unsigned int max_num_vars,
69 double var_lb, double var_ub)
70{
71 try
72 {
73 IloNumVarArray cplex_vars = IloNumVarArray(get_env(), max_num_vars,
74 var_lb, var_ub);
75
76 IloObjective objective = make_objective(cplex_vars);
77 IloRangeArray constraints = make_constraints(cplex_vars);
78
79 IloModel model = IloModel(get_env());
80
81 model.add(objective);
82 model.add(constraints);
83
84
85 IloCplex cplex = IloCplex(model);
86
87 cplex.solve();
88
89 cplex.getValues(cplex_vars, cplex_values);
90 solved = true;
91
92 } catch (IloException &ex)
93 {
94 // Improve me: we should export some kind of error info.
95 std::cerr << "CPLEX failed: " << ex << std::endl;
96 solved = false;
97 }
98}
99
100IloObjective CPLEXSolution::make_objective(const IloNumVarArray &vars)
101{
102 const LinearExpression *obj = linprog.get_objective();
103
104 IloObjective goal = IloObjective(get_env(), 0, IloObjective::Maximize);
105 IloNumArray coeffs = IloNumArray(get_env(), vars.getSize());
106
107 assert((int) obj->get_terms().size() <= coeffs.getSize());
108
109 coeffs.add(vars.getSize(), 0);
110
111 // Set coefficient for each variable in the objective function.
112 foreach(obj->get_terms(), term)
113 {
114 double coefficient = term->first;
115 unsigned int var_idx = term->second;
116 coeffs[var_idx] = coefficient;
117 }
118
119 goal.setLinearCoefs(vars, coeffs);
120
121 return goal;
122}
123
124IloRangeArray CPLEXSolution::make_constraints(const IloNumVarArray &vars)
125{
126 IloRangeArray constraints(get_env());
127
128 foreach (linprog.get_equalities(), exp)
129 constraints.add(make_constraint(vars, exp->first, exp->second, true));
130
131 foreach (linprog.get_inequalities(), exp)
132 constraints.add(make_constraint(vars, exp->first, exp->second, false));
133
134 return constraints;
135}
136
137IloRange CPLEXSolution::make_constraint(const IloNumVarArray &vars,
138 const LinearExpression *exp, double bound,
139 bool is_exact_bound)
140{
141 IloRange r = IloRange(get_env(), -IloInfinity, bound);
142
143 if (is_exact_bound)
144 r.setLB(bound);
145
146 foreach (exp->get_terms(), term)
147 r.setLinearCoef(vars[term->second], term->first);
148
149 return r;
150}
151
152CPLEXSolution::~CPLEXSolution()
153{
154 get_env().end();
155}
156
157
158Solution *cplex_solve(const LinearProgram& lp, unsigned int max_num_vars)
159{
160 CPLEXSolution *sol = new CPLEXSolution(lp, max_num_vars);
161 if (sol->is_solved())
162 return sol;
163 else
164 {
165 delete sol;
166 return NULL;
167 }
168}