Filter löschen
Filter löschen

Finding a chain in an adjacency matrix

9 Ansichten (letzte 30 Tage)
Josue Sandoval
Josue Sandoval am 25 Okt. 2016
Kommentiert: Walter Roberson am 30 Okt. 2016
Hi everyone,
I have a binary matrix A representing edges in a graph, of size n x m. It is easy to know if elements i and j are connected by an edge: I simply look up if A(i,j)==1. However, I want to know if there is a chain of size k (or smaller) that connects i and j. For example, A(i,k)==1 and A(k,j)==1. Any ideas or maybe a pre-existing function that I have not found?
I have no interest whatsoever in finding the shortest path, I just care if there is any. Thanks
  2 Kommentare
David Goodmanson
David Goodmanson am 25 Okt. 2016
Hello Josue, If A is an adjacency matrix, could you explain how it is not a square matrix?
Josue Sandoval
Josue Sandoval am 30 Okt. 2016
I meant the size is (m*n) for each the number of rows and the number of columns. Sorry about that.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Walter Roberson
Walter Roberson am 25 Okt. 2016
T = eye(size(A)) ;
found = false;
for n = 0 : k - 1
if T(i, j)
found = true;
break;
end
T = T * A;
end
chain_exists = found | T(i, j);
  4 Kommentare
Josue Sandoval
Josue Sandoval am 30 Okt. 2016
I understood what you meant after reading Seidel's shortest path algorithm (not the code but the idea). I implemented something completely brute force but that seems to work. I put the code below in case you want to see it. I think it should work.
A different question is simpler: I need to make a new figure, so I just type "figure". However, I want that the new figure keeps every plot in the old figure. I put hold on's everywhere but I guess they don't do the work. Any ideas?
%number=percentage of the society married;
%avgdistance=average distance between marriages;
%race
n=4;m=2;p=1;q=0.2;
rng(10,'twister');
x=rand(m,n); y=rand(m,n);
%sex=round(rand(m,n));
k=round(.4*n);kk=round(.4*n);
temp = [ones(m,kk), zeros(m,k), round(rand(m,n-k-kk))]
[~, idx] = sort( rand(m,n), 2)
sex = temp(sub2ind(size(temp), ndgrid(1:m,1:n), idx))
women=find(sex');men=find(~sex');
x1=reshape(x',1,n*m); y1=reshape(y',1,n*m); sex1=reshape(sex',1,n*m);
%Part 1: edges
colorstring = 'kbmcgy';hold on
for i = 1:m
for k=1:n
if sex(i,k)==1;
plot(x(i,k),y(i,k),'P', 'Color', colorstring(i),'MarkerFaceColor', colorstring(i),'MarkerSize',12)
else
plot(x(i,k),y(i,k),'O', 'Color', colorstring(i),'MarkerFaceColor', colorstring(i),'MarkerSize',10)
end
end
end
%Part 2: interracial edges
adj=zeros(m*n); boxes=(((m-1)*m)/2)*n^2;inter_edges=randsample(boxes,floor(boxes*q));
rr=1;
for i=1:(m*n)
for j=n+floor((i-1)/n)*n+1:(m*n)
if i~=j
if any(rr==inter_edges)
adj(i,j)=1;
end
rr=rr+1;
end
end
end
for i=1:n*m
for j=1:n*m
if adj(i,j)==1
plot([x1(1,i) x1(1,j)],[y1(1,i) y1(1,j)],':')
end
end
end
%Part 3: intraracial edges
intra_edges=rand(n*m);rr=0;
for i=1:n*m
rr=floor((i-1)/n);
for j=i+1:(rr*n)+n
if intra_edges(i,j)<p %
adj(i,j)=1;
end
end
end
adj=triu(adj,-1)+triu(adj)'
for k=1:m
for i=1:n
for j=i+1:n
if adj(j,i)==1
plot([x(k,i) x(k,j)],[y(k,i) y(k,j)],'Color', colorstring(k))
end
end
end
end
adj2=adj*adj;
adj3=zeros(m*n);
for i=1:m*n
for j=i+1:m*n
if adj2(i,j)+adj(i,j)>0
adj3(i,j)=1
end
end
end
adj3=triu(adj3,-1)+triu(adj3)'
%Part 4: distances
distance=zeros(n*m,m*n);
for i=1:m*n
for j=i:m*n
if i==j
distance(i,j)=NaN;
else
if adj3(i,j)==0
distance(i,j)=NaN;
else
if sex1(i)==sex1(j)
distance(i,j)=NaN;
else
distance(i,j)=sqrt((x1(i) - x1(j))^2 + (y1(i) - y1(j))^2);
end
end
end
end
end
distance=triu(distance,-1)+triu(distance)'
%Part 5: marriages
marr=zeros(1,m*n);
marriage=zeros(1,m*n);
for i=1:n*m
[~, marr(1,i)]=min(distance(i,:));
end
c=1;
while c <= min(nnz(sex),numel(sex)-nnz(sex))
for i=1:n*m
if i==marr(marr(i));
marriage(i)=marr(i);
end
end
for i=find(marriage==0)
if marriage(marr(i))~=0;
distance(i, marr(i))=NaN;
%distance(MARR(i),i)=NaN;
end
end
for i=1:n*m
[~, marr(1,i)]=min(distance(i,:));
end
c=c+1;
end
for i=1:m*n
if marriage(i)==i
marriage(i)=0;
end
end
hold on
figure
hold on
for i=1:n*m
if marriage(i)~=0
plot([x1(1,i) x1(1,marriage(1,i))],[y1(1,i) y1(marriage(1,i))],'red','LineWidth',3)
end
end
%Part 6: welfare measures
number=size(find(marriage),2)/2;
avgdist=0;
for i=find(marriage>0)
avgdist=avgdist+distance(i,marriage(i));
end
avgdist=avgdist/(2*size(find(marriage>0),2));
race=0;
for i=1:m*n
if marriage(i)>0
if marriage(i)<=(1+floor((i-1)/n))*n && marriage(i)>floor((i-1)/n)*n
race=race+1;
end
end
end
race=race/2;race=number-race;
formatSpec = '#marriages %.0f (%.0f), avgdist %.4f, p=%.2f, q=%.2f';
str = sprintf(formatSpec,number,race,avgdist,p,q)
title(str);
race=race/number
number=(number*2)/(n*m)
adj3
Walter Roberson
Walter Roberson am 30 Okt. 2016
If you want a new figure (that is, a completely new graphics window) and you want it to start out with what is in another figure, then you need to copyobj() appropriate children of the old figure into the new figure.
If what you want is a new subplot (that is, a section of an window that can be independently drawn in) and you want it to start out with what is in another subplot, then you need to copyobj() appropriate children of the old axes into the new axes.
Doing a proper copyobj of children of a figure is trickier than doing a proper copyobj of children of an axes. Some of the tricks are shown at http://www.mathworks.com/matlabcentral/answers/262265-duplicating-an-imshow-image-into-a-new-figure-without-using-imshow#comment_332459

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Thorsten
Thorsten am 25 Okt. 2016
Bearbeitet: Thorsten am 25 Okt. 2016

Kategorien

Mehr zu Graph and Network Algorithms finden Sie in Help Center und File Exchange

Produkte

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by