微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Google OR-工具-查找最佳的小组作业

如何解决Google 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。

请注意,这些变量包含一个变量数组,因此您需要根据自己的情况创建中间变量。

请参见this doc

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。