谷歌OR工具-找到最佳小组作业



我正在使用ortools(在Python中(将学生分配到组中。每个学生都有三种不同技能的水平。通过示例程序,我可以创建小组,并确保每个小组中至少有一名学生在每项技能上达到一定水平:

for p in all_people:
for g in all_groups:
allocation[(p,g)] = model.NewBoolVar('shift_p%ig%i' % (p,g))

# Setup Constraints
# Each person is assigned to exactly one group.
for p in all_people:
model.Add(sum(allocation[(p,g)] for g in all_groups) == 1)
# Each group has at enough people but not too many.
for g in all_groups:
model.Add(sum(allocation[(p,g)] for p in all_people) >= min_size)
model.Add(sum(allocation[(p,g)] for p in all_people) <= max_size)

# Each group has at least one person with good skills
for g in all_groups:
for s in all_skills:
model.Add(sum(skills_enough[p][s] *  allocation[(p,g)] for p in all_people  ) > 0)

这可以很好地作为约束满足问题。

我现在想做的是添加一个优化约束,试图使每组的技能水平尽可能均匀。我尝试了一些不同的配置,但无法想出一些功能性的东西:

  • 我想不出ORTools如何处理生成器中的最小值,即执行min(student_info[p][s] * allocation[(p,g)] for p in all_people)以获得g组中的最低值,因为没有min()等效于sum()
  • 我也不能将其设置为例如最小化平方和,因为添加乘法项会导致TypeError: Not an integer linear expression:。公平地说,它不再是线性的。示例代码:
model.Minimize(
sum(
sum(
(
sum(student_info[p][s] * allocation[(p,g)] for p in all_people) *
sum(student_info[p][s] * allocation[(p,g)] for p in all_people)
) for s in all_skills
) for g in all_groups
) )

优化符合线性求解器模型的组的方法与设置现有问题的方法一样有用。

对于min((和max((,需要使用AddMinEquality和AddMaxEquality。

请注意,这些需要一个变量数组,因此您需要在您的案例中创建中间变量。

请参阅此文档。

最新更新