1. 程式人生 > >資料結構之圖(帶權圖 迪傑斯特拉演算法)

資料結構之圖(帶權圖 迪傑斯特拉演算法)

// 主要思想是: 每次尋找最小的邊  這樣的話從上一個節點 到這個節點的值 是最小的 當找到最小的邊時,把final[v] = true 表示從原點到這個節點的最小值 已經找到了

 

<!DOCTYPE html>
<html>
<head>
    <title>實現函式</title>
    <meta charset="utf-8">
    <script>

    // 稠密圖  鄰接矩陣
    class DenseGraph{
        // n為定點個數  directed為無向或有向
        constructor(n, directed){
            this.n = n;
            this.m = 0;
            this.directed = directed
            this.data = []
            for(var i =0; i<n; i++){
                this.data[i] = []
                for(var j=0; j<n; j++){
                    this.data[i][j] = -1;
                }
            }
                
        }

        V() { return this.n }
        E() { return this.m }

        // 新增一條邊
        addEdge(v, w, weight){
            
            this.data[v][w] = weight;
            
            
            this.m++;
        }

        // 判斷是否有邊
        hasEdge(v, w){
            console.log(this.data[v])
            return (this.data[v] && this.data[v][w] > 0);
        }

        DIJ(){
            // 為求得v0 頂點到其餘頂點v的最短路徑p[v]及其帶權長度D[v]
            // 若p[v][w]為true,則w是v0到v的一個頂點
            // final[v] 為true,當且僅當 已經求得從v0到v的最短路徑
            var p = [];
            var final = [];
            var D = [];

            for(var v=0; v<this.n; v++){
                final[v] = false; D[v] = this.data[0][v];
                p[v] = [];
                for(var w=0; w<this.n; w++) { p[v][w] = false; } // 設定空路徑
                if(D[v] != -1){ p[v][0] = true; p[v][v] = true; } // 如果有值的話 那麼v0到v就有路徑
            }

            final[0] = true; D[0] = -1;

            // 開始迴圈 每次求得結果都加入到S集中(就是final[x] = true)
            for(var i=0; i<this.n; i++){
                // 每次求最小的值 並加入到S中
                var min = 99999;
                for(var w=0; w<this.n; w++){
                    if( D[w]<min && D[w] > 0 && !final[w]){
                        // 記錄位置 和 值
                        v = w;
                        min = D[w];
                        
                    }
                }
                
                final[v] = true; //把v加入到s中
                for(var j=0; j<this.n; j++){
                    // 如果發現路徑經過v節點 使得整體路徑變小了 則更新
                    if(!final[j] && ((min + this.data[v][j]) < D[j] || D[j] == -1)&& this.data[v][j] > 0){
                        
                        D[j] = min + this.data[v][j];
                        
                        p[j] = p[v]; p[j][j] = true; // p[w] = p[v] + [w]都為true
                    }
                }
            }

            return {
                p,
                final,
                D
            }
        }
    }

    var dg = new DenseGraph(6, true);
    var  arr = [[0, 2, 10], [0, 4, 30], [0, 5, 100], [1, 2, 5], [2, 3, 50], [3, 5, 10], [4, 3, 20], [4, 5, 60]];
    for(var i=0,len=arr.length; i<len; i++){
        dg.addEdge(arr[i][0], arr[i][1], arr[i][2]);
    }
    console.log(dg.DIJ())
    
    </script>

</head>
<body>
    
</body>
</html>