资源描述
2011年河南科技大学数学建模竞赛选拔
承 诺 书
我们仔细阅读了数学建模竞赛选拔的规则.
我们完全明白,在做题期间不能以任何方式(包括电话、电子邮件、网上咨询等)与队外的任何人研究、讨论与选拔题有关的问题。
我们知道,抄袭别人的成果是违反选拔规则的, 如果引用别人的成果或其他公开的资料(包括网上查到的资料),必须按照规定的参考文献的表述方式在正文引用处和参考文献中明确列出。
我们郑重承诺,严格遵守选拔规则,以保证选拔的公正、公平性。如有违反选拔规则的行为,我们将受到严肃处理。
我们选择的题号是(从A/B/C中选择一项填写): C
队员签名 :1. 崔晓鹏
2. 孙艳坤
3. 范常青
日期: 2011 年 08 月 20 日
2011年河南科技大学数学建模竞赛选拔
编 号 专 用 页
评阅编号(评阅前进行编号):
评阅记录(评阅时使用):
评
阅
人
评
分
备
注
C题 油库人员的优化配制
摘要
问题要求给出最少人员配置和工作时间统计,问题1、2、3三问其实质一样,只是兼职情况不一样。因此建立一个模型,分别套用三问的兼职策略,分别求出其解。模型采用计算机模拟的方法,通过c++实现。分别建造工人类,工作类,说明其属性和触发机制;制定工人和工作之间的匹配原则;以及用工招工原则(尽量减少工人数量)。
利用C++模拟工厂的运行,起始工人为0,运行一年后,查看工人数量即作为解,同时统计工人配置情况和平均工作时间等数据。通过模拟不仅能求得最少配置解,而且可以清晰地显示工厂运行的动态,以及每个工人每天的工作,可以制定每个工人本年度的工作表。最后根据前几问的数据,对油库的管理和效率提出建议。
一、 问题重述
一个油库管理工作要保证正常的运行,必须要设置计量与质量检测管理、收发油料管理、装备维护与维修管理、安全保障管理、服务保障管理等相关的岗位和人员配制。
根据实际需要按工种分类,油库的工作岗位可以分为5大类:(A)计量与质量检测管理;(B)收发油料管理;(C)设备维护与维修管理;(D)安全保障管理;(E)服务保障管理。
附表给出了各类工作岗位、所需要的人员数量和全年的工作量。同时要求每个人全年累积从事油库管理相关工作的总工作量不超过175天(每天按8小时计算),除节假日外,其他时间用于业务学习等活动。
研究解决下列问题:
(1)根据油库正常的工作任务需要,如果要求(A)、(B)、(C)和(D)类人员都配专职,同类中的各工作岗位人员可以兼职。那么各类工作岗位最少需要配制多少人员?平均年工作量是多少?
(2)考虑到人员和编制的问题,要求(A)、(B)两大类工作专职专人,(C)、(D)两大类在时间允许的情况下可以相互兼职。那么这个油库最少需要多少人员才能保证油库的正常运行?并说明各类人员的年总工作量为多少?
(3)如果每个人都能从事(A)、(B)、(C)和(D)类中的任何一项工作,那么在时间允许的情况下,最少需要多少人员能够保证油库的正常运行?并说明各类人员的年总工作量为多少?
(4)对该油库的岗位和人员的配置、提高油库的管理水平和运行效率等方面提出合理化建议。
一、 模型假设
1.工作人员都能按时完成每天分配的工作任务。
2.当工作人员不够时,能够按时招到所需要的人数。
二、 符号说明
A类工作:
A1 月计量检测
A2 半年计量检测
A3 储油质量检验
A4 全面检测
A5 收油计量检测
A6 收油质量检验
B类工作:
B1 收油操作1
B2 收油操作2
B3 收油操作3
B4 零发油操作1
B5 零发油操作2
B6 零发油操作3
C类工作:
C1 收油设备维护值班
C2 零发油设备维护值班
C3 常规维护保养
C4 设备日常维护保养
C5 常用设备维护保养
C6 安全设备维护保养
C7 配电设备维护保养
D类工作:
D1 收油消防值班
D2 零发油消防值班
D3 消防设施维护
D4 消防车辆维护
D5 日常安全检查与维护
D6 油库环境保养与卫生
E类工作:
E1 伙食服务保障
E2 医疗服务保障
E3 车辆服务保障
E4 警卫服务保障
四、 模型的建立与求解
问题分析:
由于E类工作人员比较固定,E1工作有总人数通过求解其他工作人员的总人数即可确定,E2,E3,E4的工作总人数通过年工作量即可求得,因此重点放在求解A,B,C,D类工作人员数。
求解A、B、C、D的模型:(计算机模拟)
日期定为2012年,共366天。
采用计算机模拟,建立一个工人类和工作类。
工作类声明25个对象,分别代表A-D中25项目工作。工作类属性中有组,每个工作对象对对应属于自己的组,如A1属于A组,B1属于B组,组号A-D用0-3表示。
工作类属性中有触发方式,触发方式即任务开始的时间,统计表中共有以下几种触发方式及其对应的代号和所对应的工作:
插入触发类型表0—14
0 每月25日开始 A1
1 每年6、12月1日开始 A2
2 每单月15日开始 A3
3 每年1、7月10日开始 A4
4 每双月10日 A5、A6、B1、B2、B3、C1、D1
5 每年12月1日开始 C3
6 每周一、周五进行 C4
7 每月15日开始 C5
8 每单月20日开始 C6
9 每年双周的周三进行 C7
10 每周一开始 D3、D4
11 每两天1次 D5
12 除节假日外每天1次 D6
13 全专职 E1、E2、E3、E4
14 平均每年120次 B4、B5、B6、C2、D2
其中随机触发用(rand()%100<33)去模拟,其他根据年月日触发。
工人类声明足够量的对象待用,工人类属性中有工作时间,和工作历史记录,和现在工作所属的组号。
模型的运行流程:
1.每天开始,查询所有工作看看有没有新任务被触发开始和有没有任务因工人不足最少人数而中断。
2.为以上两种情况的任务分配工人,若有闲置匹配人员,从中挑选,若无,新招聘工人。
3.查询哪些任务可以让更多的人类干,并从闲置工人中挑选匹配工人加入工作,并相应调整工作结束时间,若无,不新招工人。
4.结账,一天结束,结束已完成的任务并释放其占有的工人,并根据工作时间改变工人工作时间time。
循环运行以上四步366次,最终给出总共招聘的人数。
原则:
1.分配工人时的匹配原则:根据具体题目确定匹配原则,如第一题,只有组内可兼职,组之间不能兼职。匹配原则就是工人的组号和工作的组号必须相同;具体匹配原则见下面各个问题的分析。
新招聘工人的组号和招聘他的工作组号相同。
2.任务开始必须有人做。
3.有闲置匹配人员就不再新招工人。
模型流程示意图
(初始n=0)
工人和工作的匹配原则
看是否有任务开始,或有任务因人员不足而中断
若有选人,以下两条途径,
招人 n++
闲置匹配人员(优先)
结账
是否有任务可以让更多人来做
若有从闲置匹配人员中挑选
循环366次
输出n,即为总共所找人数。
程序最后统计:
1. 每组分配工人数。
2. 每组平均工作时间。
3. 每个工人一年的工作安排表。
由于有时工人可以兼职,造成一个工人可能干过很多种工作,我们以工人干过最多的工作按作为其工作;然后统计每个工作组的工人数和平均工作时间。
问题1,2,3对应的模型一样,只是工人分配工作时的匹配原则不一样,故下面分别分析。
各个问题的工人工作之间的匹配原则。
根据模型所编的程序见附录三。
问题1分析:
要求(A)、(B)、(C)和(D)类人员都配专职,同类中的各工作岗位人员可以兼职。
组内可以兼职,组间不能兼职。
匹配原则应是:工人的组数号必须和工作的组数号相同。
问题2分析:
要求(A)、(B)两大类工作专职专人,(C)、(D)两大类在时间允许的情况下可以相互兼职。
各组内可以兼职,除C,D之间可以兼职,其他组间不可兼职。
匹配原则是:除了工人的组号和工作的组号是C或D外,其他工人的组号必须和工作组号相同。
问题3分析:
每个人都能从事(A)、(B)、(C)和(D)类中的任何一项工作。
组间组内都可兼职。
匹配原则是:对工人,工作的组号无限制。
问题4分析:
附表中给出最少工作人员,在附表下方的说明中提出,增加执行同类任务的工作人员人数,可以提高工作效率,即多人从事同样工作可以减少工作时间。通过工作人员的调配便可以达到提高工作效率的目
模型求解
问题1求解
通过计算机模拟A,B,C,D四类工作的最少配置人数及各类工作的平均年工作量,结合单独求解E类工作人员数得到工作人员的总人数,表格如下:
工作类别
最少配置人数
平均年工作量
A
4
54.5
B
28
15.8
C
18
21.6
D
40
32.3
E
36
175
总工作人数
126
计算机模拟动态调配图。
通过计算机模拟得到所有工作人员的工作动态调配数据,通过matlab作图得到工作人员的一年的工作任务动态变化图,以下将第1个工作人员的动态变化图作为图例。
第一个人一年的工作任务变化图
(说明:横轴代表一年的工作时间,纵轴1-25代表A-D ,25小类工作,0代表空闲,以下相同,不再说明)
第一个工作人员的工作转换图(每天):
24->22->24->21->24->21->24->0->22->25->21->25->24->21->24->22->24->25->21->25->24->21->21->25->24->25->21->21->21->22->24->21->24->25->24->21->22->25->24->25->20->21->21->21->24->25->24->21->24->0->22->25->24->25->24->25->21->22->21->25->21->25->24->0->22->21->24->25->24->25->24->21->24->21->24->25->21->21->22->25->21->21->24->25->24->22->24->25->21->21->24->0->21->21->24->25->21->25->21->22->20->21->24->25->21->21->22->21->24->25->21->25->21->22->24->21->24->25->24->21->22->25->24->25->24->25->24->22->21->25->24->25-> 24->21->22->21->21->25->21->25->24->22->24->25->24->21->21->0->21->25->21->25->21->21->21->22->21->25->24->25->21->20->21->25->24->25->24->25->21->22->24->25->24->21->24->21->22->25->24->25->24->25->24->22->21->25->21->25->21->0->21->25->24->25->21->21->21->21->21->21->21->21->24->0->21->25->21->25->24->21->21->21->24->21->24->21->24->0->22->25->21->25->20->21->24->21->24->21->24->25->24->0->22->25->21->25->24->21->24->22->24->25->24->25->24->0-> 21->25->24->21->21->25->24->22->21->25->24->25->24->21->22->25->24->21->24->25->21->22->21->25->24->25->24->0->22->21->21->21->21->25->24->22->21->20->24->21->21->0->22->25->24->21->21->25->21->21->24->25->21->25->24->21->22->25->21->25->24->25->24->21->24->25->21->25->24->21->22->25->24->21->24->25->24->22->24->25->24->21->24->21->22->25->24->25->21->21->21->22->24->25-> 21->25->24->0->20->21->21->25->21->25->21->22->24->25->24->25->0->0->0->0->0->0->0->0->0->0->
问题2求解
通过计算机模拟A,B,C,D四类工作的最少配置人数及各类工作的平均年工作量,结合单独求解E类工作人员数得到工作人员的总人数,表格如下:
工作类别
最少配置人数
平均年工作量
各类总工作量
A
4
54.5
218
B
28
15.8
442
C
12
53.5
642
D
43
21.7
933
E
36
175
6300
总工作人数
123
计算机模拟动态调配图。
通过计算机模拟得到所有工作人员的工作动态调配数据,通过matlab作图得到工作人员的一年的工作任务动态变化图,以下将第1个工作人员的动态变化图作为图例。
第1人一年工作任务变化图:
工作转换图见附录2。
问题3求解
通过计算机模拟A,B,C,D四类工作的最少配置人数及各类工作的平均年工作量,结合单独求解E类工作人员数得到工作人员的总人数,表格如下:
工作类别
最少配置人数
平均年工作量
各类年总工作量
A
0
0
0
B
6
105.4
632
C
8
45.1
360
D
69
15.9
1097
E
36
175
6300
总工作人数
119
(A栏等于0不是说不给A配置人,而是说,不需要专门给A组配置人员,靠其他组人员的的兼职即可完成A的工作。)
计算机模拟动态调配图。
通过计算机模拟得到所有工作人员的工作动态调配数据,通过matlab作图得到工作人员的一年的工作任务动态变化图,以下将第1个工作人员的动态变化图作为图例。
第1人一年工作任务变化图:
工作转换图见附录2。
问题4求解:
比较三问结果可以看出增加组间兼职对减少工人数目效果并不明显,反而增加了每个工人所从事工作的种类,降低了工作效率,因为人的注意力是有限的,过多类型的工作只会让每样都干不好。因此问题一的方案是更好的方案。但问题一的结果显示,A D组人的工作时间明显高于其他两组,因此应加以权衡,适当增加A D组的人数,减少B C组的人数。
三、 模型的评价与改进
模型评价:
1、由于问题是动态优化问题,用计算机模拟比其他方法更具有现实意义,因为计算机模拟,不仅能求出很好的解,而且也对问题的整个过程进行了动态模拟,清楚地知道模型各个时刻的人员状况,相当于进行一次实战实验,不仅求出了所需员工数量,而且可以求出每个人一年的工作分配表,每个员工一年每一天的工作情况。这种结果对于实际问题更具有实际意义和可操作性。
2、模型思路清晰,形象性比较好,理解起来也比较容易,采用模拟现实的方法让管理者更清楚企业运行流程,对实际工作分配中可能存在的问题也会有一个直观的了解。而且也可以对已有的分配方案进行模拟运行,对方案的可执行性进行评估。
3、模型中可以加入各种突发事件和随机事件,以评估企业的抗风险能力和应对突发事件能力,以帮助提高企业的生存能力。
不足与改进:
1、 程序为了达到人数最小,采用了极限方法,员工只要有空就要去干活,只要还有人就尽量少招聘新员工,这对于求个极小值是很有帮助的,但对于现实可能并不适用,因为现实还要考虑每个员工的实际忍受能力,和实际可操作能力,因为员工毕竟是人,不是机器。若要用于实际还要适当改进,考虑到员工的劳逸结合。
2、 分配公平性问题,模型采用只要有人就不招新人,故导致早进来的员工工作时间明显高于晚进来的,若应用于实际明显存在着一些公平性问题,除非企业真是按模型的要求只有实在需要人时才招人。解决此问题可以预定一定数量的人,也就是让程序中n起始时刻有一个适当的初值,而非0。
3、 程序中为了达到最小人数,可以从图中看到,员工频繁改变工作,有的甚至一天一变,实际生活中这是不太可行的,因此,应用于实际的话话应在程序中设置一定的改变频率,阻止太过频繁的换工作,以提高工作效率。
4、 综合来看,程序是求出了个最优解,但不代表实际的企业就可以这样安排,它更多只是极限参考,若要将程序应用于实际,应在程序中加入更多人性化考虑。
四、 参考文献
1.C++面向对象程序设计教程 游洪跃 清华大学出版社
2.数学建模与数学实验(第三版)赵静 但琦 高等教育出版社
3.MATLAB 7.0 实用教程 张圣勤 机械工业出版社
五、 附录
附录1:油库5大类岗位、需要人员及年工作量
工作岗位类别
工作岗位代号
工作岗位名称
工作岗位的年工作量
备 注
(A)
计量与质量检测管理
A1
月计量检测
12次×2人×2天/次
每月25日开始
A2
半年计量检测
2次×2人×2天/次
每年6、12月1日开始
A3
储油质量检验
6次×2人×15天/次
每单月15日开始
A4
全面检测
2次×2人×2.5天/次
每年1、7月10日开始
A5
收油计量检测
6次×2人×0.5天/次
每双月10日
A6
收油质量检验
6次×2人×0.5天/次
每双月10日
(B)
收发油料管理
B1
收油操作1
6次×16人×0.5天/次
每双月10日
B2
收油操作2
6次×6人×0.5天/次
每双月10日
B3
收油操作3
6次×1人×1天/次
每双月10日
B4
零发油操作1
120次×5人×0.5天/次
平均每年120次
B5
零发油操作2
120次×1人×0.5天/次
平均每年120次
B6
零发油操作3
120次×1人×0.5天/次
平均每年120次
(C)
设备维护与维修管理
C1
收油设备维护值班
6次×2人×1天/次
每双月10日
C2
零发油设备维护值班
120次×2人×0.5天/次
平均每年120次
C3
常规维护保养
1次×12人×30天/次
每年12月1日开始
C4
设备日常维护保养
104次×12人×1天/次
每周一、周五进行
C5
常用设备维护保养
12次×3人×4天/次
每月15日开始
C6
安全设备维护保养
6次×2人×4天/次
每单月20日开始
C7
配电设备维护保养
26次×2人×0.5天/次
每年双周的周三进行
(D)
安全保障管理
D1
收油消防值班
6次×6人×1天/次
每双月10日
D2
零发油消防值班
120次×6人×0.5天/次
平均每年120次
D3
消防设施维护
52次×6人×1.5天/次
每周一开始
D4
消防车辆维护
52次×6人×0.5天/次
每周一进行
D5
日常安全检查与维护
183次×20人×1天/次
每两天1次
D6
油库环境保养与卫生
241次×1人×1天/次
除节假日外每
天1次
(E)
服务保障管理
E1
伙食服务保障
员额每15人编制1人
全专职
E2
医疗服务保障
2人/天
全专职
E3
车辆服务保障
4人/天
全专职
E4
警卫服务保障
8人/天
全专职
说明:
(1)年工作量格式:次×人×天/次,表示该项任务每年要执行×次,“至少需要×人”同时执行,每次×人需要连续工作z天。
(2)有些任务人数越多执行时间越短,即若每次由×人执行,则每次需要执行时间为×天。但与收油和零发油的相关任务依赖于设备操作,这些岗位所需人员数固定不变,也必须同时在岗,而且零发油的时间是不确定的。
附录2
问题2第1人工作转换图
24->16->24->14->24->14->24->0->16->25->14->25->16->14->17->16->24->25->14->16->24->14->14->25->19->25->14->14->14->16->24->14->24->16->24->14->16->25->19->25->13->14->14->14->24->17->24->14->24->0->16->25->19->25->16->25->14->16->14->25->14->16->24->0->16->14->19->25->16->25->24->14->24->14->17->16->14->14->16->18->14->14->16->25->24->16->24->25->14->14->24->0->14->14->19->25->14->25->14->16->13->14->24->16->14->14->16->14->19->25->14->25->14->16->24->14->24->16->24->14->16->25->19->25->16->25->24->16->14->25->24->16-> 24->14->16->14->14->25->14->25->18->16->24->25->24->14->14->0->14->25->14->25->14->14->14->16->14->25->24->16->14->13->14->25->19->25->16->25->14->16->24->25->24->14->24->14->16->25->19->25->16->25->24->16->14->25->14->16->14->0->14->25->19->25->14->14->14->14->14->14->14->14->24->0->14->25->14->25->16->14->14->14->24->14->24->14->24->0->16->25->14->25->13->14->24->14->24->14->24->16->24->0->16->25->14->25->16->14->24->16->24->25->24->16->24->0->14->25->19->14->14->25->24->16->14->25->24->16->17->14->16->25->19->14->16->25->14->16->14->25->24->16->24->0->16->14->14->14->14->25->24->16->14->13->24->14->14->0->16->25->19->14->14->25->14->14->24->25->14->16->24->14->16->25->14->25->16->25->24->14->24->25->14->16->24->14->16->25->19->14->16->25->24->16->18->25->24->14->24->14->16->25->19->25->14->14->14->16->24->25-> 14->16->24->0->13->14->14->25->14->17->14->16->24->25->24->16->24->14->14->25->19->25->16->25->24->0->
问题3第1人工作转换图
24->16->24->10->24->10->24->0->16->4->4->4->16->10->3->16->24->25->10->16->24->10->10->25->1->1->10->10->10->16->24->10->24->16->24->10->16->25->19-> 25->5->10->10->10->24->17->24->10->24->0->16->25->19->25->16->1->1->16->10->25->10->16->24->0->16->10->19->25->16->25->24->10->24->10->3->16->10->10->16->18->10->10->16->25->1->1->24->25->10->10->24->0->10->10->19->25->10->25->10->16->5->10->24->16->10->10->16->10->19->25->10->25->10->16->24->1->1->16->24->10->16->25->19->25->16->25->24->16->10->25->24->16->24->10->16->3->10->25->10->25->18->16->24->25->24->1->1->0->10->25->10->25->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->2->1->1->2->2->2->2->24->16->10->25->10->16->10->0->10->4->4->4->10->10->3->10->10->10->10->10->24->0->10->25->1->1->16->10->10->10->24->10->24->10->24->0->16->25->10->25->5->10->24->10->24->10->24->16->24->0->16->25->10->25->16->1->1->16->24-> 25->24->16->24->0->10->25->19->10->10->25->24->16->10->25->24->16->3->10-> 16->25->19->10->16->25->10->16->1->1->24->16->24->0->16->10->10->10->10->25->24->16->10->5->24->10->10->0->16->25->19->10->10->25->10->10->24->25->1->1->24->10->16->25->10->25->16->25->24->10->24->25->10->16->24->10->16->25->19->3->16->25->24->16->18->25->24->10->24->1->1->25->19->25->10->2->2->2-> 2->2->2->2->2->2->2->2->2->2->2->2->2->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->
附录3
计算机模拟程序
cpp.cpp#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include "7.h"
extern long gettime(long);
long find(long *);
using namespace std;
long page=0;
bool run;
long n=0;
long t=0;
bool active(long type)
{
long month,date,week,weekn;
long time=gettime(t);
weekn=time%100;
time/=100;
week=time%100;
time/=100;
date=time%100;
time/=100;
month=time%100;
time/=100;
switch(type)
{
case 0:
if(date==25)return 1;
break;
case 1:
if(month%6==0)return 1;
break;
case 2:
if(month%2==1&&date==15)return 1;
break;
case 3:
if(month==1||month==7)
if(date==10)return 1;
break;
case 4:
if(month%2==0&&date==10)return 1;
break;
case 5:
if(month==12&&date==1)return 1;
break;
case 6:
if(weekn==1||weekn==5)return 1;
break;
case 7:
if(date==15)return 1;
break;
case 8:
if(month%2==1&&date==20)return 1;
break;
case 9:
if(week%2==0&&weekn==3)return 1;
break;
case 10:
if(weekn==1)return 1;
break;
case 11:
if(t%2==0)return 1;
break;
case 12:
if(weekn<7)return 1;
break;
case 13:
return 1;
case 14:
if(run)return 1;
break;
}
return 0;
}
class task
{
public:
task()
{
state=0;
type=0;
min=2;
max=10;
current=0;
timelast=10;
error=0;
upable=1;
taskclass=0;
}
long ago;
long error;
long type;
long taskclass;
float timelast;
float endtime;
long state;
long min,max,current;
bool upable;
long set(int a,int b,float t,bool p,long cla)
{
type=a;
min=b;
upable=p;
timelast=t;
if(page==1)taskclass=cla;
if(page==2)
{
if(cla>1)taskclass=5;
else taskclass=cla;
cout<<taskclass<<endl;
}
if(page==3)taskclass=0;
max=min+b*t/7;
}
long jihuo()
{
if(active(type))
{
endtime=t+timelast;
state=1;
current=0;
}
return state;
}
long jiezhang()
{
if(state==1)
{
if(t>=endtime)
{
state=0;
current=0;
展开阅读全文