CPLEX/OPL 模型 - 具有子集索引的约束
CPLEX/OPL model - constraints with subset index
我目前正在使用 IBM ILOG CPLEX Optimization Studio 对 CPLEX/OPL 模型进行编程。
我在使用包含子集并依赖于另一个 parameter/variable 的总和或索引时遇到问题,例如检查以下约束:NB 2,3,4,8).
任何人都可以帮助我正确地合并这些约束吗?
请查找附件中的源代码:
//Parameter
int maxblock=...; //number of blocks (I)
int maxprodfam=...; //number of product families (J)
int maxprod=...; //number of products (P)
int maxdemand=...; //number of demand elements (K)
range blocks=1..maxblock;
range prodfam=1..maxprodfam;
range products=1..maxprod;
range demandelements=1..maxdemand;
int startalpha[blocks]=...; //earliest start time of block i
int endalpha[blocks]=...; //latest completion time of block i
int prodtime[products]=...; //unit production time for product p (a)
int minorsetup[products]=...; //minor setup time per sub-lot of product p (s)
int majorsetup[prodfam]=...; //major setup time for product family j (S)
int demand[products]=...; //demand elements (d)
//Variablen
dvar int+ x[blocks][demandelements]; //quantity of demand element k satisfied from production in block i (x)
dvar boolean y[blocks][prodfam]; //product family assessment to blocks (y)
dvar boolean q[blocks][products]; //product assessment to blocks
dvar boolean o[blocks]; //activation of blocks (e.g. if a prodfam is assignes to it)
dvar int+ alpha[blocks]; //start time block
dvar int+ duration[blocks]; //duration of block
//Modell
minimize
alpha[maxblock]+duration[maxblock]; //objective function (minimize the makespan)
subject to {
forall(i in blocks)
NB1: //one product family assigned to each block
sum(j in prodfam)
y[i][j]==o[i];
forall(i in blocks, j in prodfam)
NB2: //production sub-lots
sum(p in products(j))q[i][p]<=y[i][j]*abs(products(j));
forall(i in blocks, k in demandelements(i))
NB3: //product flow from block i into demand element k
x[i][k]<=demand[k]*q[i][p(k)];
forall(i in blocks)
NB4: //block schedule
duration[i]==sum(j in prodfam)majorsetup[j]*y[i][j]
+sum(p in products)minorsetup[p]*q[i][p]
+sum(k in demandelements(i))alpha[p(k)]*x[i][k];
forall(i in 2..maxblock)
NB5: //block starts when other block finished
alpha[i]>=alpha[i-1]+duration[i-1];
forall(i in blocks)
NB6: //time window earliest start
alpha[i]>=startalpha[i]*o[i];
forall(i in blocks)
NB7: //time window latest completion
alpha[i]+duration[i]<=endalpha[i];
forall(k in demandelements)
NB8: //matching output and demand
sum(i in blocks(k))x[i][k]==demand[k];
}
不清楚你的问题是什么,但我猜你的问题是与约束 2 中的 products(j) 之类的东西建模有关。尝试对这些使用集合 - 所以在中创建一组产品集合每个产品系列。作为安装的一部分提供的 OPL 示例中有这方面的示例。例如,在 examples\opl\models\AssemblySequencing\Sequence 模型中我们有
{string} computer[AllComputers] = ...;
所以你可以做类似的事情,例如
{int} productsInFamily[prodfam] = ...;
编辑:使用新结构...尝试类似的方法:
forall(i in blocks, j in prodfam)
NB2: //production sub-lots
sum(p in productsInFamily[j])q[i][p]<=y[i][j]*abs(products(j));
还有许多其他方法可以实现这种数据结构,有些可能更有效,有些可能从业务角度来看更有意义。我个人喜欢处理事物集合,尤其是元组集合。了解数据结构类型以及如何在 OPL 中组合它们,因为拥有正确的数据结构总是有助于您的建模。
我目前正在使用 IBM ILOG CPLEX Optimization Studio 对 CPLEX/OPL 模型进行编程。 我在使用包含子集并依赖于另一个 parameter/variable 的总和或索引时遇到问题,例如检查以下约束:NB 2,3,4,8).
任何人都可以帮助我正确地合并这些约束吗?
请查找附件中的源代码:
//Parameter
int maxblock=...; //number of blocks (I)
int maxprodfam=...; //number of product families (J)
int maxprod=...; //number of products (P)
int maxdemand=...; //number of demand elements (K)
range blocks=1..maxblock;
range prodfam=1..maxprodfam;
range products=1..maxprod;
range demandelements=1..maxdemand;
int startalpha[blocks]=...; //earliest start time of block i
int endalpha[blocks]=...; //latest completion time of block i
int prodtime[products]=...; //unit production time for product p (a)
int minorsetup[products]=...; //minor setup time per sub-lot of product p (s)
int majorsetup[prodfam]=...; //major setup time for product family j (S)
int demand[products]=...; //demand elements (d)
//Variablen
dvar int+ x[blocks][demandelements]; //quantity of demand element k satisfied from production in block i (x)
dvar boolean y[blocks][prodfam]; //product family assessment to blocks (y)
dvar boolean q[blocks][products]; //product assessment to blocks
dvar boolean o[blocks]; //activation of blocks (e.g. if a prodfam is assignes to it)
dvar int+ alpha[blocks]; //start time block
dvar int+ duration[blocks]; //duration of block
//Modell
minimize
alpha[maxblock]+duration[maxblock]; //objective function (minimize the makespan)
subject to {
forall(i in blocks)
NB1: //one product family assigned to each block
sum(j in prodfam)
y[i][j]==o[i];
forall(i in blocks, j in prodfam)
NB2: //production sub-lots
sum(p in products(j))q[i][p]<=y[i][j]*abs(products(j));
forall(i in blocks, k in demandelements(i))
NB3: //product flow from block i into demand element k
x[i][k]<=demand[k]*q[i][p(k)];
forall(i in blocks)
NB4: //block schedule
duration[i]==sum(j in prodfam)majorsetup[j]*y[i][j]
+sum(p in products)minorsetup[p]*q[i][p]
+sum(k in demandelements(i))alpha[p(k)]*x[i][k];
forall(i in 2..maxblock)
NB5: //block starts when other block finished
alpha[i]>=alpha[i-1]+duration[i-1];
forall(i in blocks)
NB6: //time window earliest start
alpha[i]>=startalpha[i]*o[i];
forall(i in blocks)
NB7: //time window latest completion
alpha[i]+duration[i]<=endalpha[i];
forall(k in demandelements)
NB8: //matching output and demand
sum(i in blocks(k))x[i][k]==demand[k];
}
不清楚你的问题是什么,但我猜你的问题是与约束 2 中的 products(j) 之类的东西建模有关。尝试对这些使用集合 - 所以在中创建一组产品集合每个产品系列。作为安装的一部分提供的 OPL 示例中有这方面的示例。例如,在 examples\opl\models\AssemblySequencing\Sequence 模型中我们有
{string} computer[AllComputers] = ...;
所以你可以做类似的事情,例如
{int} productsInFamily[prodfam] = ...;
编辑:使用新结构...尝试类似的方法:
forall(i in blocks, j in prodfam)
NB2: //production sub-lots
sum(p in productsInFamily[j])q[i][p]<=y[i][j]*abs(products(j));
还有许多其他方法可以实现这种数据结构,有些可能更有效,有些可能从业务角度来看更有意义。我个人喜欢处理事物集合,尤其是元组集合。了解数据结构类型以及如何在 OPL 中组合它们,因为拥有正确的数据结构总是有助于您的建模。