使用Python画作业调度甘特图
程序员文章站
2022-05-22 12:40:44
...
文章目录
一、背景
之前研究过遗传算法解决经典作业调度问题和柔性作业调度问题,并将调度结果使用matlab画甘特图(用任意多颜色表示任意多工件),还是挺有成就感的。但是使用Matlab画出甘特图后没法很好地整合到如网站等类似生产环境。最近恰好被一个爱好者咨询到了,且自己最近因为工作原因也在学习Python,也就想是否可以通过Python画出优雅的甘特图。还真有类似的解决方案:Matplotlib方案实用代码Python(七)甘特图画法 和 Plotly方案
Gantt Charts in Python
二、方案比较
Matplotlib方案
- Matplotlib相对比较成熟,文案显示比较优雅,但缺点是没法很好地以时间为单位显示作业调度过程,没法很好地整合到生产环境。
Plotly方案
- Plotly是也是Python的一个开源库,有单独的甘特图API支持,比较方便。另外,其作业调度的时间显示比较灵活,可以很好整合到生产环境。该类库也有个缺点:原生API没法在作业调度信息上很好地显示作业调度信息,如工件A的第三道工序的耗费时间。幸好,可以通过layout.annotations配置来解决这个问题。
三、实现方案
以柔性作业调度问题用例MK01的最佳调度图
未使用annotations进行配置修改画图效果
Matlab方案甘特图
三、代码清单
import time
import plotly as py
import plotly.figure_factory as ff
# x轴, 对应于画图位置的起始坐标x
# start, time, of, every, task, , //每个工序的开始时间
n_start_time = [0, 0, 2, 6, 0, 0, 3, 4, 10, 13, 4, 3, 10, 6, 12, 4, 5, 6, 14, 7, 9, 9, 16, 7, 11, 14, 15, 12, 16, 17,
16, 15, 18, 19, 19, 20, 21, 20, 22, 21, 24, 24, 25, 27, 30, 30, 27, 25, 28, 33, 36, 33, 30, 37, 37]
# length, 对应于每个图形在x轴方向的长度
# duration, time, of, every, task, , //每个工序的持续时间
n_duration_time = [6, 2, 1, 6, 4, 3, 1, 6, 3, 3, 2, 1, 2, 1, 2, 1, 1, 3, 2, 2, 6, 2, 1, 4, 4, 2, 6, 6, 1, 2, 1, 4, 6, 1,
6, 1, 1, 1, 5, 6, 1, 6, 4, 3, 6, 1, 6, 3, 2, 6, 1, 4, 6, 1, 3]
# y轴, 对应于画图位置的起始坐标y
# bay, id, of, every, task, , ==工序数目,即在哪一行画线
n_bay_start = [1, 5, 5, 1, 2, 4, 5, 5, 4, 4, 3, 0, 5, 2, 5, 0, 0, 3, 5, 0, 3, 0, 5, 2, 2, 0, 3, 1, 0, 5, 4, 2, 1, 0, 5,
0, 0, 2, 0, 3, 2, 1, 2, 0, 1, 0, 3, 4, 5, 3, 0, 2, 5, 2, 0]
# 工序号,可以根据工序号选择使用哪一种颜色
# n_job_id = [1, 9, 8, 2, 0, 4, 6, 9, 9, 0, 6, 4, 7, 1, 5, 8, 3, 8, 2, 1, 1, 8, 9, 6, 8, 5, 8, 4, 2, 0, 6, 7, 3, 0, 2, 1, 7, 0, 4, 9, 3, 7, 5, 9, 5, 2, 4, 3, 3, 7, 5, 4, 0, 6, 5]
n_job_id = ['B', 'J', 'I', 'C', 'A', 'E', 'G', 'J', 'J', 'A', 'G', 'E', 'H', 'B', 'F', 'I', 'D', 'I', 'C', 'B', 'B',
'I', 'J', 'G', 'I', 'F', 'I', 'E', 'C', 'A', 'G', 'H', 'D', 'A', 'C', 'B', 'H', 'A', 'E', 'J', 'D', 'H',
'F', 'J', 'F', 'C', 'E', 'D', 'D', 'H', 'F', 'E', 'A', 'G', 'F']
op = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
colors = ('rgb(46, 137, 205)',
'rgb(114, 44, 121)',
'rgb(198, 47, 105)',
'rgb(58, 149, 136)',
'rgb(107, 127, 135)',
'rgb(46, 180, 50)',
'rgb(150, 44, 50)',
'rgb(100, 47, 150)',
'rgb(58, 100, 180)',
'rgb(150, 127, 50)')
millis_seconds_per_minutes = 1000 * 60
start_time = time.time() * 1000
job_sumary = {}
# 获取工件对应的第几道工序
def get_op_num(job_num):
index = job_sumary.get(str(job_num))
new_index = 1
if index:
new_index = index + 1
job_sumary[str(job_num)] = new_index
return new_index
def create_draw_defination():
df = []
for index in range(len(n_job_id)):
operation = {}
# 机器,纵坐标
operation['Task'] = 'M' + str(n_bay_start.__getitem__(index) + 1)
operation['Start'] = start_time.__add__(n_start_time.__getitem__(index) * millis_seconds_per_minutes)
operation['Finish'] = start_time.__add__(
(n_start_time.__getitem__(index) + n_duration_time.__getitem__(index)) * millis_seconds_per_minutes)
# 工件,
job_num = op.index(n_job_id.__getitem__(index)) + 1
operation['Resource'] = 'J' + str(job_num)
df.append(operation)
df.sort(key=lambda x: x["Task"], reverse=True)
return df
def draw_prepare():
df = create_draw_defination()
return ff.create_gantt(df, colors=colors, index_col='Resource',
title='mk01的一个最佳调度', show_colorbar=True,
group_tasks=True, data=n_duration_time,
showgrid_x=True, showgrid_y=True)
def add_annotations(fig):
y_pos = 0
for index in range(len(n_job_id)):
# 机器,纵坐标
y_pos = n_bay_start.__getitem__(index)
x_start = start_time.__add__(n_start_time.__getitem__(index) * millis_seconds_per_minutes)
x_end = start_time.__add__(
(n_start_time.__getitem__(index) + n_duration_time.__getitem__(index)) * millis_seconds_per_minutes)
x_pos = (x_end - x_start) / 2 + x_start
# 工件,
job_num = op.index(n_job_id.__getitem__(index)) + 1
text = 'J(' + str(job_num) + "," + str(get_op_num(job_num)) + ")=" + str(n_duration_time.__getitem__(index))
# text = 'T' + str(job_num) + str(get_op_num(job_num))
text_font = dict(size=14, color='black')
fig['layout']['annotations'] += tuple(
[dict(x=x_pos, y=y_pos, text=text, textangle=-30, showarrow=False, font=text_font)])
def draw_fjssp_gantt():
fig = draw_prepare()
add_annotations(fig)
py.offline.plot(fig, filename='fjssp-gantt-picture')
if __name__ == '__main__':
draw_fjssp_gantt()
四、相关文档
上一篇: 判断闰年(输出2020~2500年闰年)
下一篇: unity 鼠标实时画箭头
推荐阅读
-
Python使用turtule画五角星的方法
-
python使用matplotlib画柱状图、散点图
-
使用python画个小猪佩奇的示例代码
-
使用python 的matplotlib 画轨道实例
-
使用python turtle画高达
-
Python使用add_subplot与subplot画子图操作示例
-
【Python3】作业车间调度,SPT规则,LPT规则
-
python使用turtle库画正方形、矩形、三角形、多边形、同切圆和五角星等简单图形
-
在AbpZero中hangfire后台作业的使用——hangfire的调度
-
使用php开发,基于swoole扩展开发的工具 swoole-crontab 作业/任务调度