上一篇最後提到,我決定換另一種方式來畫 Graph。
一開始會讓使用者調整 Vertex 數量,是因為當節點很少時,其實很容易直接用肉眼判斷最短路徑;但當資料越來越多,就很難直接看出答案,這時才更能感受到演算法的用途。
實際做出來後,效果確實如我想像的很酷 ![]()
但相對地,每次產生新的資料節點位置、連線數量都會跟著改變,畫面也比較複雜。
回到我一開始做這個專案的目的,是希望可以一邊學演算法,一邊透過畫面理解演算法到底在做什麼。
所以最後決定先把 Graph 簡單化:
固定 Vertex、固定 Edge,只讓 Weight 改變。
這樣每次產生新資料時,Graph 的結構都一樣,但因為 Weight 不同,最後找到的最短路徑還是可能不同。
首先固定的是 Vertex 的數量與位置。
這次使用 A~G 共 7 個 Vertex,並直接設定每個 Vertex 的 x、y 座標:
const NODE_POSITIONS = {
A: { x: 60, y: 236 },
B: { x: 280, y: 50 },
C: { x: 280, y: 236 },
D: { x: 280, y: 414 },
E: { x: 545, y: 50 },
F: { x: 545, y: 244 },
G: { x: 760, y: 380 },
}
因此不管產生幾次新資料,A~G 都會待在相同的位置。
這次我也不再隨機決定 Edge,而是直接固定哪些 Vertex 可以互相連線。
例如:
A: { B: 4, C: 2, D: 7 }
B: { A: 4, C: 3, E: 1, F: 5 }
代表 A 可以走到 B、C、D,而 B 可以走到 A、C、E、F。
因為目前使用的是無向圖,所以 A 可以走到 B,B 也要可以走回 A。
最後固定成 12 條 Edge,而「產生新資料」時,只重新產生每條 Edge 的 Weight。
這樣 Graph 的外型不會一直變,但每次的 Weight 不同,Dijkstra 找到的最短路徑仍然可能改變。
現在 Vertex 的位置與 Edge 都已經固定,其實就不需要上一篇說的棋盤處理
直接使用 SVG:
<circle>
<line>
<text>
再利用前面設定好的 x、y 座標決定 Vertex 要畫在哪裡。
這樣反而更接近前面學習 Graph 時看到的「節點+連線」形式,也更容易觀察 Dijkstra 接下來到底走過哪些地方。

最後實作出來的版本,就是:
位置固定、連線固定、Weight 隨機。
對我現在來說,這樣比完全隨機的 Graph 更適合拿來學習 Dijkstra,因為我可以把注意力放在:
「Weight 改變之後,為什麼最短路徑也跟著改變?」
下一篇就可以正式讓 Dijkstra 的執行過程一步一步顯示在這張 Graph 上。