线性规划如果/然后修改成本函数



我正在使用CPLEX建立一个线性规划优化模型,我想知道是否有可能根据任意解决方案中哪些二进制决策变量是"活动的"来完成成本函数的修改。这主要是一个关于如何制定LP模型的问题(如果可能的话(,但CPLEX背景下的回答是受欢迎的,甚至是首选的。

假设我有一个规范形式的LP问题:

minimize cTx
s.t. Ax <= b

带成本函数:

c = [c_1, c_2,...,c_100]

所有变量都是二进制的。我在CPLEX中对这个基本设置进行了建模并有效运行。

现在假设我有一个子集的变量:

efficiency_set = [x_1, x_2,...,x_5]

条件:

if any x_n in efficiency_set == 1
then c_n for all other x_n in the set = 0.9 * c_n

本质上存在一个依赖关系,如果效率集中的任何x_n是"活动的",则该集中的其他变量出现在解决方案中的成本会降低10%。

我认为CPLEX指标约束是我想要的,但在阅读了文档后,我认为我无法用它们来强制执行成本函数的动态更改(我可能错了(。所以我觉得这需要通过LP的制定来完成,但我无法推理如何完成。有什么想法吗?。谢谢

在CPLEX中,您有许多API,让我用最简单的一个OPL.来回答您

你的规范形式可以写成

int n=3;
int m=4;
range N=1..n;
range M=1..m;
float A[N][M]=[[1,4,9,6],[8,5,0,8],[2,9,0,2]];
float B[M]=[3,1,3,0];
float C[N]=[1,1,1];
dvar boolean x[N];
minimize sum(i in N) C[i]*x[i];
subject to
{
forall(j in M) sum(i in N) A[i,j]*x[i]>=B[j];
}

然后你可以写逻辑约束:

int n=3;
int m=4;
range N=1..n;
range M=1..m;
float A[N][M]=[[1,4,9,6],[8,5,0,8],[2,9,0,2]];
float B[M]=[3,1,3,0];
float C[N]=[1,1,1];
{int} efficiencySet={1,2};

dvar boolean activeEfficiencySet;
dvar boolean x[N];
minimize sum(i in N) C[i]*x[i]*(1-0.1*activeEfficiencySet*(i not in efficiencySet));
subject to
{
forall(j in M) sum(i in N) A[i,j]*x[i]>=B[j];

activeEfficiencySet==(1<=sum(i in efficiencySet) x[i]);
}

使用Alex的数据,我在docplex(cplex python API(中编写了程序

from docplex.mp.model import Model
n = 3
m = 4

A = {}
A[0, 0] = 1
A[0, 1] = 4
A[0, 2] = 9
A[0, 3] = 6
A[1, 0] = 8
A[1, 1] = 5
A[1, 2] = 0
A[1, 3] = 8
A[2, 0] = 2
A[2, 1] = 9
A[2, 2] = 0
A[2, 3] = 2
B = {}
B[0] = 3
B[1] = 1
B[2] = 3
B[3] = 0
C = {}
C[0] = 1
C[1] = 1
C[2] = 1
efficiencySet = [0, 1]
mdl = Model(name="")
activeEfficiencySet = mdl.binary_var()
x = mdl.binary_var_dict(range(n), name="x")
# constraint 1:
for j in range(m):
mdl.add_constraint(mdl.sum(A[i, j] * x[i] for i in range(n)) >= B[j])
# constraint 2:
mdl.add(activeEfficiencySet == (mdl.sum(x) >= 1))
# objective function:
# expr = mdl.linear_expr()
lst = []
for i in range(n):
if i not in efficiencySet:
lst.append((C[i] * x[i] * (1 - 0.1 * activeEfficiencySet)))
else:
lst.append(C[i] * x[i])
mdl.minimize(mdl.sum(lst))
mdl.solve()
for i in range(n):
print(str(x[i]) + " : " + str(x[i].solution_value))
activeEfficiencySet.solution_value

最新更新