首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >添加一个要求数值介于上、下界之间的约束(或工具约束优化/ CP)

添加一个要求数值介于上、下界之间的约束(或工具约束优化/ CP)
EN

Stack Overflow用户
提问于 2019-11-19 15:25:19
回答 1查看 301关注 0票数 1

问题的关键是:“对于如何在CP模型的ortools中最恰当地编码这个约束,有什么想法吗?”

我试图解决的问题有点像这里概述的员工日程安排问题:

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

问题

我想建立一个课堂作业时间表,在一段时间内每天分配学生到教室(现在,每周一次,为期两年)。

我有一所有8个教室的学校。学生被分配到教室取决于他们的年龄。每个教室都有一个与之相关的年龄范围,例如:

  • 类1: 1-3岁
  • 类2: 2-4岁
  • 类3: 3-5岁等

注意,教室的年龄范围是重叠的。

学生应在下列限制的情况下被分配到教室:

  • 1)每个学生必须每天被分配到一个教室(
  • 2)教室的学生总和不得超过该教室中学生的最大容量(
  • 3)每个学生必须被分配到适合他们年龄的教室(
  • 4)一旦学生搬到更高的教室(例如,从二班搬到三班),他们就不可能回到较低的教室

F 218

以下是我的数据:

学生=列表;每个列表包含关于1名学生的信息:(例如,

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

其中:

每个出生日期对象的唯一id,student

  • 'Date and

  • 'classroom_index‘=学生当前的课堂作业(1,2,3等)

教室=列表;每个列表包含关于1个教室的信息:(例如,

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

其中:

  • 'classroom_index‘=每个教室的唯一id (即.,1-8),
  • 'ageMin’=教室的最小年龄界( years)
  • 'ageMax‘中的整数=教室的最大年龄界(以年为整数),and
  • 'capacity’=在任何一天

上可分配到教室的学生的最大数量)

dates =涵盖预测时间表期间的日期列表;在本例中,预测时间表在未来两年中每个星期一都有:

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

现状:

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

声明模型

代码语言:javascript
复制
model = cp_model.CpModel()

创建变量

代码语言:javascript
复制
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]))

把学生分配到教室

代码语言:javascript
复制
## 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的尝试,它抛出并出错:

代码语言:javascript
复制
  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中最恰当地编码这个约束,有什么想法吗?

我试图提供尽可能多的相关信息,但如果您需要更多的信息或澄清,请告诉我。

EN

回答 1

Stack Overflow用户

发布于 2019-11-19 15:31:37

看起来是一个简单的语法错误,用于理解的过滤器在错误的范围内。

代码语言:javascript
复制
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
)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58937460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档