问题介绍
有五个地点需要派员工作,拟在五个地点中选择若干个地点建立办公室,从办公室到工作地点的旅行根据远近不同有不同的耗费,在各地建立办公室的一次性花费也不同。已知各地的派员需求量,规划在何处建址以及各办公室到不同地点的派员数量,以使得总花费最小。数据如下:
数学模型
leapms介绍
使用Java+cplex求解问题前,先介绍一种全新且高效的建模工具——Leapms。
Leapms 是一个用于求解整数规划的免费建模语言,具备简洁的建模过程。Leapms 语言设计的原则包括:(1)采用描述性语言形式;(2)尽力与模型的数学表达形式一致。leapms软件应用网站:https://www.cnblogs.com/leapms/
语言开发者:陆教授(yplu@bjtu.edu.cn)
数据定义
// 数据参数定义
class DataLocation{
// 派员需求
double[] Audits={200,100,300,100,200};
// 固定成本
double[] fixedCost={160,49,246,86,100};
// 旅行成本
double[][] travelCost={
{0,0.4, 0.8, 0.4, 0.8},
{0.7, 0, 0.8, 0.4, 0.4},
{0.6, 0.4, 0, 0.5, 0.4},
{0.6, 0.4, 0.9, 0, 0.4},
{0.9, 0.4, 0.7, 0.4, 0},
};
// 节点数量
int nodeNumber=Audits.length;
}
问题建模
public class LocationDemo {
// 定义数据
DataLocation data;
public LocationDemo(DataLocation data){
this.data=data;
}
// 定义cplex内部对象
IloCplex model;
// 定义变量
public IloNumVar[] y;
public IloNumVar[][] x;
// 求解函数
public void solve() throws IloException {
if(model.solve()==false){
// 模型不可解
System.out.println("模型不可解");
return;
}
else{
System.out.println("目标值:"+model.getObjValue());
System.out.println("=========选择变量===========");
for(int i=0;i<data.nodeNumber;i++){
if(model.getValue(y[i])!=0) {
System.out.println("变量值y[" + (i + 1) + "]:" + model.getValue(y[i]));
}
}
System.out.println("=========分配关系===========");
for(int i=0;i<data.nodeNumber;i++){
for(int j=0;j<data.nodeNumber;j++) {
if (model.getValue(x[i][j]) != 0) {
System.out.println("变量值x[" + (i + 1) + "]["+(j+1)+"]:" + model.getValue(x[i][j]));
}
}
}
}
}
// 根据数学模型建立求解模型
public void BuildModel() throws IloException{
// model
model = new IloCplex();
model.setOut(null);
// variables
y = new IloNumVar[data.nodeNumber];
x = new IloNumVar[data.nodeNumber][data.nodeNumber];
// 定义cplex变量x和y的数据类型及取值范围
for(int i=0;i<data.nodeNumber;i++){
y[i]=model.numVar(0,1, IloNumVarType.Int,"y["+i+"]");
}
for(int i=0;i<data.nodeNumber;i++){
for(int j=0;j<data.nodeNumber;j++) {
x[i][j] = model.numVar(0, 1, IloNumVarType.Int, "x[" + i + "]["+j+"]");
}
}
// 设置目标函数
IloNumExpr obj = model.numExpr();
for(int i=0;i<data.nodeNumber;i++){
for(int j=0;j<data.nodeNumber;j++) {
double odjTem=data.Audits[j]*data.travelCost[i][j];
obj = model.sum(obj, model.prod(odjTem,x[i][j]));
}
}
for(int i=0;i<data.nodeNumber;i++){
obj = model.sum(obj, model.prod(data.fixedCost[i],y[i]));
}
model.addMinimize(obj);
// 添加约束1
for(int j=0;j<data.nodeNumber;j++) {
IloNumExpr expr1 = model.numExpr();
for (int i = 0; i < data.nodeNumber; i++) {
expr1 = model.sum(expr1, x[i][j]);
}
model.addEq(expr1,1);
}
// 添加约束2
for(int i=0;i<data.nodeNumber;i++) {
IloNumExpr expr2 = model.numExpr();
for(int j=0;j<data.nodeNumber;j++){
expr2=model.sum(expr2,x[i][j]);
}
model.addLe(expr2,model.prod(1e5,y[i]));
}
}
问题求解
public static void main(String[] args)throws IloException{
DataLocation data =new DataLocation();
LocationDemo lp=new LocationDemo(data);
lp.BuildModel();
lp.solve();
}
求解结果
问题来源:[1] Rardin R. L 著,肖勇波、梁湧译. 运筹学. 北京:机械工业出版社,2018
=======================================
今天到此为止,后续记录其他cplex技术的学习过程。
以上学习笔记,如有侵犯,请立即联系并删除!