Pyomo KeyError:“访问索引组件时出错:索引'('student_5','company_3','meetingtime_1')'对数组组件'var_X'无效”

时间:2018-07-08 16:26:19

标签: python mathematical-optimization pyomo

我有一个Pyomo模型,旨在最大程度地提高学生与公司之间会议的拟合度。我将3维变量用于学生-公司-会议时间组合。 我是使用pyomo的初学者,并且在Excel中与SolverStudio一起使用。 只要列出了model.var_X范围内的所有可能组合,模型就可以正常工作。如果未列出所有可能的组合,则会出现以下错误消息:

  

错误:为带有索引('company_3','meetingtime_1')的约束company_meetingtime_capa_constraint生成表达式时,规则失败:       KeyError:“访问索引组件时出错:索引'('student_5','company_3','meetingtime_1')'对数组组件'var_X'无效”

我不想包含所有可能的组合,因为该数字太大而无法用excel处理,而且并非所有组合都是可行的。

有没有一种方法可以不列出所有组合并且仍然无法解决?

from pyomo.environ import * # For Pyomo 4.0 & later

model = AbstractModel()

## Define sets
model.idx_students = Set()
model.idx_companies = Set()
model.idx_meetingtimes = Set()
model.idx_s_c = Set(within=model.idx_students*model.idx_companies)
model.idx_s_m = Set(within=model.idx_students*model.idx_meetingtimes)
model.idx_c_m = Set(within=model.idx_companies*model.idx_meetingtimes)
model.idx_s_c_m =      
    Set(within=model.idx_students*model.idx_companies*model.idx_meetingtimes)

## Define parameters
model.prm_studentsMin = Param(model.idx_students) 
model.prm_studentsMax = Param(model.idx_students)
model.prm_company_meetingtime_capa = Param(model.idx_c_m, default=0)
model.prm_student_meetingtime = Param(model.idx_s_m, within=Binary, 
    default=0) 
model.prm_fit = Param(model.idx_s_c, default=0)
model.prm_s_c_m_locked = Param(model.idx_s_c_m, within=Binary, default=0)

## Define variables
model.var_X = Var(model.idx_s_c_m, within=Binary)

## Define objective function
def maxFit(model):
    return sum(model.var_X[n]*model.prm_fit[m]
        for (n) in model.idx_s_c_m
        for (m) in model.idx_s_c)
model.SolverResults = Objective(rule=maxFit, sense=maximize)

## Capacity for companies during meeting-times
def company_meetingtime_capa_rule(model,c,m):
    return sum(model.var_X[s,c,m] for s in model.idx_students) <=     
        model.prm_company_meetingtime_capa[c,m]
model.company_meetingtime_capa_constraint = Constraint(model.idx_c_m, rule = 
company_meetingtime_capa_rule)

## Number of meetings for students and companies
def TerminstudentscompaniesRule(model, s, c):
    return sum(model.var_X[s,c,m] for m in model.idx_meetingtimes) <= 1
model.TerminstudentscompaniesConstraint = Constraint(model.idx_s_c,     
    rule=TerminstudentscompaniesRule)

## meetingtime availability of students
def studentsmeetingtimeRule(model, s,m):
    return sum(model.var_X[s,c,m] for c in model.idx_companies) <=     
        model.prm_student_meetingtime[s,m]
model.studentsmeetingtimeConstraint = Constraint(model.idx_s_m,     
    rule=studentsmeetingtimeRule)

## locked meetings
def lockedeTermineRule(model, s,c,m):
    return (model.var_X[s,c,m]) >= model.prm_s_c_m_locked[s,c,m]
model.lockedeTermineConstraint = Constraint(model.idx_s_c_m,     
    rule=lockedeTermineRule)

## Min number of meetings for students
def minTerminestudentsRule(model,s):
    return sum(model.var_X[s,c,m] for c in model.idx_companies for m in     
        model.idx_meetingtimes) >= model.prm_studentsMin[s]
model.minTerminestudentsConstraint = Constraint(model.idx_students,     
    rule=minTerminestudentsRule)

## Max number of meeting for students
def maxTerminestudentsRule(model,s):
    return sum(model.var_X[s,c,m] for c in model.idx_companies for m in 
        model.idx_meetingtimes) <= model.prm_studentsMax[s]
model.maxTerminestudentsConstraint = Constraint(model.idx_students,     
    rule=maxTerminestudentsRule)

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

最简单的解决方案是将Var中确实存在的变量加起来,例如:

model.var_X = Var(model.idx_s_c_m, within=Binary)

## Capacity for companies during meeting-times
def company_meetingtime_capa_rule(model,c,m):
    return sum(model.var_X[s,c,m] for s in model.idx_students
        if (s,c,m) in model.idx_s_c_m) \
        <= model.prm_company_meetingtime_capa[c,m]
model.company_meetingtime_capa_constraint = Constraint(
    model.idx_c_m, rule = company_meetingtime_capa_rule)