具有 OR 逻辑的 LP / MILP 公式
LP / MILP formulation with OR logic
我正在使用 ILOG CPLEX 解决 LP/MILP 问题。
int n = ...;
range time =1..n;
dvar float+ c[time] in 0..0.3;
dvar float+ d[time] in 0..0.3;
dvar float+ x[time];
int beta[time]=...;
float pc[time]=...;
float pd[time]=...;
//Expressions
dexpr float funtion = sum(t in time) (d[t]*pd[t]-c[t]*pc[t]);
//Model
maximize function;
subject to {
x[1] == 0.5;
c[1] == 0;
d[1] == 0;
forall(t in time)
const1:
x[t] <= 1;
forall(t in time: t!=1)
const2:
(x[t] == x[t-1] + c[t] - d[t]);
forall(t in time: t!=1)
const3:
( d[t] <= 0) || (c[t] <= 0);
如您所见,我已强制 c[t] 和 d[t] 永远不会同时大于 0 "const3"。
我的问题是,这个约束如何用 LP/MILP 数学公式表示?
添加这个新变量是否足够? :
y[t]≤c[t]+d[t]
y[t]≥c[t]
y[t]≥d[t]
0≤y[t]≤M(M为c或d的最大值)
据我所知,您建议的约束将允许此设置:
c[t] = 0.1
d[t] = 0.1
y[t] = 0.2
其中c
和d
同时不为0。
我可以看到这些选项来制定您的条件而没有逻辑限制:
1) 使用仅包含 c[t]
和 d[t]
的 SOS 约束。根据 SOS 的定义,在任何可行的解决方案中,只有两者之一可以是非零的。
2) 使用 布尔值 变量 y[t]
并添加约束
c[t] <= M * y[t]
d[t] <= M * (1 - y[t])
3) 同样,使用布尔值 y[t]
,然后使用指标约束
(y[t] == 0) => (c[t] == 0);
(y[t] == 1) => (d[t] == 0);
4) 你可以只声明 c[t] * d[t] == 0
但这会使模型非线性。
在任何情况下,求解器都可能能够将您的原始公式减少到 2 或 3。因此,重新制定约束可能不会使事情变得更快,只会变得更模糊。
我正在使用 ILOG CPLEX 解决 LP/MILP 问题。
int n = ...;
range time =1..n;
dvar float+ c[time] in 0..0.3;
dvar float+ d[time] in 0..0.3;
dvar float+ x[time];
int beta[time]=...;
float pc[time]=...;
float pd[time]=...;
//Expressions
dexpr float funtion = sum(t in time) (d[t]*pd[t]-c[t]*pc[t]);
//Model
maximize function;
subject to {
x[1] == 0.5;
c[1] == 0;
d[1] == 0;
forall(t in time)
const1:
x[t] <= 1;
forall(t in time: t!=1)
const2:
(x[t] == x[t-1] + c[t] - d[t]);
forall(t in time: t!=1)
const3:
( d[t] <= 0) || (c[t] <= 0);
如您所见,我已强制 c[t] 和 d[t] 永远不会同时大于 0 "const3"。
我的问题是,这个约束如何用 LP/MILP 数学公式表示?
添加这个新变量是否足够? :
y[t]≤c[t]+d[t]
y[t]≥c[t]
y[t]≥d[t]
0≤y[t]≤M(M为c或d的最大值)
据我所知,您建议的约束将允许此设置:
c[t] = 0.1
d[t] = 0.1
y[t] = 0.2
其中c
和d
同时不为0。
我可以看到这些选项来制定您的条件而没有逻辑限制:
1) 使用仅包含 c[t]
和 d[t]
的 SOS 约束。根据 SOS 的定义,在任何可行的解决方案中,只有两者之一可以是非零的。
2) 使用 布尔值 变量 y[t]
并添加约束
c[t] <= M * y[t]
d[t] <= M * (1 - y[t])
3) 同样,使用布尔值 y[t]
,然后使用指标约束
(y[t] == 0) => (c[t] == 0);
(y[t] == 1) => (d[t] == 0);
4) 你可以只声明 c[t] * d[t] == 0
但这会使模型非线性。
在任何情况下,求解器都可能能够将您的原始公式减少到 2 或 3。因此,重新制定约束可能不会使事情变得更快,只会变得更模糊。