[解決済み] MATLABで隣接行列を構築する
2022-02-25 09:23:01
質問
サイズN×Mのグリッド上に配置された点の集合を考える。 このような隣接行列を構築するために 隣接する点は接続されている。
例えば、3×3グリッドのグラフの場合。
1-2-3
| | |
4-5-6
| | |
7-8-9
対応する隣接行列があるはずです。
+---+------------------------------------------------------+
| | 1 2 3 4 5 6 7 8 9 |
+---+------------------------------------------------------+
| 1 | 0 1 0 1 0 0 0 0 0 |
| 2 | 1 0 1 0 1 0 0 0 0 |
| 3 | 0 1 0 0 0 1 0 0 0 |
| 4 | 1 0 0 0 1 0 1 0 0 |
| 5 | 0 1 0 1 0 1 0 1 0 |
| 6 | 0 0 1 0 1 0 0 0 1 |
| 7 | 0 0 0 1 0 0 0 1 0 |
| 8 | 0 0 0 0 1 0 1 0 1 |
| 9 | 0 0 0 0 0 1 0 1 0 |
+---+------------------------------------------------------+
おまけに、4連結の近傍点でも8連結の近傍点でも解けるはずだ、です。
o o o o
o X o vs. o X o
o o o o
これが今のところあるコードです。
N = 3; M = 3;
adj = zeros(N*M);
for i=1:N
for j=1:M
k = sub2ind([N M],i,j);
if i>1
ii=i-1; jj=j;
adj(k,sub2ind([N M],ii,jj)) = 1;
end
if i<N
ii=i+1; jj=j;
adj(k,sub2ind([N M],ii,jj)) = 1;
end
if j>1
ii=i; jj=j-1;
adj(k,sub2ind([N M],ii,jj)) = 1;
end
if j<M
ii=i; jj=j+1;
adj(k,sub2ind([N M],ii,jj)) = 1;
end
end
end
ループを回避するにはどうしたらよいでしょうか?
解決方法は?
お気づきのように、作成される隣接行列には明確なパターンがあります。具体的には、それらは対称的であり
帯状
. この事実を利用し,行列を簡単に作成するために
diag
関数(または
spdiags
関数を使用します)。ここでは、上のサンプル行列を例にして、それぞれの場合の隣接行列の作り方を説明します。
4連結の隣人。
mat = [1 2 3; 4 5 6; 7 8 9]; % Sample matrix
[r, c] = size(mat); % Get the matrix size
diagVec1 = repmat([ones(c-1, 1); 0], r, 1); % Make the first diagonal vector
% (for horizontal connections)
diagVec1 = diagVec1(1:end-1); % Remove the last value
diagVec2 = ones(c*(r-1), 1); % Make the second diagonal vector
% (for vertical connections)
adj = diag(diagVec1, 1)+diag(diagVec2, c); % Add the diagonals to a zero matrix
adj = adj+adj.'; % Add the matrix to a transposed copy of
% itself to make it symmetric
そして、次のような行列が出来上がります。
adj =
0 1 0 1 0 0 0 0 0
1 0 1 0 1 0 0 0 0
0 1 0 0 0 1 0 0 0
1 0 0 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 0 0 1
0 0 0 1 0 0 0 1 0
0 0 0 0 1 0 1 0 1
0 0 0 0 0 1 0 1 0
8コネクテッド・ネイバーズ
mat = [1 2 3; 4 5 6; 7 8 9]; % Sample matrix
[r, c] = size(mat); % Get the matrix size
diagVec1 = repmat([ones(c-1, 1); 0], r, 1); % Make the first diagonal vector
% (for horizontal connections)
diagVec1 = diagVec1(1:end-1); % Remove the last value
diagVec2 = [0; diagVec1(1:(c*(r-1)))]; % Make the second diagonal vector
% (for anti-diagonal connections)
diagVec3 = ones(c*(r-1), 1); % Make the third diagonal vector
% (for vertical connections)
diagVec4 = diagVec2(2:end-1); % Make the fourth diagonal vector
% (for diagonal connections)
adj = diag(diagVec1, 1)+... % Add the diagonals to a zero matrix
diag(diagVec2, c-1)+...
diag(diagVec3, c)+...
diag(diagVec4, c+1);
adj = adj+adj.'; % Add the matrix to a transposed copy of
% itself to make it symmetric
そして、次のような行列が出来上がります。
adj =
0 1 0 1 1 0 0 0 0
1 0 1 1 1 1 0 0 0
0 1 0 0 1 1 0 0 0
1 1 0 0 1 0 1 1 0
1 1 1 1 0 1 1 1 1
0 1 1 0 1 0 0 1 1
0 0 0 1 1 0 0 1 0
0 0 0 1 1 1 1 0 1
0 0 0 0 1 1 0 1 0
関連
-
[解決済み] 第一差分フィルタ
-
[解決済み] MATLAB: symからlogicalへの変換ができない
-
[解決済み] MATLABでベクトルからNaNを除去する
-
[解決済み] MATLABで「連結される配列の次元が一致しない」というエラーをデバッグする。
-
[解決済み] matlabで補強行列を作成し、縮小行エシュロン形式を作成する。
-
[解決済み] Matlabによる最急降下法の実装
-
[解決済み] MATLABでマシンイプシロンを計算する方法は?
-
[解決済み] MATLABで分数を10進数に変換する【重複】。
-
[解決済み] 匿名関数の微分
-
[解決済み] キュービックスプライン補間と多項式補間の比較
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】2つのベクトル間の角度 matlab
-
[解決済み] double 型の入力引数に対して未定義の関数 'int' が存在する [重複] 。
-
[解決済み] matlabでrandnを持つ確率変数の範囲はどうなっていますか?
-
[解決済み] パーフカーブで1つの値を返す - matlab
-
[解決済み] Wolfram AlphaとMATLABでは伝達関数のプロットが異なる
-
[解決済み] 匿名関数の微分
-
[解決済み] Matlabでファイル名を変更する - movefileがファイルの代わりにフォルダを作成する
-
[解決済み] Matlabでのリッジ回帰とOLS回帰
-
[解決済み] Ax = B の形の行列を解く ==> エラー。行列が特異に近い、またはスケールが悪い
-
[解決済み] MATLABでヒストグラムを正規化する方法は?