我正在使用CPLEX解决MILP卡车调度问题,并且发现了两个我无法解决的问题。
首先,我尝试将具有多个索引的变量用作
int p=...; //plant index
int r=...; //request index
int k=...; //truck index
int t=...; //concrete type index
range plant = 1..p;
range request = 1..r;
range truck = 1..k;
int m=...;
int j=...;
range deliveries = 1..m; //total number of delivery each customer
range jobs = 1..j; //total jobs in a day each truck
dvar boolean x[plant][request][deliveries][truck][jobs]
,但索引交付(m)和作业(j)分别是请求(r)和卡车(k)的子集。最大交付数量“ m”取决于请求的需求,最大工作数量取决于旅行时间。然后,它根据要求和卡车进行了更换。
第二,通过计算获得的“ m”和“ j”值:
m [r] =舍入(max {Q [r] [t]} / min {C [k]})
j [k] =汇总(工作日的长度/每辆卡车的最小任务长度[k])
对于我当前尝试使用的代码“ m”,但由于无法应用索引而无法正常工作(第一个问题):
float maxQ = maxl(demand[r][t]);
float minC = minl(capacity[k]);
int m = ftoi(ceil(maxQ/minC));
range deliveries = 1..m;
但是对于“每辆卡车的最小任务长度”计算,它是从模型运行后计算出的行驶时间约束中获得的,我应该输入“ j”值作为常数,然后在模型运行时对其进行更新吗?还是可以通过其他方式完成?预先谢谢你。
PS。对不起,我的英语不好。
答案 0 :(得分:0)
您可以使用元组集代替完整的欧几里德乘积。
请参阅IDE和OPL>优化编程语言(OPL)>语言用户手册> OPL简介>建模技巧>稀疏性
在CPLEX文档中
对于第二个问题,让我分享一个小例子:
range R=1..3;
range T=1..2;
range K=1..4;
float demand[r in R][t in T]=1+r*t;
float capacity[k in K]=k;
float maxQ = max(r in R,t in T)(demand[r][t]);
float minC = min(k in K)(1/capacity[k]);
int m = ftoi(ceil(maxQ/minC));
range deliveries = 1..m;
execute
{
writeln(deliveries);
}
给出
1..28