添加一个要求数字介于上限和下限之间的约束(ortools约束优化/ CP)

问题描述 投票:1回答:1

问题的重点:“关于如何在CP模型的ortools中最适当地编码此约束的任何想法?”>


我要解决的问题有点像员工安排此处概述的任务:

https://developers.google.com/optimization/scheduling/employee_scheduling

问题

我想建立一个教室分配时间表,在一段时间内(现在,接下来的两年中每周一次)每天分配学生到教室。

我有一所有8间教室的学校。根据年龄将学生分配到教室。每个教室都有与之相关的年龄范围-例如:

  • Class 1:1-3岁
  • 第2类:2-4岁
  • [Class 3:3-5岁,等
  • 注意,教室的年龄段确实重叠。

应将学生分配到具有以下限制条件的教室:

  • 1)每个学生每天必须精确分配到一个教室
  • 2)教室中学生的总数不得超过该教室中学生的最大容纳人数
  • 3)必须为每个学生分配适合其年龄的教室
  • 4)学生一旦移至较高的教室(例如,从第2班移至第3堂),他们可能不会再向下移至较低的教室]]
  • 这是我的数据:

    Students

=列表清单;每个列表包含有关1个学生的信息:(例如,>

students = [['Student ID', 'Date of Birth', 'classroom_index'], ...]

其中:

  • '学生证'=每个学生的唯一ID
  • “出生日期” =日期对象,和
  • ''classroom_index'=学生当前的课堂作业(1、2、3等)
  • Classrooms =列表清单;每个列表均包含有关1个教室的信息:(例如

    classrooms = [['classroom_index', 'ageMin', 'ageMax', 'capacity']...]

其中:

  • ''classroom_index'=每个教室的唯一ID(即1-8),
  • 'ageMin'=教室的最小年龄(以整数为单位)
  • 'ageMax'=教室的最大年龄(以整数为单位),和
  • '容量'=在任何给定的一天可以分配到教室的最大学生人数
  • 日期 =涵盖预测时间表期间的日期列表;在这种情况下,预测时间表将说明未来2年的每个星期一:

    dates = [2019/11/25, 2019/12/2, ...]

当前状态:

按照上面链接的员工计划代码的结构,这就是我所拥有的:

声明模型
model = cp_model.CpModel()

创建变量
classroom_assignments = {}

for i, d in enumerate(dates):
  for s in students:
    for c in classrooms:
      classroom_assignments[(i, s[0], c[0])] = model.NewBoolVar('classroom_assignments_i%is%ic%i' % (i, s[0], c[0]))

分配学生到教室

## The sum of students assigned to a classroom each day must be <= the capacity of that classroom
for i, d in enumerate(dates):
  for c in classrooms:
    model.Add(sum(classroom_assignments[(i, s[0], c[0])] for s in students) <= c[3])

## The sum of classrooms that a student is assigned to each day must be exactly 1
for s in students:
  for i, d in enumerate(dates):
    model.Add(sum(classroom_assignments[(i, s[0], c[0])] for c in classrooms) == 1)

## The sum of classrooms that a student is assigned to each day where the student's age is outside the min/max range for the classroom must be exactly 0
for s in students:
  for i, d in enumerate(dates):
    d_diff = dateutil.relativedelta.relativedelta(d, s[1])
    age = (d_diff.years * 12)
    model.Add(sum(classroom_assignments[(d, s[0], c[0])] for c in classrooms) == 1 if c[1] <= age and c[2] >= age)

上面的最后一个for循环是我尝试定义约束#3,它引发并出错:

  File "<ipython-input-65-205499abc4dd>", line 15
    model.Add(sum(classroom_assignments[(d, s[0], c[0])] for c in classrooms) == 1 if c[1] <= age_months and c[2] >= age_months)
                                                                                                                               ^
SyntaxError: invalid syntax

关于如何在CP模型的ortools中最适当地编码此约束的任何想法?

我试图提供尽可能多的相关信息,但是如果您需要其他信息或说明,请告诉我。

问题的重点:“关于如何在CP工具的ortools中最适当地编码此约束的任何想法?”我要解决的问题有点像员工安排此处概述的工作:...

看起来像一个简单的语法错误,您所理解的过滤器在错误的范围内。

model.Add(
    sum(
        classroom_assignments[(d, s[0], c[0])]
        for c in classrooms
        if c[1] <= age_months and c[2] >= age_months
    )
    == 1
)

python constraint-programming or-tools
1个回答
1
投票

看起来像一个简单的语法错误,您所理解的过滤器在错误的范围内。

© www.soinside.com 2019 - 2024. All rights reserved.