我正在建模一个重新优化模型,我想包含一个约束,以减少初始解决方案和重新优化解决方案之间的距离。我正在安排人员安排,为此我想惩罚重新优化的解决方案中与初始解决方案不同的每个任务。
在开始之前,我是优化模型的新手,我构建约束的方式可能是错误的。
#1 Extract the data from the initial solution of my main variable
ModelX_DictExtVal = model.x.extract_values()
# 2 Create a new binary variable which activate when the main variable `ModelX_DictExtVal[x,s,d]` of the initial
#solution is =1 (an employee n works days d and sifht s) and the value of `model.x[n,s,d]` of the reoptimized solution are different.
model.alpha_distance = Var(model.N_S_D, within=Binary)
#3 Model a constraint to activate my variable.
def constraint_distance(model, n, s, d):
v = ModelX_DictExtVal[n,s,d]
if v == 1 and ModelX_DictExtVal[n,s,d] != model.x[n,s,d]:
return model.alpha_distance[n,s,d] == 1
elif v == 0:
return model.alpha_distance[n,s,d] == 0
model.constraint_distance = Constraint(model.N_S_D, rule = constraint_distance)
#4 Penalize in my objective function every time the varaible is equal to one
ObjFunction = Objective(expr = sum(model.alpha_distance[n,s,d] * WeightDistance
for n in model.N for s in model.S for d in model.D))
问题:我不确定我在第 3 部分中在做什么,并且在 v == 1
时出现索引错误。
ERROR: Rule failed when generating expression for constraint
constraint_distance with index (0, 'E', 6): ValueError: Constraint
'constraint_distance[0,E,6]': rule returned None
我想知道,因为我正在重用相同的模型进行重新优化,如果模型保持 model.x [n, s, d]
的初始解的值在重新优化阶段进行比较 ModelX_DictExtVal [n, s, d]! = model.x [n, s, d]
而不是新任务...
答案 0 :(得分:1)
你怀疑第 3 部分是对的。:)
因此,您有一些“初始值”,它们可以是原始计划(优化之前)或其他一些初步优化。如果我理解你的问题,你的决策变量是二元的,由 [n,s,d] 索引。
在您的约束条件下,您不能使用基于决策变量比较测试的 if-else 结构。在约束构建时,该变量的值未知,对吗?
不过,您走在正确的轨道上。因此,您真正想要做的是让您的 alpha_distance
(或 penalty
)变量捕获任何更改,在发生更改的地方指示 1。这是一个绝对值操作,但可以用 2 个约束来捕获。考虑(在伪代码中):
penalty = |x.new - x.old| # is what you want
因此引入 2 约束,(完全由 [n,s,d] 索引):
penalty >= x.new - x.old
penalty >= x.old - x.new
然后,就像您现在所做的那样,将 penalty
包含在您的目标中,可以选择乘以权重。
如果这没有意义,请回评论...