我自覺很失職,第二版出來那麼久了,卻始終沒有告訴讀者如何使用。忙是一回事,寫使用說明這事很耗時則是另一個原因。此外寫完了有多少人看?有發揮什麼影響?這些不是我能知道的,簡單的說:寫了半天,卻沒有可預見的報償,這才是我一天拖過一天的最大原因。
那就開始吧!
剛登入的畫面如下:
這版的結構跟第一版不同,在第一版裡,使用者沒有等級的分別;但這一版的使用者有權限差別。
各位拿到的都是”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 這些方法去嘗試或許效果會更好。