You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pyomo无法处理二次表达式:护士患者匹配模型语言匹配约束问题

护士-患者匹配算法语言匹配模块报错分析与解决

问题背景

开发护士-患者匹配算法,目标为每位患者分配唯一护士,同时最小化工作负载不均、房间距离等问题,当前需加入语言匹配激励机制。相关模块定义如下:

集合

model.PatientIDs = {0, 1, 2}
model.NurseIDs = {'a', 'b'}

语言参数

# 患者语言映射
model.PATIENT_LANGUAGE = {0: 'English', 1: 'Spanish', 2: 'English'}
# 护士语言映射
model.NURSE_LANGUAGE = {'a': 'English', 'b': 'Spanish'}
# 预计算的语言匹配标识(1表示匹配,0表示不匹配)
model.LANGUAGES_MATCH = {(0, 'a'): 1, (0, 'b'): 0, (1, 'a'): 0, (1, 'b'): 1, (2, 'a'): 1, (2, 'b'): 0}

决策变量

# 分配标识:ASSIGNMENTS[p,n]=1表示患者p分配给护士n
model.ASSIGNMENTS = pe.Var(model.PatientIDs, model.NurseIDs, domain=pe.Binary)
# 语言匹配虚拟变量:DUMMY_LANGUAGE[p,n]=1表示分配的护士与患者语言匹配
model.DUMMY_LANGUAGE = pe.Var(model.PatientIDs, model.NurseIDs, domain=pe.Binary)

原约束与报错

原约束试图通过乘法关联变量与参数:

def matches_language(model, patient, nurse):
    return model.DUMMY_LANGUAGE[patient, nurse] <= model.ASSIGNMENTS[patient, nurse] * model.LANGUAGES_MATCH[patient, nurse]

model.LANG_MATCH = pe.Constraint(model.PatientIDs, model.NurseIDs, rule=matches_language)

运行时触发报错:

ValueError: Solver unable to handle quadratic expressions. Constraint at issue: 'LANG_MATCH[1]'

报错原因

尽管LANGUAGES_MATCH是常数参数,但ASSIGNMENTS是二元决策变量,两者直接相乘会被Pyomo解析为二次表达式。而大多数线性规划(LP)或整数线性规划(ILP)求解器仅支持线性约束,无法处理二次项,因此抛出错误。

解决方法

将原二次约束转化为等价的线性约束,核心逻辑是:仅当患者被分配给该护士(ASSIGNMENTS[p,n]=1)且两者语言匹配(LANGUAGES_MATCH[p,n]=1)时,DUMMY_LANGUAGE[p,n]才能取1,否则必须为0。可通过以下两种方式实现:

方式1:基于参数值生成针对性线性约束

直接在约束规则中判断LANGUAGES_MATCH的值,生成对应线性约束:

def matches_language(model, patient, nurse):
    match_flag = model.LANGUAGES_MATCH[patient, nurse]
    if match_flag == 0:
        # 语言不匹配时,虚拟变量必须为0
        return model.DUMMY_LANGUAGE[patient, nurse] == 0
    else:
        # 语言匹配时,虚拟变量不能超过分配标识(仅分配时才能为1)
        return model.DUMMY_LANGUAGE[patient, nurse] <= model.ASSIGNMENTS[patient, nurse]

model.LANG_MATCH = pe.Constraint(model.PatientIDs, model.NurseIDs, rule=matches_language)

方式2:通用线性约束形式

无需判断参数值,用三个线性约束组合实现等价逻辑:

def lang_match_constraint1(model, patient, nurse):
    # 虚拟变量不能超过分配标识
    return model.DUMMY_LANGUAGE[patient, nurse] <= model.ASSIGNMENTS[patient, nurse]

def lang_match_constraint2(model, patient, nurse):
    # 虚拟变量不能超过语言匹配标识
    return model.DUMMY_LANGUAGE[patient, nurse] <= model.LANGUAGES_MATCH[patient, nurse]

def lang_match_constraint3(model, patient, nurse):
    # 当分配且语言匹配时,虚拟变量可以为1
    return model.DUMMY_LANGUAGE[patient, nurse] >= model.ASSIGNMENTS[patient, nurse] + model.LANGUAGES_MATCH[patient, nurse] - 1

model.LANG_MATCH1 = pe.Constraint(model.PatientIDs, model.NurseIDs, rule=lang_match_constraint1)
model.LANG_MATCH2 = pe.Constraint(model.PatientIDs, model.NurseIDs, rule=lang_match_constraint2)
model.LANG_MATCH3 = pe.Constraint(model.PatientIDs, model.NurseIDs, rule=lang_match_constraint3)

目标函数调整

在目标函数中加入最大化语言匹配项即可实现激励:

model.obj = pe.Objective(
    expr=sum(model.DUMMY_LANGUAGE[p,n] for p in model.PatientIDs for n in model.NurseIDs),
    sense=pe.maximize
)

内容的提问来源于stack exchange,提问作者Nurse_Patient_Optimizer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 08:33:25