例子要求参考于Gurobi自带的案例Bilinear
代码如下
import gurobi.*;
/**
* @Author:superNova
* @ClassName:Bilinear
* @Description:example from gurobi itself(Bilinear)
* @Date:2022/09/03/21:24
* @Email:shiyudawei@qq.com
* @Blog:https://blog.csdn.net/shiyudawei?spm=1018.2226.3001.5343
*/
/* This example formulates and solves the following simple bilinear model :
maximize x
subject to x + y + z <= 10
x * y <= 2 ( bilinear inequality )
x * z + y * z == 1 ( bilinear equality )
x, y, z non - negative (x integral in second version )
*/
public class bilinear {
public static void main(String[] args) {
try {
//creat Model
GRBEnv grbEnv = new GRBEnv("grbenv");
GRBModel grbModel = new GRBModel(grbEnv);
//add variable
GRBVar x = grbModel.addVar(0.0,GRB.INFINITY,0,GRB.CONTINUOUS,"x");
GRBVar y = grbModel.addVar(0.0,GRB.INFINITY,0,GRB.CONTINUOUS,"y");
GRBVar z = grbModel.addVar(0.0,GRB.INFINITY,0,GRB.CONTINUOUS,"z");
GRBVar[] grbVars = {x,y,z};
//set Object
GRBLinExpr target = new GRBLinExpr();
target.addTerm(1,x);
grbModel.setObjective(target,GRB.MAXIMIZE);
//create constraints
/**
* subject to x + y + z <= 10
* x * y <= 2 ( bilinear inequality )
* x * z + y * z == 1 ( bilinear equality )
* x, y, z non - negative (x integral in second version )
*/
GRBLinExpr expr1 = new GRBLinExpr();
expr1.addTerms(new double[]{1, 1, 1},grbVars);
grbModel.addConstr(expr1,GRB.LESS_EQUAL,2,"c0");
GRBQuadExpr expr2 = new GRBQuadExpr();
expr2.addTerm(1,x);
expr2.addTerm(1,z);
expr2.addTerm(1,y,z);
grbModel.addQConstr(expr2,GRB.EQUAL,1,"c1");
GRBQuadExpr expr3 = new GRBQuadExpr();
//expr3.addTerms(new double[]{1,0,0},new GRBVar[]{x,z,y}, new GRBVar[]{y,y,y});
expr3.addTerm(1,x,y);
grbModel.addQConstr(expr3,GRB.LESS_EQUAL,2,"c2");
//solve obj\
try {
grbModel.optimize();
assert false;
}catch (Exception e){
System.out.println("Failed");
}
grbModel.set(GRB.IntParam.NonConvex,2);
grbModel.optimize();
System.out.println("最优解为:" + grbModel.get(GRB.DoubleAttr.ObjVal));
for (int i = 0; i < grbVars.length; i++) {
System.out.println(grbVars[i].get(GRB.StringAttr.VarName) + "=" + grbVars[i].get(GRB.DoubleAttr.X));
}
System.out.println("---------------------------------second version'result--------------------------");
//second version requirements
x.set(GRB.CharAttr.VType,GRB.INTEGER);
grbModel.optimize();
System.out.println("最优解为:" + grbModel.get(GRB.DoubleAttr.ObjVal));
for (int i = 0; i < grbVars.length; i++) {
System.out.println(grbVars[i].get(GRB.StringAttr.VarName) + "=" + grbVars[i].get(GRB.DoubleAttr.X));
}
grbModel.dispose();
grbEnv.dispose();
}catch (Exception e){
e.printStackTrace();
}
}
}
输出结果
Optimal solution found (tolerance 1.00e-04)
Best objective 1.000000000000e+00, best bound 1.000000000000e+00, gap 0.0000%
最优解为:1.0
x=1.0
y=0.0
z=0.0
几点注意
第一
这不是线性的问题,而是非线性的,所以在语法上,有一些区别,主要体现在:
GRBQuadExpr expr2 = new GRBQuadExpr();
expr2.addTerm(1,y,z);
grbModel.addQConstr();
第二
非线性问题会有下面的问题出现
Quadratic equality constraints are non-convex. Set NonConvex parameter to 2 to solve model
所以我们需要设置NonConvex参数为2 ,即
grbModel.set(GRB.IntParam.NonConvex,2);