Как говорится в сообщении об ошибке, вам нужен ваш массив E
как 2D, формы (50,50)
, а не 1D массив формы (2500)
.
Существует несколько способов обойти это :
E
после присвоения ему E = E.reshape(len(W1),len(W0))
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))
Если вы заметили, в создаваемых вами матрицах смежности есть отчетливый образец. В частности, они симметричны и полосчатые . Вы можете воспользоваться этим фактом, чтобы легко создавать свои матрицы с помощью функции diag
(или функции spdiags
, если вы хотите создать разреженную матрицу). Вот как вы можете создать матрицу смежности для каждого случая, используя приведенный выше образец матрицы в качестве примера:
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
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
Для каждого узла в графе добавьте соединение вправо и одно вниз. Проверьте, не выходите ли вы за пределы сетки. Рассмотрим следующую функцию, которая строит матрицу смежности.
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
Ваш текущий код не так уж плох. Так или иначе вам нужно перебрать все пары соседей. Если вам действительно нужно оптимизировать код, я бы посоветовал:
1 <= i <= (N * M)
[iM, i + 1, i + M, i-1]
по часовой стрелке Обратите внимание, что для получения всех соседних пар узлов:
i% M! = 0
(поскольку Matlab основан не на 0, а на 1) i> M
Это приведет к единственному циклу (но с таким же количеством итераций N * M), не вызывает sub2ind () и имеет только два операторы if в цикле.
Ради удовольствия, вот решение для построения матрицы смежности путем вычисления расстояния между всеми парами точек в сетке (очевидно, не самый эффективный способ)
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)')) )