我自觉很失职,第二版出来那么久了,却始终没有告诉读者如何使用。忙是一回事,写使用说明这事很耗时则是另一个原因。此外写完了有多少人看?有发挥什么影响?这些不是我能知道的,简单的说:写了半天,却没有可预见的报偿,这才是我一天拖过一天的最大原因。
那就开始吧!
刚登入的画面如下:
这版的结构跟第一版不同,在第一版里,使用者没有等级的分别;但这一版的使用者有权限差别。
各位拿到的都是”admin”帐号的版本,所以能使用全部的功能。
首先,我们看(1),这里预设只有「医院」的选项,各位可以跳过此。
(2)所有排班列表:这里是所有排过的班表所在。前一版无法储存排过的班表,所以每个月都得重新输入排班条件。范例中有二个班表,各位可以不用理它,自行建立新班表。
接下来我们看(4),所有同事列表,各位可以勾选要参与此次排班的人员。范例中,只有”sue”没有勾选,其余六位都参与排班。
再来就跳回(3),(3) 很直觉,只有「值班后应休息几班」须要说明。这功能如字面上的意义,假说你认为一天有三班,每值一班后,需休息二班,那就调成”2″,这样,程式就会把每个人值班间隔调成二班以上。
把(3)的所有条件设定后,就到(5),选择「新增排班基本设定」。若是你选择「储存排班基本设定」也可以,但会把你当做范本的班盖掉。
接着,按(5) 里最下方的「前往排班进阶设定」,画面会变成如下:
所谓「排班进阶设定」指的是
a. 每个班需要多少人?以此班表为例,星期一至五,每班只需一人;而星期六日则每班需二人。这一点也是第二版最大的突破!第一版仅能做一班一人的排班,这一版则可以设定一班多人。看起来似乎没什么大不了的改进,其实内部结构有很大不同,以后我在基因演算法那个版会详述。
b. 每个班的权重(或称点数),即图中的(2)
c. 每个人的值班意愿,即图中的(3)
在「各班次人力编制」里,右栏的「shift人数微调」「weekday人数微调」都是用来调整每班人数。你也可以直接按某一个班,然后改变人数。最后,记得要按「储存」键。
相信大家在这里会有个疑问:若是要参与排班的员工名字不在第一页的功能里面呢?或是要排班的人超过预设的七人呢?我自己难道不能加入员工的姓名等资料吗?应该没有人写的程式这么笨,会无法更改。
只是本程式要更改上述的设定的按键,有点像游戏程式的特殊功能,不易被发现。请看下图的「显示」–> 「员工基本资料」
按下去后,就会出现「员工基本资料」的设定。怎样,有够隐密吧?
你现在可以把 sue 改成 阿明。
在这儿有个很重要的参数叫「点数微调」,它的意思就是代表此人资深程度,
你把这个点数调成5,那么最后排班结果此人的值班点数(或是权重)就会比平均值少5点。
所以,若是R5和R1一起排班,你就可以把R5的「点数微调」设高一点,这样他值的班就会比较少。
最后,还是要记得按「储存员工资料」
ok, 我按「所有人列表」来看我新增的人员
请注意看:阿花、阿珠、阿明三个人的「职位等级」不是0
员工设定好后,我可以再回去「排班基本设定与选择」
然后把我刚才加入的员工选出来参与排班
最后还是不要忘记按「储存排班基本设定」
接下来,我再回到「各班次人力编制」,将人员需要设定如下图。
而图中圈起来处是mouse cursor 所处的班次资讯,可以告诉你mouse所在处是几号,第几个礼拜,第几班。
再次提醒您:一定要「储存」。这个程式在变更任何设定后,一定得按「储存」,否则变更后的资料就不会写入资料库内,执行程式便会出现与预期不符的现象。
接下来设定「各班次点数设定」。有排过班的人大概都知道这是什么意思?简单的说:值星期一早班和值星期六晚班并不等价,虽然都是值一班,但有的人可能宁愿用二班星期一早班来换一班星期六晚班。所以我们给每个班一个点数,也就是权重,用来评估此班的价值。程式最后也是力求「点数」接近,而不只是「班数」接近。
以往笔者在当实习医师时代,还没有周休二日,我们把平常日一班当1点,星期六1.5点,星期日则是2点,这样要计算每个人的点数比较方便。但是有一天,一位同学有异议,他认为星期六应该是1.6点,结果大家都傻眼了,因为1.6会使得点数计算很难公平。最后大家并没有采纳他的建议,但是这件事笔者一直放在心上,所以我写程式时便让点数可以微调到小数点后一位,算是纪念这位同学。这也是一种蝴蝶效应吧? 顺道一提,这位同学现在在秀传放射肿瘤科当主治医师。
下一步是值班意愿设定。在这里,每个人的值班偏好可以充分表达,像是那天想值班;那天不可值班;那天二者皆可。
先看(1),选出要设定的人员
再看(2),把cursor移到日期上,对着班别按mouse左键便可在 值班–>不值班–>不设定 三种状态切换。
像小玲,可能为了值夜班多赚点钱,便设定第二个星期的大夜班要「排班」;而第一个星期的头二天,她想回南部,所以设定「不排班」
(3),记得储存设定
全部人员都设定完后,不要急着离开这个画面。
按一下右栏中的「选择各班不值班之人数」。这个功能是让 Administrator 了解有多少人选择不值某个班。举例而言,本班意愿设定中,有二个人(小贞和小玲)指定不值第二天的早班(见图中圈圈)。通常这个功能是没什么用的,但有时会变得很重要。例如排班的七个人都指定不值第二天的早班,那么程式无论如何也找不到最佳解。所以当你发现大家都争着值某班,或争着不值某班时,要先协调一下,不然程式虽然还是可以运行,但永远会有人不满意。
有没有办法不用人去检查这种逻辑冲突?高荣急诊部的庄旺全医师想出了加入dummy(假人)的方式,我觉得相当好。详情可问庄医师,或待我有空再po上来。
终于进入最后一项设定「演算法参数设定」。这里有好多各位看不懂的参数,不用太害怕,请听我娓娓道来
若您是初学者
请直接按(5)「产生新的排班结果」即可。
但若是你的产生新的排班结果这个按键是虚的,无法按,怎么办?这表示你前面(人力编制、点数设定、值班意愿)有些项目没设定到,或是没有按「储存」。只要再回去那些画面检查一下即可。
若您是中阶使用者
那么,我们一步一步进行
首先(1)中,选一个演算法编号。这些编号记录着你以前用过的参数设定。若你都没有变更过,那应该只要一个”test”可以选
在(2)中,你可以设定名称,这儿可做可不做
在(3)的绿框中,可以设定penalty的高低。例如「不休息」9分的意思是演算法中,若遇到某人连值的情形,则会对这个班表扣9分;「只休一班」4分,表示若某人qod值班(值一班,休一班,又再值班),则程式会对这个班表扣4分。
举例:
某班表如下: ….AACBFBDEF….
因为A连值,B隔班值,所以这个班表penalty是9+4=13, 即会被扣13分。而这个程式追求的是penalty愈小愈好,最好是0。同理,下面的「不愿值但排班」9分的意思就是某人设定那天他不想值班,但程式却把他排进去,这样这个班表就会被扣9分。
这些分数你可以调动它,这会影响最后找到的「好」的班表是不是符合你们的期望。像是有些人不介意连值,那么便可以把「不休息」和「只休一班」这二栏都填0分;有些人介意自己不想排的班被排入,但不介意想值而没被排入,便可把「不愿值但排班」填高一点,例如12分,而「想值但不排班」填低一点,如3分。(4)是问你程式跑一次需给你几个班表?预设是给你十个解,让你自己去挑那个比较好,范例中则填入20,这样程式每跑一次,就给你20个班表任你选择。
最后就是按(5)开始跑程式了。
若你是高阶使用者
….应该只有我跟台大研究生及金博士三个人吧 ,那就不用解释了,耶~
好罢,以后以后,当我很有空时,我从GA演算法谈起,再谈如何把排班转换成gene形式,再谈crossover的方式,再谈selection的方式,这样你们才会了解其它参数在干麻。其实,下载我程式的各位都是智商很高很高的人,这些玩意对你们而言并没有那么难,我只是唬唬大家,顺便偷懒一下。
不过我可以告诉各位,在大部份情况下你不需变动这些参数便可得到很好的结果,但在某些情形,如极多限制,极多人员,极大日期,则调整这些参数有助于找到最佳解。
好,当你按下「产生新的排班结果」时,你可能发现….毫无动静这是怎么了呢?不用担心,程式已经在跑了,只是我们没有做程式执行中的变化,例如沙漏在漏这样的动画。
等了40秒左右(视问题大小而定),就会跳出下图,按ok即可
接下来这个画面要小心,它显示了20组解答的penalty。在此例中,最好的那个解是126.9,最差的那个解是149.1。
请注意! 这个值愈接近0愈好。
所以,若是你满意了这组答案,那请按「取消」;若你不满意这组答案,则请按「确定」,这样,程式会再继续跑400代(视你在generation那里的设定而定)
你可以一直按「确定」让程式一直跑,但要知道一件事:不一定会有最佳解,也就是penalty=0的解。当你玩够了,就按「取消」吧,这样程式就会跳回原先的画面。在这里,你必需等个约十秒吧,画面才会变成如下图,多了二个功能。这十秒是让程式把结果写入资料库用的,要有点耐心喔。
按一下「观看排班结果」,选择人员看他的值班日。
你可以切换回去看一下「阿明」的排班意愿(如下图),了解是否有达成
再看一下「值班同仁之姓名」
这是让你了解谁跟你同值班?有没有跟讨厌的人同班?亦或跟美女帅哥同班?
其余功能不多说了,不要剥夺你们自行摸索的乐趣
接下来看功能表最右边那项「排班结果分析」
这个表算是一个总览表,可以让你很快了解某个班表的良窳优缺。
(1)里头有个排班编号,之前我们设定20组解,所以这里会有 1~20个编号,而且每个编号有相对应的「排班惩罚分数」。在此例我们选择1号,分数119.64这个班表
(1)的右侧栏位有所有人的值班天数、周末值班天数、权重等等统计,我们注意一下(2),全部是0,这表示组员对于那天值班或那天不值班的要求都没有违反,表示在这方面,这个班表表现不错。在(3)中,我们可以看到所有人的权重(点数)。大家应有注意到阿花和阿珠点数比平均低了不少,这符合我们之前的设定;但是阿明好像跟平均值差不了多少,所以这个班表在阿明的值班权重上表现并不理想。如果各位回头看阿明的班表,还会发现有不少连续值班的情形,这也就是为什么惩罚分数(penalty)没有达到0,而是119的缘故。
大家可以从1~20选择可以接受的班表。若是都不能接受,那就得回到「演算法参数设定」调整一下参数。我调整了一下「演算法参数设定」再执行一次程式,得到了更好的结果如下图
这个班表虽然阿珠有一班违反她的意愿,但是全体人员的权重比较接近原先的设定,而且比较没有连值的情形出现。惩罚分数(penalty)也比第一次的参数设定所得到的最佳解来的低 (87 vs. 119)
总结一下:
1. 此程式是帮你尽量找到最佳解,但不保证
2. 若不满意某组解,可以改变参数设定重跑,或是用原来的参数多跑几次
3. 有时候你试了很久很久,还是无法得到满意的解,这时请重新检视一下你的要求有没有什么不合理处
2013 年
这个程式到现在都还有人在下载使用,而且遍及各行各业包括:诚品,台大,成大,中国,台北荣总,中山,香港公开大学,诊所等等。2011年后住院医师和实习医师的值班也开始受到一些限制,包括连值和值班时数都向美国ACGME规定看齐,我感到很欣慰。
这个程式并没有做到尽善尽美,有些人要求我加入一些功能,但我现在关心的事不在此,能做的大概就是把C++的原始档开放让大家下载修改,缩短有兴趣者开发的时间。
另外,类似排班这种NP(non-polynomial)问题,基因演算法并非唯一,甚至不是很好的一种解法,这是我投入一段时间后才知道的事,有志者可以朝ACO (ant colony optimization) , SVM(support vector machine), Simulated Annealing 这些方法去尝试或许效果会更好。