最近在看一些演算法的**,其中涉及了asap和alap演算法,這兩種演算法由很多的應用背景,在此僅闡述對於圖中節點執行順序的選擇。首先從字面上理解,asap是as soon as possible,是盡快執行的意思,即當圖中節點沒有依賴關係和資源限制的前提下就可以馬上執行;相反的,alap是as late as possible的意思,即在圖中關鍵路徑執行結束前拖到最晚執行。從字面上理解有點籠統,下面我們可以通過乙個例子來理解:
圖a是dfg圖,圖中節點有兩種,三角形和圓形分別代表不同的操作,如加操作、乘操作、載入操作、儲存操作等,圖中的邊表示不同操作之間的依賴關係,圖b是asap演算法下的排程方式,在第0步時,0 1 3 4這四個節點沒有父節點的限制,則盡快在第一步執行,當第0步執行完畢後,在圖中去掉這四個節點,所以2 5 7這三個節點又沒有了父節點的依賴限制,所以在第1步就執行2 5 7,依次類推,在第2步執行6,在第3步執行8。圖c是alap演算法,可以看出,0->2->6->8是這個圖的關鍵路徑,即最長的路徑,所有節點要盡量靠後執行,節點是根據關鍵路徑反向盡快執行,圖中的7節點可以在第1步或者第2步執行則選擇靠後的第2步,4節點可以選擇在第0步和第1步執行,則選擇靠後的第1步。
輸入**件如下所示,其中每一行的第乙個數字表示乙個節點,後面的所有數字表示為第乙個數字的子節點,對於後面的所有數字來說,第乙個數字使他們的父節點。每一行都是如此。例如第一行表示,節點0是父節點,8 23 26 28 31 37 39 46全部是0節點的子節點。
0 8 23 26 28 31 37 39 46
8 28 31 37 39
23 8 28 31 37 39
26 8 23 28 31 37 39
31 28 37 39
37 28 39
39 28
46 8 23 26 28 31 37 39
53 13
#include#include#include#include #includeusing namespace std;
/*儲存圖節點*/
struct node ;
void input(vector> &vec_dti, string filename);
void initdata(map&map, vector> indata);
void asap(vector> &output_asap, mapm);
void alap(vector> &output_alap, mapm);
void delate(map&m, vectorkey );
void print(vector> output);
void main()
/*fuction:input
將檔案中標示圖的節點以二維組的形式存放在vector中*/
void input(vector> &vec_dti,string filename)
vec_dti.push_back(temp_line); //儲存所有資料
temp_line.clear(); }}
/*fuction:initdata
初始化node結構體,儲存在map中,記錄圖的各個節點的依賴關係
所給的**件,結構像乙個鄰接表,每一行的第乙個數字代表節點名字,後面的所有節點都是第乙個節點的子節點*/
void initdata(map&m,vector> indata)
m[tmp.name] = tmp;
}//每行第乙個節點都是後面所有節點的父節點,所以,將父節點的資訊儲存到每個節點的父節點陣列中
for (int i = 0; i < indata.size(); i++)
}}/*fuction:print
計算結果儲存在乙個二維的vector中,將結果輸出在終端上*/
void print(vector> output)
cout << endl; }}
/*fuction:asap
將圖中所有沒有父母節點先執行,並在圖中刪除這些已執行的節點,直到圖中所有節點被刪除*/
void asap(vector> &output_asap, mapm)
it++;
} output_asap.push_back(tmp);
delate(m, tmp);//將tmp陣列中的所有節點以及有關的依賴關係刪除
} }/*fuction:alap
alap的關鍵是要倒著用asap排程,然後反轉結果即可,將圖中所有沒有孩子節點先執行,並在圖中刪除這些已執行的節點,直到圖中所有節點被刪除,最後反轉結果順序*/
void alap(vector> &output_alap, mapm)
it++;
} output_alap.push_back(tmp);
delate(m, tmp);//刪除tmp
} int n = output_alap.size() ;
for (int i = 0; i < n/2; i++)
}/*function:delate
刪除圖中的某些節點,即key中儲存的節點,再刪除節點時,要將圖中所有有關這些節點的依賴關係刪除,即以這些刪除節點為父節點或孩子節點的依賴關係刪除*/
void delate(map&m, vectorkey)
else
}for (itr = child.begin(); itr != child.end();)
else
}} it->second.parent = parent;
it->second.child = child;
it++;
}//從map中刪掉key
for (int t = 0; t < key.size(); t++) }
}
演算法和演算法分析
一 演算法的基本概述 演算法是為了解決某類問題而規定的乙個有限長的操作序列。乙個演算法必須滿足以下五個重要特性 1 有窮性2 確定性3 可行性 4 有輸入5 有輸出 二 設計演算法的原則 1.正確性 2.可讀性 3 健壯性 4.高效率與低儲存量需求 三 演算法的時間複雜度簡介 語句頻度 語句重複執行...
演算法和演算法分析
演算法是為了解決某類問題而規定的乙個有限長的操作序列。五個特性 1.有窮性2.確定性3.可行性4.輸入5.輸出 1.正確性2.可讀性3.健壯性4.高效性 1.問題規模和語句頻度 不考慮計算機的軟硬體等環境因素,影響演算法時間代價的最主要因素是問題規模。問題規模是演算法求解問題輸入量的多少,是問題大小...
演算法和演算法分析
1.定義 是對特定問題求解步驟的一種描述,它是指令的有限序列,其中每一條指令表示乙個或多個操作。2.特徵 1 有窮性 乙個演算法必須在執行有窮步之後結束,即演算法中的每個步驟在有限的時間內完成。2 確定性 每條指令必須有確定的含義,無二義性,在任何條件下,演算法都只有一條執行路徑。3 可行性 乙個演...