目前有兩個已發展的藥物排程演算法,One-Medicine-at-A-Time (OMAT) 和
One-Dose-at-A-time (ODAT) [8],它們是根據即時系統排程理論[9]所設計出來的演算法,
這一章將會介紹這兩個演算法它們所運用的模型,以及它們的主要概念和用途。
2.2.1 排程模組
2.2.1.1 資源模組
OMAT 和 ODAT 運用即時系統排程理論的資源模組 (Resource Model) 的概念。它在排 程時分配給每一藥物一個虛擬處理器 (virtual processor PM) 和一個虛擬資源 (virtual resource RM) 來處理排程時的相互時間關係。PM 負責處理同一藥物的每劑服用時間的 間隔關係 (intra-dose separations),RM 負責處理有交互作用的藥物(或食物)之間的服用時 間間隔關係 (inter-dose separations)。當我們在計算服藥時程時,我們將每一藥物 (medicine) 視為一個任務 (task) ,每一劑 (dose) 的服用視為一個在 PM 上執行的工作 (job),一連串的工作組合成一個任務。一個工作的起始點 (start time) 代表使用者必須 服藥的時間點 (in-take time)。一個藥物的時程就是一個時間表,每一個時間代表每一劑 藥物必須被服用的時間點。
7
2.2.1.2 資源分配規則
排程演算法利用 PM 來處理連續劑量之間的正確時間間隔。它將每一劑藥物視為一個在 PM 上執行的非搶占式工作 (non-preemptable job1),每一個工作的執行時間 (execution time)為最小時間間隔 smin,也就是每一個工作會占用 PM 最小時間間隔長度的時間,
PM 同一時間只能執行一個工作。另外,它將最大時間間隔長度視為兩個連續工作之間 的相對期限時間 (relative-deadline),以確保連續劑量的服用時間不超出最大時間間隔。
為了避免藥物-藥物的衝突或藥物-食物的衝突,排程演算法利用 RM 來處理衝突藥物(食 物)之間的服用時間間隔關係。任一個藥物被排程時,會占用所有與它有衝突關係的藥 物的虛擬資源 RM,從該工作開始的時間點往前占用 minfrinterferer 時間,往後占 用 mintointerferer 時間。換句話說,它利用占用別人的資源來擋住與它有衝突關 係的藥物,也就是任何一個工作只有在 PM 和 RM 沒有被占用時,才能開始執行。
2.2.1.3 優先順序方案
OMAT 和 ODAT 根據藥物的優先順序 (priority) 來做為排程的順序。它利用幾種優先順 序的決定方法,分配給每種藥物優先順序,演算法在執行時會從最高優先順序的藥物排 到最低優先順序的藥物。優先順序決定方法有下列五種:
1) MVF (most-victimized-first):它根據最糟情況的阻斷時間 (worst case blocking time) 來決定優先順序,也就是在最糟情況下,RM 可能被占用的時間長度,時間長度 越長,優先順序越高。
2) MIF (most-interactions-first):它根據衝突藥物的數量來決定優先順序,也就是衝 突藥物越多的藥物,優先順序越高。
3) SSDF (shortest-separation-difference-first):它根據時間間隔的差距長度來決定優先 順序,也就是最小時間間隔跟最大時間間隔的差,相差越短的,優先順序越高。
1 一個非搶占式工作是一種從執行的開始到結束都不容許被中斷的工作
(A job is non-preemptable if it must be executed from start to completion without interruption)
8
4) RM (rate-monotonic):它根據藥物服用的週期來決定優先順序,週期越短的,優 先順序越高。
5) EDF (earliest deadline first):這是一種動態決定優先順序的方法,它會根據現有工 作的期限時間來決定不同劑量的優先順序,期限時間越早的,優先順序越高。
2.2.2 排程演算法
這一小節介紹 OMAT 與 ODAT 的演算法概念,表格 3 和表格 4 分別為 OMAT 和 ODAT 的虛擬碼,它們使用一個布林植 feasibleSchedule 來表示排程器是否排出一個合理 的服藥時程,當 feasibleSchedule 的值為真時,MIS 陣列的內容即為正確排程的結 果,也就是所有藥的服藥時程。
2.2.2.1 一次一藥法 (One-Medicine-at-A-time, OMAT)
OMAT 排程演算法會根據藥物的優先順序,一次排一種藥,依次排完所有藥的服藥時程。
在排程時,OMAT 會排出每種藥在療程期裡的所有劑量 (dose) 的服用時程。它利用 Resource Model 來確保所有劑量之間的安全時間間隔。OMAT 排程法會指定給每種藥一 個固定的優先順序,所以 EDF 優先順序決定法在 OMAT 裡不適用。
OMAT 試著排出所有藥的時程,而且在遵守用藥規則和限制上,表現的比 ODAT 更好,
但是 OMAT 適合傾向準時服藥的使用者,因為當使用者延遲或遺忘吃藥時,整個時程 就必須重排。
Basic OMAT 在排程時會盡可能排出緊密的時程,讓每劑 (dose) 的服用時程越接近越好,
這也導致排程失敗的機率較高,因為當有藥物衝突時,較高優先順序的藥可能把時間都 占滿,以致低優先順序的藥很難成功排程。為解決此問題所發展出的另一版本的 OMAT,
稱為 advanced OMAT,它在排程時會將每劑的服用時程盡可能的安排在靠近期限時間 (respective deadline),也就是它會盡可能排出時間鬆散的時程,大幅提高了排程成功的 機率。
9
2.2.2.2 一次一劑量法 (One-Dose-at-A-time, ODAT)
ODAT 排程演算法每次只排出下一劑的服用時程,它會根據 EDF 動態優先順序決定法
ListMedicationScheduleSpec MSS[number_medicines]
PrioritySchemes PS OUTPUT:
Boolean feasibleSchedule
List MedicineIntakeSchedule MIS[number_medicines]
PROCEDURE:
FOR every MSS[i]{
CREATE JobModel, ResourceModel CREATE integer latestStartTime } ASSIGN priority to every MSS[i]
based on PrioritySchemes PS SET feasibleSchedule to TRUE
FOR every MSS[i] according to descending priority{
SET latestStartTime of MSS[i] to 0
SET ResourceModel.feasible of MSS[i] to TRUE WHILE ResourceModel.feasible of MSS[i] is TRUE {
FOR i from JobModel.release_time to
JobModel.deadline of MSS[i] { IF ResourceModel.processor[i]==0 and ResourceModel.resource[i]==0 {
SET Tavail to I THEN BREAK }}
IF Tavail is found
IF Tavail>=MSS[i].TheraphyDuration THEN BREAK APPEND Tavail to ResourseModel.Schedule
SET latestStartTime of MSS[i] to Tavail
SET JobModel.release_time to (Tavail+ nsmin) SET JobModel.deadline to
(JobModel.release_time + asmax) FOR k from Tavail to (Tavail + nsmin)
SET ResourceModel.process[k] of MSS[i] to 1
SET ResourceModel.feasible of MSS[i] to FALSE SET feasibleSchedule to FALSE }
IF feasibleSchedule is TRUE {
SET MIS[i] to ResourceModel.Schedule of MSS[i]}
RETURN feasibleSchedule and MIS[]
END PROCEDURE
表格 3: OMAT 虛擬碼
10 INPUT:
List MedicationScheduleSpec MSS[number_medicines]
PrioritySchemes PS OUTPUT:
Boolean feasibleSchedule
List MedicineIntakeSchedule MIS[number_medicines]
PROCEDURE:
FOR every MSS[i]
CREATE JobModel, ResourceModel
SET numberMedicines to the length of MSS[] array CREATE integer array
ReleaseTimeCurrentJobs[numberMedicines]
SET ScheduleComplete to 0 SET feasibleSchedule to TRUE
WHILE (feasibleSchedule is TRUE) and
(scheduleComplete < numberMedicines){
FIND MSS[i] with earliest time in
ReleaseTimeCurrentJobs[] and highest priority FOR k from JobModel.release_time
to JobModel.deadline of MSS[i]{
IF ResourceModel.processor[k]==0 and ResourceModel.resource[k]==0{
SET Tavail to k THEN BREAK }}
IF Tavail is found
IF Tavail >= MSS[i].TheraphyDuration {
INCREMENT scheduleComplete THEN BREAK } APPEND Tavail to ResourseModel.Schedule APPEND ResourceModel.Schedule to MIS[i]
SET JobModel.release_time to (Tavail+nsmin) SET JobModel.deadline to
(JobModel.release_time + asmax)
SET ReleaseTimeCurrentJobs[i] to(Tavail+nsmin) FOR k from Tavail to (Tavail + nsmin)
SET ResourceModel.process[k] of MSS[i] to 1 FOR every interferer MSS[i].IP[j] {
FOR k from
SET feasibleSchedule to FALSE } RETURN feasibleSchedule and MIS[]
END PROCEDURE
表格 4: ODAT 虛擬碼
11