Pulp 变量的条件
Conditionals on Pulp variables
我正在尝试使用 Pulp 解决 professor/class 分配问题。下面是我的代码的一个简化示例。在示例中,有 12 个不同的 subjects/year('Maths_1',代表数学第一年)被分配给 3 个不同的组(A、B、C)。共有 36 类 分配给 9 位教授(每人 4 类)。我想尽量减少教授必须教授的不同科目的数量。这是:一个教授要上4节课,那么,比如说,
Maths_1_A、Maths_1_B、Maths_1_C & Programming_1A 仅涉及两个不同的主题(Maths_1 和 Programming_1)
并且比涉及 4 个不同主题的 Maths_1_A、Maths_2_A、Physics_1_B、Chemistry_3_A 更好的选择(Maths_1、Maths_2、Physics_1, Chemistry_3).我尝试通过定义一个 objective 函数来做到这一点,该函数是分配给教授的不同科目数量的总和。
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)
我遇到的问题是定义 objective 函数。我只能根据纸浆变量赋值的条件来思考:
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
问题是:如何制作一个 objective 函数来计算分配给教授的不同科目数量?
我认为通过为主要赋值变量保留一个由 3 个部分组成的索引会让生活变得更轻松:
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。然后您可以计算这些或做任何您想要的事情想和他们一起在你的 objective.
我正在尝试使用 Pulp 解决 professor/class 分配问题。下面是我的代码的一个简化示例。在示例中,有 12 个不同的 subjects/year('Maths_1',代表数学第一年)被分配给 3 个不同的组(A、B、C)。共有 36 类 分配给 9 位教授(每人 4 类)。我想尽量减少教授必须教授的不同科目的数量。这是:一个教授要上4节课,那么,比如说, Maths_1_A、Maths_1_B、Maths_1_C & Programming_1A 仅涉及两个不同的主题(Maths_1 和 Programming_1) 并且比涉及 4 个不同主题的 Maths_1_A、Maths_2_A、Physics_1_B、Chemistry_3_A 更好的选择(Maths_1、Maths_2、Physics_1, Chemistry_3).我尝试通过定义一个 objective 函数来做到这一点,该函数是分配给教授的不同科目数量的总和。
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)
我遇到的问题是定义 objective 函数。我只能根据纸浆变量赋值的条件来思考:
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
问题是:如何制作一个 objective 函数来计算分配给教授的不同科目数量?
我认为通过为主要赋值变量保留一个由 3 个部分组成的索引会让生活变得更轻松:
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。然后您可以计算这些或做任何您想要的事情想和他们一起在你的 objective.