我有一个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)
非常感谢您的帮助!
答案 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)