[matlab] 22.matlab圖論實例 最短路問題與最小生成樹 (轉載)
阿新 • • 發佈:2018-09-14
dijkstra 分享 data 幫助 存儲 生成樹 jks lap open
最短路問題之 Floyd
某公司在六個城市 c1c1,c2c2,….,c6c6 中有分公司,從 cici 到 cjcj 的直接航程票價記在下述矩陣的 (ii,jj) 位置上。 (∞∞表示無直接航路),請幫助該公司設計一張城市 c1c1 到其它城市間的票價便宜的路線圖。
變量解釋:
- n 是公司個數
- a 存儲航路票價,最後結束循環存儲的是最便宜票價
- path 存儲每對頂點之間最短路徑上所經過的定點的序號,也就是”中轉站”序號
clear;clc; n = 6; a = [0 50 inf 40 25 10; 0 0Floyd 算法15 20 inf 25; 0 0 0 10 20 inf; 0 0 0 0 10 25; 0 0 0 0 0 55; 0 0 0 0 0 0]; % 由於 a 是無向圖,航路票價沿著正對角線對稱,可以只寫出右上角 a = a + a‘; % 由於票價沿正對角線對稱,即完整的 a 為 a + a 的轉置 path = zeros(6); % 定義 path 為 6 x 6 的矩陣 for k = 1:n for i = 1:n for j = 1:n if a(i,j) > a(i,k) + a(k,j)% 如果從 i 城市到 j 城市的票價大於從 i 城市到 k,再從 k 到 j 城,那麽 i 到 j 城肯定不是最短路徑 a(i,j) = a(i,k) + a(k,j); % 更新 i 到 j 的最少票價 path(i,j) = k; % 同時記錄下 i 到 j 的"中轉站" % 註意下一次更新會覆蓋上一次 path(i,j) 存儲的,所以其實 path(i,j)中存儲的 只是最後一個 "中轉站" end end end end a,path
最短路問題之 dijkstra 算法
變量解釋:
- n 是公司個數
- m 存儲票價
- pb 存放標號信息,當 pb(ii) = 1,當前第 ii 節點已標號,否則為 0 未標號
- d 表示最短通路的值
- path 存儲每對頂點之間最短路徑上所經過的定點的序號
- tb 表示當前未標記的點的矩陣
- fb 表示當前已標記的點的矩陣
- min 求最小值之前的預設值
- lastpoint 暫存當前選定的一個已標記點
- newpoint 暫存當前選定的一個未標記點
- plus 即已知點到未知點距離
clear;clc; n = 6; m = [0 50 inf 40 25 10; 0 0 15 20 inf 25; 0 0 0 10 20 inf; 0 0 0 0 10 25; 0 0 0 0 0 55; 0 0 0 0 0 0]; m = m + m‘; pb(1:length(m))= 0; % 將所有未標記點置 0 pb(1) = 1; % 選擇第 1 個點標記 d(1:length(m))=0; % 將全部最短距離置 0 path(1:length(m))=0; % 將全部"中轉站"置 0 while sum(pb) < 6 % 當狀態不全為 1(即未標記全部點時) tb = find(pb==0); % 找到未標記的點的矩陣 fb = find(pb==1); % 找到已標記的點的矩陣 min = 1000000; lastpoint =1; newpoint =1; % 從每一個已標記點,到每一個未標記點 for i=1:length(fb) for j=1:length(tb) plus = d(fb(i)) + m(fb(i),tb(j)); % 計算點之間的距離 if min > plus min = plus; % 更新最小值 lastpoint = fb(i); % 記錄當前最小值下已標記點 newpoint = tb(j); % 記錄當前最小值下未標記點 end end end d(newpoint) = min; % 更新最終的最小值 pb(newpoint) = 1; % 更新當前未標記點狀態(未標記——》標記) path(newpoint) = lastpoint; % 更新當前點上一個點 end d,pathdijkstra 算法
最小生成樹問題之prim
變量解釋:
- n 頂點個數
- a 存儲圖
- result 第一、二、三行分別表示生成樹邊的起點、終點、權集合
- p 存放圖的最小生成樹中的頂點
- tb 存放當前未選擇的頂點
- temp 存放當前最小生成樹連通的所有邊
- d 存放最小的邊值
- jb 存放最小的邊值中已經選作最小生成樹的點的矩陣(也許不止一個)
- kb 存放最小的邊值中未選作最小生成樹的點的矩陣(也許不止一個)
- j 確定已經選作最小生成樹的點的矩陣中的第一個點
- k 確定未被選作最小生成樹的點的矩陣中的第一個點
clear; clc; n = 7; a = [0 50 60 inf inf inf inf; 0 0 inf 65 40 inf inf; 0 0 0 52 inf inf 45; 0 0 0 0 50 30 42; 0 0 0 0 0 70 inf; 0 0 0 0 0 0 inf; 0 0 0 0 0 0 0];% 由於 a 是無向圖,航路票價沿著正對角線對稱,可以只寫出右上角 a = a + a‘; % 由於票價沿正對角線對稱,即完整的 a 為 a + a 的轉置 result =[]; % 定義出 result p =1; % 當前只有第 1 個點為最小生成樹的節點 tb =2:n; % 當前未作為最小生成樹的節點 while length(result) ~= n - 1 % 當生成樹的邊為 節點數-1 時,即最小生成樹生成(n個點 n-1 條邊) temp = a(p,tb); % 存放當前最小生成樹連通的所有邊,用來求最短邊 temp = temp(:); % 將 temp 轉化成 1 列,讓求出的最短距離只有一個值 d = min(temp); % 求出最短距離 [jb,kb] = find(a(p,tb)==d); % 根據最短距離,找出哪些點符合最短距離的情況 j = p(jb(1)); % 從當前最小生成樹中的點中 k = tb(kb(1)); % 和當前未進入最小生成樹的點中挑出第一個點 result = [result,[j;k;d]]; % 表示生成樹邊的起點、終點、權集合 p = [p,k]; % 剛剛選的點進入最小生成樹 tb(find(tb==k)) =[]; % 將進入最小生成樹的點剔除掉 end resultprim 算法
最小生成樹問題之kruskal (待補充)
[matlab] 22.matlab圖論實例 最短路問題與最小生成樹 (轉載)