【ilcplex】IloEnv

本文介绍了Concert Technology中用于管理模型或算法环境的IloEnv类。IloEnv实例作为一个环境,负责管理内存和标识符。每个Concert Technology对象如模型或算法都必须属于一个IloEnv实例。

【参考】http://www.ibm.com/support/knowledgecenter/en/SSSA5P_12.6.3/ilog.odms.cpo.help/refcppcpoptimizer/html/classes/IloEnv.html

The class of environments for models or algorithms in Concert Technology.
Concert Technology中模型或算法的环境类。

An instance of this class is an environment, managing memory and identifiers for modeling objects. Every Concert Technology object, such as an extractable object, a model, or an algorithm, must belong to an environment. In C++ terms, when you construct a model (an instance of IloModel) or an algorithm (an instance of IloCplex, IloCP, or IloSolver, for example), then you must pass one instance of IloEnv as an argument of that constructor.
这个类的一个实例是一个环境,管理用于建模对象的内存和标识符。 每个Concert Technology对象(例如可提取对象,模型或算法)都必须属于环境。 在C ++术语中,当您构造模型(IloModel的实例)或算法(例如IloCplex,IloCP或IloSolver的实例)时,您必须传递IloEnv的一个实例作为该构造函数的参数


我理解成,每次都带上环境参数即可

待续...


#include<ilcplex/ilocplex.h> #include<vector> #include<map> #include<algorithm> ILOSTLBEGIN typedef IloArray<IloIntArray> TwoDIntMatrix;//二维整数数组 typedef IloArray<IloArray<IloIntArray>>ThreeDIntMatrix;//三维整数数组 typedef IloArray < IloArray<IloNumArray>>ThreeDNumMatrix;//三维数组 typedef IloArray<IloNumVarArray> TwoDNumVars;//二维变量数组 typedef IloArray<IloIntVarArray> TwoDIntVars;//二位整数变量数组 int main(int argc, char** argv)//argc是命令行参数数量,argv是指向这些参数的指针数组 { IloEnv env; IloInt nodeNum;//节点数量 IloInt columnNum;//用来生成随机数 IloInt e;//飞行范围的阈值 IloInt b;//电量容量限制 IloInt num;//卡车路段的最大卡车数量 IloNum lt;//无人机等待卡车回合的时间 IloIntArray arrivetime(env);//某一个节点的到达时间 TwoDIntMatrix t_ijT(env);//记录i到j的卡车传输时间 TwoDIntMatrix t_ijD(env);//记录i到j的无人机传输时间 IloNum trunktotaltime, dronetotaltime; const char* filename = "未来往里添加的文件名"; if (argc > 1) filename = argv[1];//如果命令行参数大于1,则将第二个参数赋值给文件名 ifstream file(filename); if (!file) { cerr << "ERROR: could not open file '" << filename << "' for reading" << endl; cerr << "usage: " << argv[0] << " <file>" << endl; throw(-1); } file >> nodeNum >> columnNum >> e >> b >> num >> lt >> arrivetime >> t_ijT >> t_ijD >> trunktotaltime >> dronetotaltime; const int M = 99999999; try { TwoDNumVars onbattery(env, nodeNum);//记录i到j去时的电池容量消耗 TwoDNumVars offbattery(env, nodeNum);//记录i到j回来时的电池容量消耗; for (IloInt i = 0; i < nodeNum; i++) { onbattery[i] = IloNumVarArray(env, nodeNum, 0, (columnNum - 1) * 10); } for (IloInt i = 0; i < nodeNum; i++) { offbattery[i] = IloNumVarArray(env, nodeNum, 0, (columnNum - 1) * 10); } IloNumVarArray starttime(env, nodeNum + 1); IloNumVarArray completetime(env, nodeNum + 1); IloModel model(env);//创建一个名为model的数学规划模型对象,该对象用于存储整个数学规划模型的定义 IloExpr finishTime(env);//声明表达式对象,表示完成的时间 finishTime = IloMax(completetime);//在交汇点,完成时间等于最后一个分支的完成时间 IloObjective obj = IloMinimize(env, finishTime);//在TSP-D中,我们希望最小化最大完成时间。 model.add(obj);//添加约束到模型中 TwoDIntVars x_ijT(env, nodeNum + 1); TwoDIntVars x_ijD(env, nodeNum + 1); for (IloInt i = 1; i < nodeNum + 1; i++) { x_ijT[i] = IloIntVarArray(env, nodeNum + 1, 0, 1); // 取值范围限制为0或1 x_ijD[i] = IloIntVarArray(env, nodeNum + 1, 0, 1); // 取值范围限制为0或1 } for (IloInt i = 1; i < nodeNum + 1; i++)//保证剩余燃料时间足够 { for (IloInt j = i + 1; j < nodeNum + 1; j++) { model.add(arrivetime[i] + t_ijT[i][j] <= arrivetime[j] + M * (1 - x_ijT[i][j])); model.add(arrivetime[i] + t_ijD[i][j] <= arrivetime[j] + M * (1 - x_ijD[i][j])); } } IloIntArray y_T(env, nodeNum, 0, 1);//卡车结点 IloIntArray y_D(env, nodeNum, 0, 1);//无人机结点 IloIntArray y_C(env, nodeNum, 0, 1);//结合结点 TwoDNumVars z_ij(env);//如果i到j有环则为1没有环则为0 for (IloInt i = 0; i < nodeNum + 1; i++) { z_ij[i] = IloNumVarArray(env, nodeNum, 0, 1, ILOINT); } IloExprArray temp(env, nodeNum + 1); for (IloInt i = 0; i < nodeNum + 1; i++) { temp[i] = IloExpr(env); temp[i] += y_T[i] + y_D[i] + y_C[i]; for (IloInt j = 0; j < nodeNum; j++) { temp[i] += z_ij[i][j]; } model.add(temp[i] == 1);//增加限制条件:i点至少是这4个类型中的一个,要么卡车访问,要么无人机访问,要么作为汇合点,要么被当做环路访问 } //下面考虑无人机飞行范围 IloExpr sum(env); for (IloInt i = 0; i < nodeNum + 1; i++) { sum = 0; for (IloInt j = 0; j < nodeNum; j++) { sum += (x_ijD[i][j] * t_ijD[i][j] + x_ijD[j][i] * t_ijD[j][i] + (x_ijD[i][j] + x_ijD[j][i]) * z_ij[i][j]); } model.add(sum <= e + M * (1 - y_D[i]));//只有无人机点才需要考虑 } //考虑无人机电池容量 for (IloInt i = 0; i < nodeNum + 1; i++) { sum = 0; for (IloInt j = 0; j < nodeNum; j++) { sum += (x_ijD[i][j] * onbattery[i][j] + x_ijD[j][i] * offbattery[j][i] + (onbattery[i][j] + offbattery[j][i]) * z_ij[i][j]); } model.add(sum <= b + M * (1 - y_D[i]));//只有无人机点才需要考虑 } //交汇点时间限制(无人机到达交汇点后需要在空中斡旋,此时同样消耗电量,所以有最长的等待时间限制,j->i->k) for (IloInt j = 0; j < nodeNum + 1; j++) { for (IloInt i = 0; i < nodeNum + 1; i++) { for (IloInt k = 0; k < nodeNum + 1; k++) { model.add((arrivetime[k] - arrivetime[j]) <= e + M * (2 - x_ijD[j][i] - x_ijD[i][k]) + M * (1 - y_D[i]));//确保j到i及i到k是无人机路径且中间是无人机节点 } } } //下面考虑发起与交汇时间。 IloIntArray l(env, nodeNum, 0, 1);//值为1当客户是无人机客户且无人机不是从仓库起飞而是途中再次起飞的 for (int i = 0; i < nodeNum + 1; i++) { model.add(l[i] >= y_D[i] - x_ijD[0][i]);//确保x_ijD[0][j]为零,在y_D[i]为1的时候l[i]等于1,y_D[i]为0的时候l[i]为0 } //我们要考虑每次无人机中途加油到再次起飞之间需要的时间startTime[i]-arriveTime[i],以及每次无人机到达汇合点之后等待卡车的时间lt。 //我们要保证卡车无人机能运行的时间长于总的时间(环路上两点之间的时间,发起时间和交汇时间,以及对于每个无人点的启动时间和交汇时间) IloExpr sum2(env); for (IloInt i = 0; i < nodeNum + 1; i++) { for (IloInt j = 0; j < nodeNum + 1; j++) { sum2 += (t_ijD[i][j] + t_ijD[j][i] + starttime[i] -arrivetime[i] + lt) * z_ij[i][j]; } sum2 += l[i] * (starttime[i] - arrivetime[i]) + y_D[i] * lt;//加上中途起飞无人机的启动时间和无人机会和时间 } model.add(trunktotaltime >= (arrivetime[0] + sum2)); model.add(dronetotaltime >= (arrivetime[0] + sum2)); env.out() << endl; //我们这里讨论卡车路段的最多卡车数量。假设卡车路段最多num个卡车,当num>2时我们用v[i]代表卡车访问的客户数量 IloIntArray v(env, nodeNum + 1); for (IloInt i = 0; i < nodeNum + 1; i++) { if (num == 0) { model.add(y_T[i] == 0); } else if (num == 1) { for (IloInt j = 0; j < nodeNum + 1; j++) { model.add(x_ijD[i][j] + x_ijD[j][i] <= y_C[i] + y_C[j]); } } else { model.add(y_T[i] <= v[i] <= num * y_T[i]); for (IloInt j = 0; j < nodeNum + 1; j++) { model.add(v[i] + 1 <= v[j] + (num - 1) * (2 - x_ijT[i][j] - y_T[j])); } } } } catch (IloException& ex) { cerr << "Error: " << ex << endl; } catch (...) { cerr << "Error" << endl; } env.end(); return 0; }帮我改错
07-17
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值