c++&cplex 定义二维变量以及复杂表达式

最近在学习运筹学,因此尝试使用c++调用cplex来求解一些经典运筹学模型,也是对最近知识 的一次总结,由于某些原因,目标函数就暂不列出了。

Cplex是IBM公司的通用数学模型求解工具,通过掌握一些特定的方法,可以在c++进行傻瓜式编辑数学模型,然后进行求解。

注释已经相对详细了,直接上代码:

#include<ilcplex/ilocplex.h>

typedef IloArray<IloNumVarArray> NumVarMatrix;//声明二维变量矩阵,我要使用二维变量了。

ILOSTLBEGIN

using namespace std;

int main(){

    IloEnv  env;//定义环境
    IloInt n,m;//定义n行m列二维变量,var_jk
	IloModel model(env);//定义模型
	NumVarMatrix var(env, n);//定义n行一维变量,var_j即为j行一维变量
	IloRangeArray con(env);//定义约束条件组
	IloObjective obj;//定义目标值

    for (int j = 0; j < n; j++) {
		var[j] = IloNumVarArray(env, m, 0, 1, ILOBOOL);//定义n列,整型二维变量var[j][k]
	}
    for (int j = 0; j < n; j++) {//此处我们将添加约束条件,以及复杂的约束条件表达式
		con.add(IloRange(env, 1.0, 1.0));//约束条件j:空==1
		
        IloNumExpr expr(env);//定义表达式
		for (int k = 0; k < m + 1; k++) {//循环,将每个变量写入表达式,即sum(yjk)==1;
			expr += var[j][k];

            //给变量起个名吧:
			string s = "y" + to_string(j + 1) + to_string(k);
			const char* ss = s.c_str();

			var[j][k].setName(ss);//命名
		}
        //将表达式放到约束条件j的“空”位置。
		con[j].setExpr(expr);
	}
    //还可以再加一条约束:

    con.add(IloRange(env, 0, m));// 0<= c<=m
	IloExpr expr2(env);//写复杂表达式
	for (int j = 0; j < wta.n; j++) {
		for (int k = 0; k < wta.m + 1; k++) {
			expr2 += var[j][k];
		}
	}
	con[n].setExpr(expr2);//写入表达式给n约束。

    //同样,obj也支持写入复杂表达式。
    IloExpr expr3(env);
    obj=IloMinimize(env,expr3)//极小值

    //将模型、目标函数加入模型中
    model.add(con);
    model.add(obj);

    IloCplex cplex(model)
    cplex.solve();//求解
}

 补充定义二维表达式的方法:

IloExprArray expr(env,n);//定义n维expr空句柄,仅有空句柄没有实际值,想要使用还需要赋值。
for (int i = 0; i < n; i++) {
	expr[i] = IloExpr(env);//给句柄赋值,索引至第n个表达式。
}

补充逻辑判断(可以实现根据变量不同取值有不同的表达式):

IloExpr expr(env);
//使用()表达判断
expr +=(var[i][j]==1)*cost[0]+(var[i][j]>=2)*(1+cost[1]*(var[i][j]-1))//分段函数

补充修改变量、目标函数和约束的方法

#使用如下添加方法:
IloObjective obj= IloAdd(model, IloMinimize(env, e1, "obj1"));
#多目标添加方法:
IloObjective obj=IloAdd(model, IloMinimize(env, IloStaticLex(env, e1, e2), "obj1"))
#调用remove方法移除并重新添加即可。
model.remove(var);
model.remove(obj);
model.remove(con);

补充一下,Cplex的所有类都可以使用iloarray<object>来表示索引一组对象,就是数组,并且可以循环套iloarray<iloarray<object>>。

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值