141 bool defaultParam =
false;
149 CPXENVptr env = NULL;
153 env = CPXXopenCPLEX (&status);
156 char errmsg[CPXMESSAGEBUFSIZE];
157 CPXXgeterrorstring (env, status, errmsg);
158 limboAssertMsg(0,
"Could not open CPLEX environment: %s", errmsg);
160 param->operator()(env);
162 m_cplexModel = CPXXcreateprob (env, &status,
"CplexLinearApi");
168 CPXDIM numcols =
m_model->numVariables();
169 CPXDIM numrows =
m_model->constraints().size();
171 std::vector<double> obj (numcols, 0);
172 std::vector<double> rhs (numrows, 0);
173 std::vector<char> sense (numrows,
'=');
175 std::vector<CPXNNZ> matbeg (numcols, 0);
176 std::vector<CPXDIM> matcnt (numcols, 0);
177 std::vector<double> lb (numcols);
178 std::vector<double> ub (numcols);
179 std::vector<char> ctype (numcols);
181 for (
unsigned int i = 0, ie =
m_model->numVariables(); i < ie; ++i)
183 variable_type var (i);
184 lb[var.
id()] =
m_model->variableLowerBound(var);
185 ub[var.
id()] =
m_model->variableUpperBound(var);
189 "LinearModel<T, V> is declared as V = integer type, but variable %s is CONTINUOUS",
m_model->variableName(var).c_str());
194 for (
unsigned int i = 0, ie =
m_model->constraints().size(); i < ie; ++i)
196 constraint_type
const& constr =
m_model->constraints().at(i);
198 for (
typename std::vector<term_type>::const_iterator it = constr.
expression().
terms().begin(), ite = constr.
expression().
terms().end(); it != ite; ++it)
200 if (it->coefficient() != 0)
202 matcnt[it->variable().id()] += 1;
209 for (
unsigned int i = 0; i < numcols - 1; ++i)
211 matbeg[i + 1] = matbeg[i] + matcnt[i];
214 numnz += matcnt.back();
216 std::vector<CPXDIM> matind (numnz, 0);
217 std::vector<double> matval (numnz, 0);
218 std::vector<CPXDIM> curcnt (numcols, 0);
219 for (
unsigned int i = 0, ie =
m_model->constraints().size(); i < ie; ++i)
221 constraint_type
const& constr =
m_model->constraints().at(i);
223 for (
typename std::vector<term_type>::const_iterator it = constr.
expression().
terms().begin(), ite = constr.
expression().
terms().end(); it != ite; ++it)
225 if (it->coefficient() != 0)
227 matind[matbeg[it->variable().id()] + curcnt[it->variable().id()]] = i;
228 matval[matbeg[it->variable().id()] + curcnt[it->variable().id()]] = it->coefficient();
229 limboAssert(matbeg[it->variable().id()] + curcnt[it->variable().id()] < matind.size());
230 curcnt[it->variable().id()] += 1;
234 switch (constr.
sense())
237 sense[i] =
'L';
break;
239 sense[i] =
'E';
break;
241 sense[i] =
'G';
break;
251 for (
typename std::vector<term_type>::const_iterator it =
m_model->objective().terms().begin(), ite =
m_model->objective().terms().end(); it != ite; ++it)
253 obj[it->variable().id()] = it->coefficient();
255 objsen =
m_model->optimizeType() ==
MIN? CPX_MIN : CPX_MAX;
259 status = CPXXcopylp (env,
m_cplexModel, numcols, numrows, objsen, obj.data(), rhs.data(),
260 sense.data(), matbeg.data(), matcnt.data(), matind.data(), matval.data(),
261 lb.data(), ub.data(), NULL);
266 status = CPXXcopyctype (env,
m_cplexModel, ctype.data());
273 status = CPXXwriteprob (env,
m_cplexModel,
"problem.lp", NULL);
291 if (solstat == CPXMIP_INFEASIBLE)
293 status = CPXXrefineconflictext (env,
m_cplexModel, 0, 0, NULL, NULL, NULL, NULL);
298 status = CPXXclpwrite (env,
m_cplexModel,
"problem.ilp");
303 limboPrint(kERROR,
"Model is infeasible, compute IIS and write to problem.ilp\n");
306 status = CPXXwriteprob (env,
m_cplexModel,
"problem.sol.lp", NULL);
313 std::vector<double> x (numcols, 0);
314 status = CPXXgetx (env,
m_cplexModel, x.data(), 0, numcols-1);
321 for (
unsigned int i = 0; i <
m_model->numVariables(); ++i)
323 variable_type var =
m_model->variable(i);
324 double value = x[var.
id()];
325 m_model->setVariableSolution(
m_model->variable(i), sround(value));
342 status = CPXXcloseCPLEX (&env);
355 case CPXMIP_INFEASIBLE:
359 case CPXMIP_INForUNBD:
360 case CPXMIP_UNBOUNDED: