[英]Conditionals on Pulp variables
我正在嘗試使用 Pulp 解決教授/班級分配問題。 下面是我的代碼的一個簡化示例。 在示例中,每年有 12 個不同的科目('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),並且比涉及的 Maths_1_A、Maths_2_A、Physics_1_B、Chemistry_3_A 更好4 個不同的科目(Maths_1、Maths_2、Physics_1、Chemistry_3)。 我嘗試通過定義一個目標 function 來做到這一點,該目標是教授分配的不同科目數量的總和。
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)
我遇到的問題是定義目標 function。我只能根據紙漿變量賦值的條件來思考:
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
問題是:我怎樣才能制定一個目標 function 來計算分配給教授的不同科目數量?
我認為通過為主要賦值變量保留一個由 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
要對特定assign_subj
subj
必須設置為 1。然后您可以計算這些或在您的目標中對它們進行任何您想做的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.