Python实现零件分配至指定时隙的调度程序优化咨询
零件时隙调度程序实现优化咨询
我目前正在开发一款可将零件分配至指定时隙的调度程序,以下是我基于while/for循环、if/else条件语句完成的初步实现代码,作为Python编程入门者,我想咨询是否存在更高效合理的实现方案,感谢各位的帮助。
import pandas as pd from datetime import datetime, timedelta day_start = str('2021-07-28 06:30') break_1_start = str('2021-07-28 08:50') lunch_start = str('2021-07-28 12:00') break_2_start = str('2021-07-28 14:50') day_end = str('2021-07-28 17:40') day_start = datetime.strptime(day_start, "%Y-%m-%d %H:%M") break_1_start = datetime.strptime(break_1_start, "%Y-%m-%d %H:%M") break_1_end = break_1_start + timedelta(minutes=20) lunch_start = datetime.strptime(lunch_start, "%Y-%m-%d %H:%M") lunch_end = lunch_start + timedelta(minutes=30) break_2_start = datetime.strptime(break_2_start, "%Y-%m-%d %H:%M") break_2_end = break_2_start + timedelta(minutes=20) day_end = datetime.strptime(day_end, "%Y-%m-%d %H:%M") sched_df = pd.DataFrame({"Time": [day_start, break_1_start, break_1_end, lunch_start, lunch_end, break_2_start, break_2_end, day_end]}) print(sched_df) demand_df = pd.DataFrame({"PartNo": ['Part1', 'Part2', 'Part3', 'Part4', 'Part5'], "TTJ": [75, 100, 180, 30, 60]}) demand_df = demand_df.astype({'TTJ': float}) print(demand_df) a = 0 b = 1 c = 2 x = sched_df.iloc[a]['Time'] y = sched_df.iloc[0]['Time'] z = 0 for n in range(0, len(demand_df)): while y < sched_df.iloc[1]['Time']: y = x + timedelta(minutes=demand_df.iloc[a]['TTJ']) if y > sched_df.iloc[1]['Time']: end = sched_df.iloc[1]['Time'] print(demand_df.iloc[a]['PartNo'], 'time from : ', x.time(), ' to ', end.time()) start = sched_df.iloc[1]['Time'] end = sched_df.iloc[2]['Time'] print('Break time from : ', start.time(), ' to ', end.time()) xyz = sched_df.iloc[1]['Time'] - x delta = xyz.total_seconds() minutes = float(delta // 60) z = demand_df.iloc[a]['TTJ'] - minutes x = end + timedelta(minutes=z) counter = a else: print(demand_df.iloc[a]['PartNo'], 'time from : ', x.time(), ' to ', y.time()) x = y a = a+1 if x > sched_df.iloc[3]['Time']: start = sched_df.iloc[2]['Time'] end = sched_df.iloc[3]['Time'] print(demand_df.iloc[a]['PartNo'], 'time from : ', start.time(), ' to ', end.time()) xyz = x-end delta = xyz.total_seconds() minutes = float(delta // 60) z = minutes start = sched_df.iloc[3]['Time'] end = sched_df.iloc[4]['Time'] print('Lunch time from : ', start.time(), ' to ', end.time()) start = sched_df.iloc[4]['Time'] x = start + timedelta(minutes=z) print(demand_df.iloc[a]['PartNo'], 'time from : ', start.time(), ' to ', x.time()) z = 0 a = a + 1 else: start = sched_df.iloc[2]['Time'] print(demand_df.iloc[a]['PartNo'], 'time from : ', start.time(), ' to ', x.time()) z = 0 a = a + 1 y = x for n in range(0, len(demand_df)): while y < sched_df.iloc[3]['Time']: y = x + timedelta(minutes=demand_df.iloc[a]['TTJ']) if y > sched_df.iloc[3]['Time']: end = sched_df.iloc[3]['Time'] print(demand_df.iloc[a]['PartNo'], 'time from : ', x.time(), ' to ', end.time()) start = sched_df.iloc[3]['Time'] end = sched_df.iloc[4]['Time'] print('Lunch time from : ', start.time(), ' to ', end.time()) xyz = sched_df.iloc[3]['Time'] - x delta = xyz.total_seconds() minutes = float(delta // 60) z = demand_df.iloc[a]['TTJ'] - minutes start = sched_df.iloc[4]['Time'] x = start + timedelta(minutes=z) print(demand_df.iloc[a]['PartNo'], 'time from : ', start.time(), ' to ', x.time()) z = 0 a = a + 1 else: print(demand_df.iloc[a]['PartNo'], 'time from : ', x.time(), ' to ', y.time()) x = y a = a + 1
可参考的优化思路
- 硬编码逻辑解耦:现有代码的作息时间、时段索引都是固定写死的,后续调整作息、扩展多日调度很容易出错。可以将所有时段统一整理为结构化的时段列表,标记每个时段是工作还是休息,后续只需修改这个列表就能适配不同排班规则,不用单独维护一堆时间变量,也不用依赖
sched_df.iloc[x]这种固定下标取值。 - 重复逻辑抽离:现在处理第一趟休息、午餐时段的逻辑几乎完全一致,只是判断的时段边界不同,可以把零件分配的逻辑抽为通用函数,输入当前零件加工时长、当前时间、可用时段列表,直接返回分配结果和下一个可用时间,大幅减少重复代码,可读性也会提升很多。
- 变量命名规范:现有代码里
a、b、c、x、y、z都是无意义的变量名,后续排查问题很难快速对应逻辑,可以改成current_part_idx、current_time、remaining_process_minutes这种见名知意的命名,不用来回翻代码对应变量含义。 - 减少不必要的依赖:当前场景下pandas只是用来存储两个表格,完全可以用Python原生的列表存储零件需求、时段信息,减少不必要的依赖,运行效率也更高,如果后续需要导出调度结果再引入pandas也不迟。
- 补充边界处理逻辑:现有代码没有覆盖超过下班时间、零件加工时长超过单个工作时段的通用场景,可以加通用的循环判断逻辑:每次取当前可用的工作时段,判断剩余加工时长是否能在当前时段内完成,能就直接分配,不能就占满当前时段,减去对应加工时长后自动跳到下一个工作时段(自动跳过休息/午餐),直到当前零件加工完成即可。
内容的提问来源于stack exchange,提问作者Bajuns
相关产品推荐
相关产品推荐

