这里的基本困难是你有一个多目标优化问题。我认为您对三件事感兴趣,可以考虑目标或“软约束”:
- 获得相似的班级规模
- 最小化每个班级的级别数
- 如果班级中有学生,则班级中有足够多的学生。
请注意,我在 AMPL 中为此编写了一个优化模型。由于您使用的是 Python,因此您可以使用类似的 Python 优化建模语言,例如 PuLP 和 pyomo。该模型不应该太难翻译。
这是一个整数规划模型和一个数据文件,它强调目标数 1,同时保持问题(整数)线性。有了这个目标,优化问题会找到您在示例中给出的相同解决方案。希望您可以在此基础上添加其他约束和/或客观术语并获得更好的解决方案。
目标是最小化最大的班级规模。感兴趣的变量是 y[i,j]。y[i,j] for i in LEVEL, j in CLASS 是从级别 i 分配到班级 j 的学生人数。它假定您输入了每个班级中每个级别的最少学生人数(如果有分配到该级别)。
目标函数可能不是您想要的,但它是一种尝试均衡线性班级规模的方法。我也不保证这是解决问题的最有效方法。可能有更好的自定义算法来解决这个问题,但我所要做的就是表达约束和目标,而不是编写算法。它可能足以供您使用。
使用 neos-server.org 上的求解器 Gurobi(您可以使用 lpsolve 或其他开源优化求解器),我得到了解决方案
y :=
1 1 14
1 2 9
1 3 0
2 1 6
2 2 0
2 3 18
3 1 6
3 2 16
3 3 8
;
模型:
set LEVEL ordered;
set CLASS;
param maxClassSize {CLASS};
param minLevelNumberInClass {LEVEL, CLASS};
param numInLevel {LEVEL};
var z >= 0;
var y{LEVEL, CLASS} integer, >= 0;
var x{LEVEL, CLASS} binary;
#minimize maximum class size
minimize obj:
z;
subject to allStudentsAssigned {i in LEVEL}:
sum {j in CLASS} y[i,j] = numInLevel[i];
#z is the largest of all classes sizes
subject to minMaxZ {j in CLASS}:
z >= sum {i in LEVEL} y[i,j];
subject to maxClassSizeCon {j in CLASS}:
sum {i in LEVEL} y[i,j] <= maxClassSize[j];
#xij = 1 if any students from level i are in class j
subject to defineX {i in LEVEL, j in CLASS}:
y[i,j] <= min(numInLevel[i], maxClassSize[j]) * x[i,j];
#if any students from level i are assigned to class j, then there is a minimum
#if x[i,j] = 1, y[i,j] >= minLevelNumberInClass[i,j]
subject to minLevel {i in LEVEL, j in CLASS}:
minLevelNumberInClass[i,j] * x[i,j] <= y[i,j];
您的示例的数据文件:
set LEVEL := 1 2 3;
set CLASS := 1 2 3;
param minLevelNumberInClass:
1 2 3 :=
1 6 6 6
2 6 6 6
3 6 6 6
;
param maxClassSize :=
1 77
2 77
3 77
;
param numInLevel :=
1 23
2 24
3 30
;