纸浆变量的条件

时间:2020-10-26 11:43:26

标签: python conditional-statements pulp objective-function

我正在尝试使用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,Maths_2,Physics_1,Chemistry_3)的Maths_1_A,Maths_2_A,Physics_1_B,Chemical_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)

我遇到的问题是定义目标函数。我只能根据纸浆变量assign的条件来考虑:

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

问题是:我该如何建立一个目标函数来计算教授所分配的不同科目?

1 个答案:

答案 0 :(得分:2)

我认为您可以通过为主要分配变量保留3成分索引来简化生活:

handleChange(id) {
   let updatedObj = this.state.jokesLst.map((item) => {
      if (item.id === id) {
        item.completed = !item.completed;
      }
    
      return item;
    });
    
    this.setState({
      jokesLst: updatedObj
    });
   };

如果您要计算教授分配的不同学科的数量,则可以引入一组特定的二进制变量:

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变量,然后才能将其设置为1。希望他们与您达成目标。