Построить матрицу смежности в MATLAB

Как говорится в сообщении об ошибке, вам нужен ваш массив E как 2D, формы (50,50), а не 1D массив формы (2500).

Существует несколько способов обойти это :

  1. измените свой E после присвоения ему
    E = E.reshape(len(W1),len(W0))
    
  2. сначала создайте E с правильной формой, затем используйте ваши i и j, чтобы проиндексировать его
    E = np.zeros((len(W1),len(W0)))
    
    for i in range (len(W1)):
        for j in range (len (W0)):
            w1 = np.array([W1[i],W0[j]])
            yn = np.dot(w1.T,X)
            E[i][j] = (1./50)*(np.sum((y-yn)**2))
    
30
задан Peter Mortensen 23 July 2010 в 16:31
поделиться

4 ответа

Если вы заметили, в создаваемых вами матрицах смежности есть отчетливый образец. В частности, они симметричны и полосчатые . Вы можете воспользоваться этим фактом, чтобы легко создавать свои матрицы с помощью функции 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
24
ответ дан 28 November 2019 в 00:04
поделиться

Для каждого узла в графе добавьте соединение вправо и одно вниз. Проверьте, не выходите ли вы за пределы сетки. Рассмотрим следующую функцию, которая строит матрицу смежности.

function  adj = AdjMatrixLattice4( N, M )
    % Size of adjacency matrix
    MN = M*N;
    adj = zeros(MN,MN);

    % number nodes as such
    %  [1]---[2]-- .. --[M]
    %   |     |          |
    % [M+1]-[M+2]- .. -[2*M]
    %   :     :          :
    %   []    []   ..  [M*N]     

    for i=1:N
        for j=1:N
            A = M*(i-1)+j;          %Node # for (i,j) node
            if(j<N)                
                B = M*(i-1)+j+1;    %Node # for node to the right
                adj(A,B) = 1;
                adj(B,A) = 1;
            end
            if(i<M)
                B = M*i+j;          %Node # for node below
                adj(A,B) = 1;       
                adj(B,A) = 1;
            end            
        end
    end    
end

Пример как выше AdjMatrixLattice4(3,3)=

 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
0
ответ дан 28 November 2019 в 00:04
поделиться

Ваш текущий код не так уж плох. Так или иначе вам нужно перебрать все пары соседей. Если вам действительно нужно оптимизировать код, я бы посоветовал:

  • перебирать индексы узлов i, где 1 <= i <= (N * M)
  • не используйте sub2ind () для повышения эффективности, соседями узла i являются простые [iM, i + 1, i + M, i-1] по часовой стрелке

Обратите внимание, что для получения всех соседних пар узлов:

  • у вас есть только для вычисления "правильных" соседей (т. е.горизонтальные ребра) для узлов i% M! = 0 (поскольку Matlab основан не на 0, а на 1)
  • , вам нужно только вычислить "вышележащих" соседей (то есть вертикальных ребер) для узлов i> M
  • есть аналогичное правило для диагональных ребер

Это приведет к единственному циклу (но с таким же количеством итераций N * M), не вызывает sub2ind () и имеет только два операторы if в цикле.

2
ответ дан 28 November 2019 в 00:04
поделиться

Ради удовольствия, вот решение для построения матрицы смежности путем вычисления расстояния между всеми парами точек в сетке (очевидно, не самый эффективный способ)

N = 3; M = 3;                  %# grid size
CONNECTED = 8;                 %# 4-/8- connected points

%# which distance function
if CONNECTED == 4,     distFunc = 'cityblock';
elseif CONNECTED == 8, distFunc = 'chebychev'; end

%# compute adjacency matrix
[X Y] = meshgrid(1:N,1:M);
X = X(:); Y = Y(:);
adj = squareform( pdist([X Y], distFunc) == 1 );

А вот код для визуализации матрицы смежности и графа подключенных точек:

%# plot adjacency matrix
subplot(121), spy(adj)

%# plot connected points on grid
[xx yy] = gplot(adj, [X Y]);
subplot(122), plot(xx, yy, 'ks-', 'MarkerFaceColor','r')
axis([0 N+1 0 M+1])
%# add labels
[X Y] = meshgrid(1:N,1:M);
X = reshape(X',[],1) + 0.1; Y = reshape(Y',[],1) + 0.1;
text(X, Y(end:-1:1), cellstr(num2str((1:N*M)')) )

8_connected 4_connected

14
ответ дан 28 November 2019 в 00:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: