Kruskal 演算法是將各邊線依權值大小由小到大排列, 接著從權值最低的邊開始架構最小的成本擴張樹, 如果加入的邊會造成迴路則捨棄不用, 直到加了 n-1 個邊為止. 這個方法看似不難, 我們直接來看如何以 K 氏法得到範例下圖中的最小成本擴張樹 :
步驟一 : 將所有邊線的成本列出並由小到代排序 :
步驟二 : 選擇成本最低的一條邊做為架構最小成本擴張樹的起點. Edge(B,C)->3
步驟三 : 依步驟1所建立表格, 依序加入邊線.
步驟四 : C-D 加入會形成迴路, 所以跳過.
完成圖 :
範例代碼 :
- #include
- using namespace std;
- #define VERTS 6 //圖形頂點樹
- class edge {
- public:
- int from, to;
- int find, val;
- class edge *next;
- edge(){
- from = -1;
- to = -1;
- find = 0;
- val = -1;
- }
- };
- typedef class edge enode;
- typedef edge* penode;
- int v[VERTS+1];
- char ptrName[7] = {'-','A','B','C','D','E','F'};
- penode _findmincost(penode head) { //搜尋成本最小的邊
- int dv = 100;
- penode ptr, retptr;
- ptr = head;
- while(ptr!=NULL) {
- if(ptr->val < dv && ptr->find ==0) {
- retptr = ptr;
- dv = ptr->val;
- }
- ptr = ptr->next;
- }
- retptr->find = 1;
- return retptr;
- }
- void _minTree(penode head) { // 最小成本擴張樹副程式
- penode ptr, mceptr;
- int result = 0;
- ptr = head;
- for(int i=0; i<=VERTS; i++)
- v[i] = 0;
- while(ptr!=NULL) {
- mceptr = _findmincost(head);
- if(v[mceptr->from] >0 && v[mceptr->to]>0) {
- // 形成迴圈, 跳過
- } else {
- result++;
- v[mceptr->from] = 1;
- v[mceptr->to] = 1;
- cout << "起始定點[" << ptrName[mceptr->from] << "]\t終止頂點[" << ptrName[mceptr->to] << "]\t路徑長度[" << mceptr->val << "]" << endl;
- }
- if(result==(VERTS-1))
- break;
- }
- }
- void main() {
- // 成本陣列
- int data[10][3] = {{1,2,6}, {1,6,12}, {1,5,10}, {2,3,3}, {2,4,5}, {2,6,8}, {3,4,7}, {4,6,11}, {4,5,9}, {5,6,16}};
- penode head, ptr, newnode;
- head = NULL;
- cout << "建立圖形串列: " << endl;
- for(int i=0; i<10; i++) {
- newnode = new enode;
- newnode->from = data[i][0];
- newnode->to = data[i][1];
- newnode->val = data[i][2];
- newnode->next = NULL;
- newnode->find = 0;
- if(head == NULL) {
- head = newnode;
- ptr = head;
- } else {
- ptr->next = newnode;
- ptr = ptr->next;
- }
- }
- ptr = head;
- while(ptr!=NULL) { // 列印圖形串列
- cout << "起始定點[" << ptrName[ptr->from] << "]\t終止頂點[" << ptrName[ptr->to] << "]\t路徑長度[" << ptr->val << "]" << endl;
- ptr = ptr->next;
- }
- cout << "建立最小成本擴張樹: " << endl;
- _minTree(head);
- delete head;
- }
This message was edited 9 times. Last update was at 16/05/2010 16:30:21
沒有留言:
張貼留言