2017年8月1日 星期二

(Java) K法與P法 求最小擴張樹


  1. class Kruskal {  
  2.     public static int VERTS=6;  
  3.     public static int v[]=new int[VERTS+1];  
  4.     static K_Node NewList = new K_Node();  
  5.     public static void main(String[] args) {          
  6.         int Data[][] =          /*圖形陣列宣告*/  
  7.             { {1,2,6},{1,6,12},{1,5,10},{2,3,3},{2,4,5},  
  8.               {2,6,8},{3,4,7},{4,5,9},{4,6,11},{5,6,1} };  
  9.         for(int i = 0 ; i < 10 ; i++ )  
  10.         NewList.Create(NewList.FindFree(),Data[i][2],Data[i][0],Data[i][1],0);            
  11.           
  12.         NewList.printList();  
  13.           
  14.         System.out.println("K氏法最小擴張樹");  
  15.         mintree() ;  
  16.         System.out.println("Prim法最小擴張樹");  
  17.         findmincost_prim() ;  
  18.     }  
  19.     //Prim法  
  20.     public static int U[]=new int[VERTS+1];//U集合  
  21.     public static int V[]=new int[VERTS+1];//V集合  
  22.     public static void findmincost_prim()  
  23.     {  
  24.         //u 已經有1個頂點  
  25.         int u = 1 ;  
  26.         int count = 1 ;  
  27.         int min = 999 , minv = 0 ;  
  28.             while(true){  
  29.               
  30.             for(int v = 0 ; v <VERTS-1; v++){  
  31.                 if(NewList.from[v] == u){  
  32.                     if(V[NewList.to[v]] == 0 && min > NewList.val[v]){  
  33.                           
  34.                         min = NewList.val[v] ;  
  35.                         minv = v ;  
  36.                     }  
  37.                 }  
  38.             }  
  39.             if(count == u){//假設u數量等於count表全部檢查完  
  40.             System.out.print("起始頂點["+NewList.from[minv]+"]  終止頂點[");  
  41.             System.out.print(NewList.to[minv]+"]  路徑長度["+NewList.val[minv]+"]");  
  42.             System.out.println("");       
  43.             V[NewList.to[minv]] = 1;//V集合已加入倒U集合  
  44.             //U[NewList.to[minv]] = 1;  
  45.             count++ ;  
  46.             u = 1 ;//找出值後 u重製開開始重新判斷最小值  
  47.             min = 999 ; minv = 0 ;  
  48.             }else  
  49.                 u++ ;    
  50.             if(count == U.length-1)//當U數量已飽和跟V一樣  
  51.                 break ;  
  52.         }  
  53.     }  
  54.     //K氏法  
  55.     public static int findmincost()  
  56.     {     
  57.         int a=0;  
  58.         int minval=100;  
  59.         int retptr=0;  
  60.         while(NewList.Next[a] !=-1)  
  61.         {  
  62.             if(NewList.val[a]<minval && NewList.find[a]==0)  
  63.             {  
  64.                 minval=NewList.val[a];  
  65.                 retptr = a ;  
  66.             }  
  67.             a++ ;  
  68.         }  
  69.         NewList.find[retptr]=1;//設定已經用過  
  70.         return retptr;  
  71.     }  
  72.     public static void mintree(){  
  73.         int pointer = NewList.Header ;  
  74.         int retptr=0;//找出最小位置  
  75.         int a=0;  
  76.         while(pointer  !=-1){  //走訪串列  
  77.             retptr = findmincost() ;  
  78.             v[NewList.from[retptr]]++ ;  v[NewList.to[retptr]]++ ;  
  79.             if(v[NewList.from[retptr]] > 1 && v[NewList.to[retptr]] > 1){           //判斷會不會造成迴路  
  80.                 v[NewList.from[retptr]]-- ;  v[NewList.to[retptr]]-- ;  
  81.             }else{  
  82.                 System.out.print("起始頂點["+NewList.from[retptr]+"]  終止頂點[");  
  83.                 System.out.print(NewList.to[retptr]+"]  路徑長度["+NewList.val[retptr]+"]");  
  84.                 System.out.println("");       
  85.             }  
  86.             pointer = NewList.Next[pointer];  
  87.         }  
  88.     }  
  89.   
  90. }  
  91. class K_Node{  
  92.     int Header = 0 ; //起始  
  93.     int MaxLength = 20;         // 定義鏈結串列最大長度  
  94.     int from[] = new int[MaxLength];//  A  
  95.     int to[] = new int[MaxLength];  //    B  
  96.     int find[] = new int[MaxLength];      
  97.     int val[] = new int[MaxLength]; //長度  
  98.     int Next[] = new int[MaxLength];    // 鏈結串列的下一個節點位置  
  99.     public K_Node ()                // Node建構子  
  100.     {  
  101.         for ( int i = 0 ; i < MaxLength ; i++ )  
  102.             Next[i] = -2;       // -2表示未用節點  
  103.     }  
  104.     public void Create(int FreeNode,int DataNum,int fromNum,int toNum,int findNum){  
  105.         int pointer ; //現在的節點位置  
  106.         if(Header == FreeNode){  
  107.             val[Header] = DataNum ;  
  108.             from[Header] = fromNum ;  
  109.             to[Header] = toNum ;  
  110.             find[Header] = findNum ;  
  111.             Next[Header] = -1;  
  112.         }else{  
  113.             pointer = Header;   // 現在的節點為首節點                              
  114.             val[FreeNode] = DataNum;// 設定資料編號  
  115.             from[FreeNode]=fromNum;  
  116.             find[FreeNode]=findNum;  
  117.             to[FreeNode]=toNum;  
  118.                         // 設定資料名稱  
  119.             Next[FreeNode] = -1;    // 將下個節點的位置,-1表示空節點  
  120.                         // 找尋鏈結串列尾端  
  121.             while ( Next[pointer] != -1)  
  122.                 pointer = Next[pointer];  
  123.   
  124.                         // 將新節點串連在原串列尾端  
  125.             Next[pointer] = FreeNode;     
  126.   
  127.   
  128.         }  
  129.           
  130.           
  131.           
  132.     }  
  133.    public int FindFree(){//搜尋可用節點  
  134.        int i ;  
  135.        for( i = 0; i < MaxLength ; i++){  
  136.            if( Next[i] == -2 )//未使用  
  137.                break ;  
  138.        }  
  139.        return i ;  
  140.    }  
  141.   public void printList(){  
  142.       int pointer = Header ;  
  143.       while(pointer != -1){  
  144.          System.out.println("邊線 : "+from[pointer] + "-->"+to[pointer]+"      長度 : "+val[pointer] );  
  145.          pointer = Next[pointer];  
  146.       }  
  147.   }  
  148.   
  149. }  

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。