10人10天排班表生成器 - 满足复杂条件的班次分配方案

本工具可以生成一个包含10名员工、10天工作的排班表,满足各种复杂的班次类型和限制条件,例如每天只能有特定数量的班次、特定班次不能连续安排等等。生成的排班表以电子表格形式输出,方便查看和管理。

问题描述

生成一个10人的10天的排班表,班的种类有'A1'、'A2'、'A3'、'B1'、'B2'、'C',也可以组合成'A1B1'、'A1B2'、'A2B1'、'A2B2'、'A3B1'、'A3B2'、'B1C'、'B2C',这些组合班是要计算各自的两个班的,无论怎么排每天只能有'A1'、'A2'、'A3'、'B1'、'B2'、'C'各1个,'C'、'B1C'、'B2C'第二天不能接其他任何班,每人连续没班的天数不超过4天。生成符合条件的班表以电子表格的形式输出,其中

  • 第一行为标题,是1号到31号日期
  • 第一列标题是一、二、三、四、五、六、七、八、九、十这10个人的名字

代码实现

由于题目比较复杂,因此我们需要分步骤进行。

第一步:确定班次种类

我们需要确定班次的种类,这里有八种班次:'A1'、'A2'、'A3'、'B1'、'B2'、'C'、'B1C'、'B2C'。我们可以用一个列表来表示这些班次:

shifts = ['A1', 'A2', 'A3', 'B1', 'B2', 'C', 'B1C', 'B2C']

其中,'B1C'和'B2C'表示'B1'和'C'的组合班,'B1C'包含'B1'和'C'两个班次,'B2C'包含'B2'和'C'两个班次。

第二步:确定每天的班次

我们需要确定每天的班次,这里有一些限制条件:

  • 每天只能有'A1'、'A2'、'A3'、'B1'、'B2'、'C'各1个班次。
  • 'C'、'B1C'、'B2C'第二天不能接其他任何班次。

我们可以用一个列表来表示每天的班次,列表的长度为10,表示10个人,列表中的每个元素是一个字典,表示这个人每天的班次。例如,第一天(1号)的班次可以表示为:

{
    'A1': False,
    'A2': False,
    'A3': False,
    'B1': False,
    'B2': False,
    'C': False,
    'B1C': False,
    'B2C': False
}

其中,False表示这个人这一天没有这个班次,True表示有这个班次。

我们可以用一个函数来生成每天的班次,下面是代码:

def generate_shifts():
    shifts_per_day = []
    for i in range(10):
        shifts_per_person = {
            'A1': False,
            'A2': False,
            'A3': False,
            'B1': False,
            'B2': False,
            'C': False,
            'B1C': False,
            'B2C': False
        }
        shifts_per_day.append(shifts_per_person)
    for day in range(1, 11):
        for person in range(10):
            if day == 1:
                shifts_per_day[person]['A1'] = True
            else:
                available_shifts = [shift for shift in shifts if shift not in ['B1C', 'B2C']]
                if day % 2 == 0:
                    available_shifts = [shift for shift in available_shifts if shift != 'C']
                for shift in available_shifts:
                    if not shifts_per_day[person][shift]:
                        if shift in ['B1', 'B2']:
                            if day == 10:
                                shifts_per_day[person][shift] = True
                            elif not shifts_per_day[person]['C']:
                                shifts_per_day[person]['B1C' if shift == 'B1' else 'B2C'] = True
                                shifts_per_day[person]['C'] = True
                                break
                        else:
                            shifts_per_day[person][shift] = True
                            break
    return shifts_per_day

上面的代码中,我们先生成一个空的班次列表shifts_per_day,然后遍历每天和每个人,根据不同的限制条件来确定每个人每天的班次。最后返回完整的班次列表。

第三步:确定连续没班的天数

我们需要确定每个人连续没班的天数不超过4天。我们可以用一个函数来检查每个人的班次,下面是代码:

def check_shifts(shifts_per_day):
    for person in range(10):
        consecutive_days_without_shift = 0
        for day in range(10):
            if not any(shifts_per_day[person].values()):
                consecutive_days_without_shift += 1
            else:
                consecutive_days_without_shift = 0
            if consecutive_days_without_shift > 4:
                return False
    return True

上面的代码中,我们遍历每个人的班次,如果这个人这一天没有任何班次,则连续没班的天数加1,否则连续没班的天数清零。如果连续没班的天数超过4天,则返回False,表示这个班表不符合要求。

第四步:生成班表并输出

现在我们可以将上面的步骤整合起来,生成符合条件的班表并输出。下面是代码:

import random
import pandas as pd

shifts = ['A1', 'A2', 'A3', 'B1', 'B2', 'C', 'B1C', 'B2C']

def generate_shifts():
    shifts_per_day = []
    for i in range(10):
        shifts_per_person = {
            'A1': False,
            'A2': False,
            'A3': False,
            'B1': False,
            'B2': False,
            'C': False,
            'B1C': False,
            'B2C': False
        }
        shifts_per_day.append(shifts_per_person)
    for day in range(1, 11):
        for person in range(10):
            if day == 1:
                shifts_per_day[person]['A1'] = True
            else:
                available_shifts = [shift for shift in shifts if shift not in ['B1C', 'B2C']]
                if day % 2 == 0:
                    available_shifts = [shift for shift in available_shifts if shift != 'C']
                for shift in available_shifts:
                    if not shifts_per_day[person][shift]:
                        if shift in ['B1', 'B2']:
                            if day == 10:
                                shifts_per_day[person][shift] = True
                            elif not shifts_per_day[person]['C']:
                                shifts_per_day[person]['B1C' if shift == 'B1' else 'B2C'] = True
                                shifts_per_day[person]['C'] = True
                                break
                        else:
                            shifts_per_day[person][shift] = True
                            break
    return shifts_per_day

def check_shifts(shifts_per_day):
    for person in range(10):
        consecutive_days_without_shift = 0
        for day in range(10):
            if not any(shifts_per_day[person].values()):
                consecutive_days_without_shift += 1
            else:
                consecutive_days_without_shift = 0
            if consecutive_days_without_shift > 4:
                return False
    return True

def generate_schedule():
    while True:
        shifts_per_day = generate_shifts()
        if check_shifts(shifts_per_day):
            break
    schedule = []
    for i in range(10):
        person_schedule = []
        for j in range(10):
            person_schedule.append(random.choice([shift for shift, value in shifts_per_day[j].items() if value]))
        schedule.append(person_schedule)
    return schedule

schedule = generate_schedule()
df = pd.DataFrame(schedule, index=['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'], columns=range(1, 11))
print(df)

上面的代码中,我们先调用generate_shifts函数生成符合条件的班次列表。然后调用check_shifts函数检查班次列表是否符合要求。如果不符合要求,则重新生成班次列表,直到符合要求为止。

最后,我们调用generate_schedule函数生成班表,班表用一个二维列表表示,列表的第一维表示10个人,列表的第二维表示10天的班次。

最后,我们将班表输出为电子表格的形式,用pandas库中的DataFrame函数来实现。

使用方法

  1. 复制上面的代码到一个名为schedule.py的文件中。
  2. 使用python运行schedule.py文件,例如:python schedule.py
  3. 程序将打印一个包含10行10列的电子表格,每一行代表一个人的排班,每一列代表一天的排班。

注意事项

  • 代码中使用了一些python库,例如pandas库,你需要在你的环境中安装这些库,例如使用pip install pandas命令。
  • 程序每次运行都会生成不同的排班表,因为我们在代码中使用了随机数。
  • 本程序仅供参考,实际使用时需要根据具体的实际情况进行调整。

联系我们

如果你在使用本工具的过程中遇到任何问题,请随时与我们联系。

作者

本工具由[你的名字]编写,感谢你的使用!

10人10天排班表生成器 - 满足复杂条件的班次分配方案

原文地址: http://www.cveoy.top/t/topic/nJak 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录