我目前正在研究一个线性编程问题,我们将会话分配给某些护理人员,并且约束给了我一个非线性错误。 在放置约束的代码之前,我将介绍该约束中使用的所有模型项。
model.CASE_COMBINATIONS = pe.Set(
initialize=product(
self.df_sessions["idx"].unique(),
self.df_sessions["idx"].unique(),
),
dimen=2,
)
这是 model.SESSION_ASSIGNED 和 model.TASKS 的代码:
model.SESSION_ASSIGNED = pe.Var(model.TASKS, domain=pe.Binary)
model.TASKS = pe.Set(
initialize=model.CASES * model.CAREGIVERS, dimen=2
)
model.CASE_BIGGER = pe.Param(
model.CASE_COMBINATIONS, initialize=self._generate_case_bigger()
def _generate_case_bigger(self):
case_bigger = {}
for case1, case2 in product(
self.df_sessions["idx"].unique(), self.df_sessions["idx"].unique()
):
case_bigger[(case1, case2)] = int(case1 > case2)
return case_bigger
model.COMMUTE = pe.Param(
model.CLIENT_CONNECTIONS,
initialize=self._generate_clients_commute(),
)
现在对于具有非线性问题的约束:
def commute_care(model, caregiver):
commute_expr = sum(
[
model.SESSION_ASSIGNED[case[0], caregiver] *
model.SESSION_ASSIGNED[case[1], caregiver] *
(
model.CASE_BIGGER[case[1], case[0]] *
model.COMMUTE[(model.IDX_CLIENTS[case[0]], model.IDX_CLIENTS[case[1]])] +
(1 - model.CASE_BIGGER[case[1], case[0]]) *
model.COMMUTE[(model.IDX_CLIENTS[case[1]], model.IDX_CLIENTS[case[0]])]
)
for case in model.CASE_COMBINATIONS
]
)
return model.COMMUTE_CARE[caregiver] == commute_expr
有了这个约束,我们想要计算每个护理人员的通勤时间。我们迭代不同案例的叉积,并计算每对案例是否将它们分配给同一个护理人员,如果是,我们计算它们之间的通勤时间。这些通勤时间的总和等于所有这些通勤时间的总和。 有谁知道如何将此约束转换为线性约束? 谢谢你
从代码中退一步,您可以得到以下形式的表达式:
a[i,j]*x[i]*x[j]
其中 a 是常数,x 是二元变量。这可以使用众所周知的重构来线性化:
a[i,j]*y[i,j]
y[i,j] <= x[i]
y[i,j] <= x[j]
y[i,j] >= x[i]+x[j]-1
其中 y 是一个额外的二进制变量。 (y可以放宽到0到1之间连续)。