第四章 改良式消去迴圈演算法
4.1 搜尋迴圈與演算法流程
此節介紹搜尋迴圈的方式,詳細說明改良式消去迴圈演算法的流程與架 構,並在下一節分析演算法的模擬結果。
4.1-1 搜尋迴圈方法
首先準備基本矩陣,先找出所有元素 1 儲存各種資訊於陣列中,如表 4-1 這些包含上、下、左、右 1 的個數、坐標及位移資訊,而演算法中不管是搜尋迴 圈或是權重機制都是從左上方的點開始往右搜尋到底後換列,如圖 4-1 所示,直 到所有的點都被搜尋過,如此一來保持演算法執行的方向統一避免重覆,以下用 條列式的方式介紹搜尋方法與順序,並以圖 4-2 輔助說明。
表 4-1 每個元素為 1 之陣列
圖 4-1 搜尋時之方向示意圖
1. 從左上方的原點 P(1,1)出發,往右及往下搜尋找到 P(1,2)及 P(4,1)並標記 為第一層,其中 P(1,2)與原點有相同的列數、P(4,1)與原點有相同的行數。
2. 從 P(1,2)往上或下搜尋得到 P(2,2),而 P(4,1)往右搜尋得到 P(4,4),將 P(2,2)及 P(4,4)標記為第二層,其中 P(1,2)與 P(2,2)有相同的行數、P(4,1) 與 P(4,4)有相同的列數。
3. 從 P(2,2)往右或左搜尋得到 P(2,3),而 P(4,4)往上或往下搜尋得到
P(3,4),將 P(2,3)及 P(3,4)標記為第三層,其中 P(2,2)與 P(2,3)有相同的 列數、P(3,4)與 P(4,4)有相同的行數。
且與 P(4,4)有相同的行數則形成 Cycle-6;若有一點 P(X,Y)與 P(2,3)有相 同的行數並且與 P(3,4)有相同的列數則形成 Cycle-8。
圖 4-2 搜尋迴圈示意圖
搜尋迴圈時有兩點需要特別注意:
(1) 在階層搜尋時,必須避免不同階層搜尋到相同的點,這種現在尤其在 cycle-8 時更容易發生。如圖 4-3 所示,空心的點為原點,在往右搜尋時會 先找到 A 點,而同樣地從原點依序往下、往右及往上也會找到 A 點,造成同 一點搜尋兩次的情況,因此在搜尋過程中設定所有點的坐標均不相等即可。
(2) 搜尋的方向不能超過起始點左側的行數,如圖 4-4 以空心點當原點時,搜尋 到第三層也就是虛線框起來的部分,這兩點行數已小於原點;而以 B 點當原 點搜尋時也會搜尋到一樣的迴圈,造成同一個迴圈被搜尋至兩次,所以要以 原點的行數做標準,任何搜尋的路徑只能在原點的右半側。
P(1,1)
P(2,2) P(2,3)
P(X,Y) P(3,4)
P(4,1) P(4,4)
P(1,2)
圖 4-3 造成同一點搜尋兩次之範例
圖 4-4 搜尋時路徑超過原點左半邊之範例
4.1-2 演算法流程與架構
前一章介紹了傳統式迴圈演算法,雖然過程是循序式的將迴圈打斷,但運 算量及複雜度很高,所以我們提出改良式消去迴圈演算法,除了有效打斷消除迴 圈之外,依照每一點包含迴圈的數量訂為權重值,按權重高低消去迴圈以簡化運 算量。
優先權消去迴圈演算法流程:
此行數為基準時已搜尋過
B A
(1) 找出基本矩陣中為 1 的元素,並創造一個空陣列儲存各種資訊。
(2) 清空元素 1 中全部參數的初始值。
(3) 從最左上角的 1 開始,找出所有 1 的 (x,y) 坐標及上、下、左、右四個 方向為 1 的個數及坐標,並儲存在陣列中供搜尋迴圈使用。
(4) //搜尋 Cycle-4、6、8,同時將每條迴圈的坐標及資訊存入陣列。
(5) 從原點 H(i,j)往右、往下找到兩點 H(i,k)、H(m,j),若有一點坐標為 H(m,k) 則此 4 點形成 cycle-4。
(6) for H(i,k)上方及下方的 1 為 H(p,k)、H(m,j)右方的 1 為 H(m,n),
若有一點坐標為 H(p,n) 則此 6 點形成 cycle-6。
(7) for H(p,k)右方及左方的 1 為 H(p,r)、H(m,n)上方及下方的 1 為 H(s,n),若有一點坐標為 H(s,r) 則此 8 點形成 cycle-8。
(8) end (9) end
(10) //優先權一次式消去迴圈法 (11) while (元素 1 最大迴圈數>0)
(12) if ((某一點元素迴圈數==最大迴圈數)&&(位移旗標==0)) (13) for (該元素所有可位移的值 P = (1~L-1) )
(14) 檢查該元素包含的 constraint,分別記錄滿足 constraint 及 不滿足的數量(這邊定義參數為 rig 與 wro)。
(15) if (rig > wro)
(16) 比較該元素所有的位移值並取 P 使(rig-wro)有最大值。
(17) else
(18) 該元素位移值 P=0 ; (19) end
(20) 該元素的位移旗標設為 1;
(21) 更新基本矩陣的最大迴圈數; rig:滿足 constraint 總數 wro:不滿足 constraint 總數
Yes
演算法分段以行數說明與分析如下:
(1)~(3)行:首先準備一個基本矩陣,所有在矩陣中的 1 均產生如表 4-1 的 清單並將初始值歸零。如圖 4-1 從矩陣的左上角開始搜尋 1 的位置記錄坐標,
並同時找出上下左右四個方向的 1,將其坐標與數量儲存。因為每個元素包含許 多 cycle,每條 cycle 都會轉成 constraint 存於清單。
(4)~(9)行:每一點包含 4 個方向的資訊,我們利用此資訊尋找迴圈。在 4.1-1 節說明了搜尋方法,但此方法只適用於專門搜尋 Cycle-4、6、8 的情況,
cycle 的基本定義為從原點出發繞過一條封閉的路徑回到原點,且每一個節點不 能通過第 2 次,所以提出兩點方法避免找到錯誤或重覆的 cycle。然而這邊所搜 尋是未擴展之前的基本矩陣,經由模擬結果證明圖 4-3 的情形在擴展矩陣之後 有可能造成新的 cycle-8,如果我未考慮及搜尋到此種迴圈,即便程式結果指出 已打斷所有迴圈,新的擴展矩陣還會有未打斷的 cycle 產生。為了使程式能完 全打斷所有的迴圈,提出兩條輔助方法:
(1) 以圖 4-5 當作範例,若藍色 AB 共點則勢必造成紅色 CD 共點,反之亦然;
這並不符合構成迴圈的形式,因為當搜尋至 A、B 點時下一步是往水平方向 搜尋而找到 C、D 點,找到 C、D 點後下一步往垂直方向搜尋,若 C、D 共點 的話則無法找到搜尋的路徑,所以除了讓 A、B 和 C、D 不共點之外取消其 它避免共點的限制。
(2) 在[13]文獻中提到所有搜尋的點的行數必須大於原點的行數( d > j ), 但 這種說法並不周延,我的模擬實驗出現了一種情況,以圖 4-6 所示藍點為 原點,各點的數字指移位量,在此種情形下原點被搜尋到兩次,利用式 3-11 得到
∑
Δ = +P 0 (14)+(14)+ −( 28)=0,代表在擴展矩陣後會形成新的 cycle-8,並不符合作者演算法中的描述,因此我修改為所有點的行數必須 大於或等於原點的行數。圖 4-5 若 A、B 共點則 C、D 共點將無法找到搜尋路徑之圖例
圖 4-6 原點被搜尋到兩次之範例
(10)~(28)行:權重指元素 1 所包含迴圈總數,這也是本演算法主要的精神,
依照每個 1 不同權重來執行迴圈消去的優先次序。當初的構想是當該元素擁有 最高權重時,能一次打斷迴圈的數量必會高於其它元素。首先找出具有最高權 重的元素,接著把所有的位移值 (1~L-1) 代入 constraint 表,統計各別滿足 及不滿足 constraint 的總數,首要條件為滿足的總量必須大於不滿足的總量,
再來選擇讓兩者相差最大的位移值,也就是該位移值能打斷更多的迴圈、更少 重新連結的迴圈,充份利用每一次打斷的機會。另外再準備 1 張表單,把滿足 的 constraint 搬到此表單、不滿足的維持在原表單,如圖 4-7 所示方便處理迴 圈資訊與數量。若滿足的總量小於不滿足的總量,則該元素位移值設為零,繼
A B
C D
14
28
0 0
0
0 0
原點
續往下一個擁有高優先權的元素動作,最後只要有判斷執行該元素時均拉起位 移旗標表示已處理過。每執行完一次位移動作時,程式將重新整理取得最新的 優先權順序,再執行位移動作盡可能打斷所有的迴圈。因為整體演算法執行到 最後才會將基本矩陣擴展,不可能每次統計最新優先權時執行搜尋迴圈的動 作,於是在這邊使用一個技巧,直接讀取圖 4-7 中未被打斷迴圈的數量,就可 快速且精準地得到各元素所剩餘的迴圈數。
圖 4-7 表單處理 constraint 動向之示意圖