需要帮助制定 Pyomo 线性程序 - 调度问题

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

我有一个数据集,其中包含有关“多个教学大纲”中的许多课程的信息,将在这些教学大纲中使用的教室以及教室将使用多长时间(例如,如果一节课是一个小时,则教室将是使用一个小时)。下面是每个数据集的示例(数据集很长,所以我只提供了每个数据集的头部):

教学大纲_df:

    +------------+----------+-----+----------+-------------+
    |syllabus_id |lesson_id |day  |classroom |lesson_length|
    +------------+----------+-----+----------+-------------+
    |s101        |l1        |day1 |cr1       |1            |
    |s101        |l2        |day1 |cr2       |2            |
    |s101        |l3        |day2 |cr1       |2            |
    |s102        |l4        |day1 |cr3       |4            |
    |s102        |l5        |day2 |cr4       |2            |
    +-----------------------+-----+----------+-------------+


classroom_df:
    +-----------+-------------+-----------+-------------+
    |session_id |classroom_id |date       |availability |
    +-----------+-------------+-----------+-------------+
    |ses1       |cr1          |01/01/2024 |8            |
    |ses2       |cr1          |01/02/2024 |9            |
    |ses3       |cr1          |01/03/2024 |8            |
    |ses4       |cr1          |01/04/2024 |7            |
    |ses5       |cr1          |01/05/2024 |9            |
    |ses6       |cr1          |01/06/2024 |7            |
    |ses7       |cr1          |01/07/2024 |7            |
    +-----------+-------------+-----------+-------------+

classroom_df 数据框显示一年中每个日期每个教室的可用性,“会话”是“教室 + 日期”的唯一 ID

所以我希望 LP 使用这些信息创建今年的时间表。

目标函数是最大化每天运行的教学大纲数量。

我正在努力思考如何对以下约束进行编程:

  1. 保证lesson_length的总和< availability of the classroom for each day

  2. 同一教学大纲中的所有课程应连续上课(因此“天数”栏;第 1 天、第 2 天、第 3 天等)。有些教室在周末不可用,所以我会接受“下一个可用的一天”作为一个可行的解决方案,在教学大纲中有几天的差距

这是我到目前为止的代码,基于this示例:

import pyomo.environ as pe
import pyomo
import pandas as pd

model = pe.ConcreteModel

# list of lesson id's
model.LESSONS = pe.Set(initialize=list(syllabus_df.lesson_id))
# list of syllabus id's
model.SYLLABUSES = pe.Set(initialize=list(syllabus_df.syllabus_id.unique()))
# list of session id's
model.SESSIONS = pe.Set(initialize=list(classroom_df.session_id))
# list of classroom id's
model.CLASSROOMS = pe.Set(initialize=list(classroom_df. classroom_id.unique()))
# list of all possible lesson-session combinations
model.SCHEDULE_LESSONS = pe.Set(initialize=model.LESSONS * model.SESSIONS, dimen=2)
# the lesson length for each lesson
model.LESSON_LENGTH = pe.Param(model.LESSONS, initialize=self._generate_lesson_durations())
# the availability of each session
model.SESSION_AVAILABILITY = pe.Param(model.SESSIONS, initialize=self._generate_session_availability)
# the available dates for each session
model.SESSION_DATES = pe.Param(model.SESSIONS, initialize=self._get_session_dates())

num_lessons = self.syllabus_df.shape[0]

# DECISION VARIABLES
model.SESSION_ASSIGNED = pe.Var(model.SCHEDULE_LESSONS, domain=pe.Binary)
model.LESSONS_IN_SESSION = pe.Var(model.SESSIONS, bounds=(0, num_lessons), within=pe.PositiveReals)

# OBJECTIVE
def objective_function(model):
    return pe.summation(model.LESSONS_IN_SESSION)
model.OBJECTIVE = pe.Objective(rule=objective_function, sense=pe.maximize)

# CONSTRAINTS
# need help here and also with the solver

提前感谢那些提供帮助的人,我真的很感激!

python constraints linear-programming solver pyomo
1个回答
1
投票

我不知道 Pyomo 编程,但希望这个公式能有所帮助:
参数:
课程时长:

d[l,c] 
其中
s=
教学大纲,
l=
课,
c=
课堂
可用性:
 a[c,d]
在哪里
d=
日期
集合(元组/数据帧)
(S,L)

变量
二进制

 x[l,c,d], y[s,d]

约束
循环 'c,d`:

sum(d[l,c]*x[l,c,d] over l) <= a[c,d] 
:照顾你的第一个约束

循环

s

N = |s|

N*y[s,d] - sum(y[s,k] over k from 1 to d-1) <= N*y[s,d+1]
:
在这里,您的
d =
可用日期和
N =
教学大纲的基数(教学大纲中的课程数量
s

y[s,d] <=sum(sum(x[l,c,d] over c) over l in s) <= Ny[s,d]

sum(y[s,d] over d) = N

l
中循环
s

sum(sum(x[l,c,d] over c) over d) <=1 

上述限制确保教学大纲中课程的教室和日期的连续分配。

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