问题介绍
某鞋店出售橡胶雪靴,预计未来4个月市场需求如下:
月份:1 2 3 4
需求:40 20 30 40
每次订货只有10,20,30,40,50几种批量方案,每种批量的价格分别为48,86,118,138,160元,每月库存不能超过40双,存储费用按月末计算,每双价格为0.2元。考虑到四个月后市场风险较大,希望四个月后的库存为0.这四个月如何订货,总花费最小?
问题约束
(1)每月的月末库存不能超过40
(2)第4个月的月末库存为0
(3)当月库存=上月库存+当月订货量-当月需求量
数学模型
变量s_i表示第i月的剩余库存量
变量x_i_k表示第i月是否选择第k种订货方案
leapms介绍
使用Java+cplex求解问题前,先介绍一种全新且高效的建模工具——Leapms。
Leapms 是一个用于求解整数规划的免费建模语言,具备简洁的建模过程。Leapms 语言设计的原则包括:(1)采用描述性语言形式;(2)尽力与模型的数学表达形式一致。leapms软件应用网站:https://www.cnblogs.com/leapms/
语言开发者:陆教授(yplu@bjtu.edu.cn)
该问题的Leapms解决方法见【一个多阶段库存订货问题的 +Leapms 求解要点 】
数据定义
class Data{
//批量种类
double[] batchType={10,20,30,40,50};
//批量价格
double[] batchPrice={48,86,118,138,160};
//需求量
double[] demmand={40,20,30,40};
//库存成本
double InventoryCost=0.2;
}
问题建模
// 根据数学模型建立求解模型
public void BuildModel() throws IloException{
//model
model = new IloCplex();
model.setOut(null);
//variables
s = new IloNumVar[data.demmand.length+1];
x = new IloNumVar[data.demmand.length][data.batchType.length];
//定义cplex变量x和y的数据类型及取值范围
for(int i=0;i<data.demmand.length+1;i++){
s[i]=model.numVar(0,Double.MAX_VALUE, IloNumVarType.Int,"s["+i+"]");
}
for(int i=0;i<data.demmand.length;i++){
for(int j=0;j<data.batchType.length;j++) {
x[i][j] = model.numVar(0, 1, IloNumVarType.Int, "x[" + i + "]["+j+"]");
}
}
//设置目标函数
IloNumExpr obj = model.numExpr();
//订货成本
for(int i=0;i<data.demmand.length;i++){
for(int j=0;j<data.batchType.length;j++) {
obj = model.sum(obj, model.prod(data.batchPrice[j],x[i][j]));
}
}
//库存成本
for(int i=0;i<data.demmand.length+1;i++){
obj = model.sum(obj, model.prod(data.InventoryCost,s[i]));
}
model.addMinimize(obj);
//添加约束1
for(int i=0;i<data.demmand.length;i++) {
IloNumExpr expr1 = model.numExpr();
expr1=model.sum(expr1,s[i+1-1]);
expr1=model.sum(expr1,-1*data.demmand[i]);
for(int j=0;j<data.batchType.length;j++){
expr1=model.sum(expr1,model.prod(data.batchType[j],x[i][j]));
}
model.addEq(s[i+1],expr1);
}
//添加约束2
model.addEq(s[0],0);
//添加约束3
model.addEq(s[4],0);
//添加约束4
for(int i=0;i<data.demmand.length;i++) {
model.addLe(s[i], 40);
}
System.out.println(model);
}
问题求解
//主函数
public static void main(String[] args)throws Exception {
InventoryOrderingProblemDemo lp=new InventoryOrderingProblemDemo();
lp.BuildModel();
lp.solve();
}
求解结果
完整代码
import ilog.concert.IloException;
import ilog.concert.IloNumExpr;
import ilog.concert.IloNumVar;
import ilog.concert.IloNumVarType;
import ilog.cplex.IloCplex;
public class InventoryOrderingProblemDemo{
class Data{
//批量种类
double[] batchType={10,20,30,40,50};
//批量价格
double[] batchPrice={48,86,118,138,160};
//需求量
double[] demmand={40,20,30,40};
//库存成本
double InventoryCost=0.2;
}
Data data=new Data();
//定义cplex内部对象
IloCplex model;
//定义变量
public IloNumVar[] s;
public IloNumVar[][] x;
//构造函数
public InventoryOrderingProblemDemo() {
}
//求解函数
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.demmand.length;i++){
if(model.getValue(s[i])!=0) {
System.out.println("变量值s[" + (i + 1) + "]:" + model.getValue(s[i]));
}
}
System.out.println("=========分配关系===========");
for(int i=0;i<data.demmand.length;i++){
for(int j=0;j<data.batchType.length;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
s = new IloNumVar[data.demmand.length+1];
x = new IloNumVar[data.demmand.length][data.batchType.length];
//定义cplex变量x和y的数据类型及取值范围
for(int i=0;i<data.demmand.length+1;i++){
s[i]=model.numVar(0,Double.MAX_VALUE, IloNumVarType.Int,"s["+i+"]");
}
for(int i=0;i<data.demmand.length;i++){
for(int j=0;j<data.batchType.length;j++) {
x[i][j] = model.numVar(0, 1, IloNumVarType.Int, "x[" + i + "]["+j+"]");
}
}
//设置目标函数
IloNumExpr obj = model.numExpr();
//订货成本
for(int i=0;i<data.demmand.length;i++){
for(int j=0;j<data.batchType.length;j++) {
obj = model.sum(obj, model.prod(data.batchPrice[j],x[i][j]));
}
}
//库存成本
for(int i=0;i<data.demmand.length+1;i++){
obj = model.sum(obj, model.prod(data.InventoryCost,s[i]));
}
model.addMinimize(obj);
//添加约束1
for(int i=0;i<data.demmand.length;i++) {
IloNumExpr expr1 = model.numExpr();
expr1=model.sum(expr1,s[i+1-1]);
expr1=model.sum(expr1,-1*data.demmand[i]);
for(int j=0;j<data.batchType.length;j++){
expr1=model.sum(expr1,model.prod(data.batchType[j],x[i][j]));
}
model.addEq(s[i+1],expr1);
}
//添加约束2
model.addEq(s[0],0);
//添加约束3
model.addEq(s[4],0);
//添加约束4
for(int i=0;i<data.demmand.length;i++) {
model.addLe(s[i], 40);
}
System.out.println(model);
}
//主函数
public static void main(String[] args)throws Exception {
InventoryOrderingProblemDemo lp=new InventoryOrderingProblemDemo();
lp.BuildModel();
lp.solve();
}
}
=======================================
今天到此为止,后续记录其他cplex技术的学习过程。
以上学习笔记,如有侵犯,请立即联系并删除!