我正试图用Pulp解决一个教授/班级助理的问题。下面是我的代码的简化示例。在本例中,每年有12门不同的科目("数学_1",代表数学一年级(被分为3个不同的组(A、B、C(。共有36个班将被分配给9名教授(每个班4个(。我想尽量减少教授必须教授的不同科目的数量。这是:一位教授必须被分配4门课,例如,数学_1_A、数学_1_B、数学1_C&Programming_1A只涉及两个不同的科目(数学_1和Programming_1(并且是比涉及4个不同科目(数学_1、数学_2、物理_1、化学_3(的数学_1_a、数学2_a、物理_1_B、化学_3_a更好的选择。我试图通过定义一个目标函数来做到这一点,该函数是教授被分配的不同科目数量的总和。
from itertools import product
import pulp
subjects=['Maths_1','Maths_2','Maths_3', 'Physics_1','Physics_2','Physics_3',
'Quemistry_1', 'Quemistry_2', 'Quemistry_3',
'Programming_1', 'Programming_2', 'Programming_3']
groups=['A','B','C']
clases=[a[0]+'_'+a[1] for a in product(subjects, groups)]
professors=['professor'+str(i) for i in range(1,10)]
number_of_clases_per_professor=4
model=pulp.LpProblem('Class assignmnet', sense=pulp.LpMaximize)
assign={(prof, clas): pulp.LpVariable('prof_%r_class_%r'%(prof, clas), cat=pulp.LpBinary)
for prof in professors
for clas in clases}
#CONSTRAINTS
# 1. Each "class" has to be assigned exactly once:
for clas in clases:
model.addConstraint(sum(assign[(prof, clas)] for prof in professors)==1)
#2. The number of classes per professor cannot exceed 4
for prof in professors:
model.addConstraint(sum(assign[(prof, clas)] for clas in clases)<=4)
我遇到的问题是在定义目标函数方面。我只能根据条件来思考纸浆变量分配:
obj=0
for prof in professors:
subjects_for_prof=[]
for subject in subjects:
for group in groups:
clas=subject+'_'+group
if assign[(prof, clas)]:
if subject not in subjects_for_prof:
subjects_for_prof.append(subject)
obj+=len(subjects_for_prof)
model+=obj
问题是:我如何制作一个客观函数来计算教授被分配的不同科目数量?
我认为,通过为主要赋值变量保留一个三分量索引,会让生活变得更轻松
assign={(prof, subject, group): pulp.LpVariable('prof_%r_subj_%r_grp_%r'%(prof, subj, grp), cat=pulp.LpBinary)
for prof in professors
for subj in subjects
for grp in groups}
如果你想计算教授被分配教授的不同科目的数量,那么你可以引入一组特定的二元变量:
assign_subj={(prof, subject): pulp.LpVariable('prof_%r_subj_%r'%(prof, subj), cat=pulp.LpBinary)
for prof in professors
for subj in subjects}
然后,您可以设置约束,在伪代码中,这些约束类似于:
for prof in professors:
for subj in subjects:
model += pulp.lpSum([assign[(prof, subj, grp)] for grp in groups]) <= assign_subj[(prof, subj)]*max_no_groups
在最后一组约束中,您需要将max_no_groups
设置为任何主题的最大预期组数。该约束将意味着,对于任何特定的prof
要具有对特定subj
的任何赋值,则必须将适当的assign_subj
变量设置为1。然后你可以数这些,或者在你的目标中用它们做任何你想做的事。