文章目录
一、涉及软件
Visual Studio 2017、Visual Studio 2019
CPLEX 12.9.0
二、配置效果
1、可以实现C++调用CPLEX求解线性规划,混合整数规划等;
2、可以在debug和release两种模式下进行调试或者运行代码
三、配置步骤
1、首先选择代码运行的环境
(1)、将平台设置为x64
或者(活动)x64
,此处一定需要修改!不能使用x32
平台模式
(2)、配置的设置可以根据需要自行选择release
模式或者debug
模式(作者建议两种都进行配置一下,方便后续使用)
2、打开项目的属性项
3、修改C/C++附加包含目录
这里找到CPLEX的安装目录(根据自己的安装目录进行修改
),如本人的是:
(注:下述若不做特殊说明,均需要将目录替换为自己的目录,若安装时没进行修改,从IBM/ILOG/…的目录同下述目录应该相同)
//CPLEX安装目录
D:\Program Files\IBM\ILOG\CPLEX_Studio129\concert\include
D:\Program Files\IBM\ILOG\CPLEX_Studio129\cplex\include
将上述两项加入到附加目录之中,点击确定,效果如下:
4、修改C/C++预处理器中的预处理器定义项
添加下述命令到预处理器定义中(此处无需进行修改,直接复制粘贴就好
):
NDEBUG
_CONSOLE
IL_STD
5、修改C/C++代码生成中的运行库
将此处的改为多线程DLL(/MD)
或者多线程调试DLL(/MDd)
6、修改链接器常规项中的“附加库目录项”
将下述两个目录添加到“附加库目录项”中,目录地址同上述CPLEX安装目录相同
D:\Program Files\IBM\ILOG\CPLEX_Studio129\concert\lib\x64_windows_vs2017\stat_mda
D:\Program Files\IBM\ILOG\CPLEX_Studio129\cplex\lib\x64_windows_vs2017\stat_mda
7、修改链接器输入中的“附加依赖项”
将下述两个目录添加到“附加库目录项”中,目录地址同上述CPLEX安装目录相同
D:\Program Files\IBM\ILOG\CPLEX_Studio129\concert\lib\x64_windows_vs2017\stat_mda\concert.lib
D:\Program Files\IBM\ILOG\CPLEX_Studio129\cplex\lib\x64_windows_vs2017\stat_mda\cplex1290.lib
D:\Program Files\IBM\ILOG\CPLEX_Studio129\cplex\lib\x64_windows_vs2017\stat_mda\ilocplex.lib
8、 点击确定,点击应用,大功告成!
四、运行测试代码
1、下面给出CPLEX官方测试文档中的cutstock
代码进行测试
#include <ilcplex/ilocplex.h>
ILOSTLBEGIN
#define RC_EPS 1.0e-6
static void readData(const char* filename, IloNum& rollWidth,
IloNumArray& size, IloNumArray& amount);
static void report1(IloCplex& cutSolver, IloNumVarArray Cut,
IloRangeArray Fill);
static void report2(IloAlgorithm& patSolver,
IloNumVarArray Use,
IloObjective obj);
static void report3(IloCplex& cutSolver, IloNumVarArray Cut);
/// MAIN PROGRAM ///
int main(int argc, char **argv)
{
IloEnv env;
try {
IloInt i, j;
IloNum rollWidth;
IloNumArray amount(env);
IloNumArray size(env);
if (argc > 1)
readData(argv[1], rollWidth, size, amount);
else
readData("cutstock.dat",
rollWidth, size, amount);
/// CUTTING-OPTIMIZATION PROBLEM ///
IloModel cutOpt(env);
IloObjective RollsUsed = IloAdd(cutOpt, IloMinimize(env));
IloRangeArray Fill = IloAdd(cutOpt,
IloRangeArray(env, amount, IloInfinity));
IloNumVarArray Cut(env);
IloInt nWdth = size.getSize();
for (j = 0; j < nWdth; j++) {
Cut.add(IloNumVar(RollsUsed(1) + Fill[j](int(rollWidth / size[j]))));
}
IloCplex cutSolver(cutOpt);
/// PATTERN-GENERATION PROBLEM ///
IloModel patGen(env);
IloObjective ReducedCost = IloAdd(patGen, IloMinimize(env, 1));
IloNumVarArray Use(env, nWdth, 0.0, IloInfinity, ILOINT);
patGen.add(IloScalProd(size, Use) <= rollWidth);
IloCplex patSolver(patGen);
/// COLUMN-GENERATION PROCEDURE ///
IloNumArray price(env, nWdth);
IloNumArray newPatt(env, nWdth);
/// COLUMN-GENERATION PROCEDURE ///
for (;;) {
/// OPTIMIZE OVER CURRENT PATTERNS ///
cutSolver.solve();
report1(cutSolver, Cut, Fill);
/// FIND AND ADD A NEW PATTERN ///
for (i = 0; i < nWdth; i++) {
price[i] = -cutSolver.getDual(Fill[i]);
}
ReducedCost.setLinearCoefs(Use, price);
patSolver.solve();
report2(patSolver, Use, ReducedCost);
if (patSolver.getValue(ReducedCost) > -RC_EPS) break;
patSolver.getValues(newPatt, Use);
Cut.add(IloNumVar(RollsUsed(1) + Fill(newPatt)));
}
cutOpt.add(IloConversion(env, Cut, ILOINT));
cutSolver.solve();
cout << "Solution status: " << cutSolver.getStatus() << endl;
report3(cutSolver, Cut);
}
catch (IloException& ex) {
cerr << "Error: " << ex << endl;
}
catch (...) {
cerr << "Error" << endl;
}
env.end();
return 0;
}
static void readData(const char* filename, IloNum& rollWidth,
IloNumArray& size, IloNumArray& amount)
{
ifstream in(filename);
if (in) {
in >> rollWidth;
in >> size;
in >> amount;
}
else {
cerr << "No such file: " << filename << endl;
throw(1);
}
}
static void report1(IloCplex& cutSolver, IloNumVarArray Cut,
IloRangeArray Fill)
{
cout << endl;
cout << "Using " << cutSolver.getObjValue() << " rolls" << endl;
cout << endl;
for (IloInt j = 0; j < Cut.getSize(); j++) {
cout << " Cut" << j << " = " << cutSolver.getValue(Cut[j]) << endl;
}
cout << endl;
for (IloInt i = 0; i < Fill.getSize(); i++) {
cout << " Fill" << i << " = " << cutSolver.getDual(Fill[i]) << endl;
}
cout << endl;
}
static void report2(IloAlgorithm& patSolver, IloNumVarArray Use,
IloObjective obj)
{
cout << endl;
cout << "Reduced cost is " << patSolver.getValue(obj) << endl;
cout << endl;
if (patSolver.getValue(obj) <= -RC_EPS) {
for (IloInt i = 0; i < Use.getSize(); i++) {
cout << " Use" << i << " = " << patSolver.getValue(Use[i]) << endl;
}
cout << endl;
}
}
static void report3(IloCplex& cutSolver, IloNumVarArray Cut)
{
cout << endl;
cout << "Best integer solution uses "
<< cutSolver.getObjValue() << " rolls" << endl;
cout << endl;
for (IloInt j = 0; j < Cut.getSize(); j++) {
cout << " Cut" << j << " = " << cutSolver.getValue(Cut[j]) << endl;
}
}
2、首先编译代码,出现下面截图说明配置成功辽
3、给出输入文件信息如下:
115
[25, 40, 50, 55, 70]
[50, 36, 24, 8, 30]