MATLAB: нахождение количества уникальных преемников каждого узла из матрицы

Я новичок в программном обеспечении MATLAB и в настоящее время пытаюсь изучить его без формального обучения, и у меня довольно простой вопрос.

У меня есть матрица смежности, соответствующая орграфу, и я хочу посмотреть, какие узлы связаны переходом с другими узлами в сети. Итак, учитывая матрицу смежности с n узлами:

D = [0,1,1,0,0,0,0;
     0,0,0,1,1,0,0;
     0,0,0,0,1,0,0;
     0,0,0,0,0,1,0;
     0,0,0,0,0,1,0;
     0,0,0,0,0,0,1;
     0,0,0,0,0,0,0]

Я хочу найти количество уникальных преемников для каждого узла. В настоящее время я использую для этого код, но он очень неуклюж; каждый раз, когда я меняю матрицу, мне нужно менять код. Это выглядит следующим образом:

D1 = logical(D^1 + D^2 + D^3 + D^4 + D^5 + D^6 + D^7);

D1(logical(eye(size(D1)))) = 0;

B = sum(transpose(D1));

Есть ли способ привести код в порядок и сделать его более общим!?


person Owen    schedule 18.09.2013    source источник
comment
похоже, мы редактировали друг друга :)   -  person Amro    schedule 18.09.2013
comment
@Amro О, да, мы это сделали, ха-ха! Я только что отправил вам электронное письмо с благодарностью, надеюсь, вы его получили!   -  person Owen    schedule 18.09.2013
comment
оценил, рад, что смог помочь!   -  person Amro    schedule 18.09.2013


Ответы (3)


Вот простой способ:

N = length(D);
DD = zeros(N);
for i=1:N
    DD = DD + D^i;
end
DD = logical(DD);
DD(1:N+1:end) = false;
B = sum(DD,2);

Возможно, ссылка на объяснение значения степеней матрицы смежности.


Вы можете использовать следующий код для визуализации результирующего графика (обратите внимание, что график не различает направленные/ненаправленные ребра):

% circular layout
t = linspace(0,2*pi,N+1)'; t(end) = [];
xy = [cos(t) sin(t)];

% plot graph and label nodes
subplot(121), gplot(DD, xy, '-*')
text(xy(:,1), xy(:,2), num2str((1:N)'), 'BackgroundColor',[.4 .9 .5], ...
    'VerticalAlign','bottom', 'HorizontalAlign','right')
axis square off

% adjacency matrix
subplot(122), spy(DD)
set(gca, 'XTick',1:N, 'YTick',1:N)
ylabel('from'), xlabel('to')

график

person Amro    schedule 18.09.2013

Вы можете заменить D^1 + D^2 + D^3 + D^4 + D^5 + D^6 + D^7 на D*(D^size(D,1)-eye(size(D)))/(D-eye(size(D))) и использовать .*~eye(size(D)), чтобы избавиться от диагонали и получить

B=sum(logical(D*(D^size(D,1)-eye(size(D)))/(D-eye(size(D)))).*~eye(size(D)), 2)';

Однако лично я предпочитаю ваш код. Легче понять, что он делает.

person Mohsen Nosratinia    schedule 18.09.2013

Ты можешь измениться

D1 = logical(D^1 + D^2 + D^3 + D^4 + D^5 + D^6 + D^7);

to

aux = (arrayfun(@(x) D^x, 1:length(D), 'UniformOutput',false));
D1 = any(cat(3,aux{:}),3);

который действителен для всех размеров D.

person Luis Mendo    schedule 18.09.2013