169 lines
4.7 KiB
Matlab
169 lines
4.7 KiB
Matlab
% Construct the graph with the maximum possible s-metric, given the degree
|
|
% sequence; the s-metric is the sum of products of degrees across all edges
|
|
% Source: Li et al "Towards a Theory of Scale-Free Graphs"
|
|
%
|
|
% INPUTs: degree sequence: 1xn vector of positive integers (graphic)
|
|
% OUTPUTs: edge list of the s-max graph, mx3
|
|
%
|
|
% GB: last updated, November 9 2012
|
|
|
|
function gA=buildSmaxGraph(deg)
|
|
|
|
didj=[];
|
|
for ii=1:length(deg)-1
|
|
for jj=ii+1:length(deg)
|
|
% [deg_i*deg_j, 'B', deg_i, deg_j, 'B', i, j] - 'B' for sorting purposes
|
|
didj=[didj; deg(ii)*deg(jj), 2, deg(ii), deg(jj), 2, ii,jj];
|
|
end
|
|
end
|
|
|
|
didj=sortrows(didj);
|
|
didj=didj(end:-1:1,:); % reverse to decreasing order
|
|
|
|
w=deg; % number of remaining stubs - originally equals the degrees
|
|
[~,maxdegind]=max(deg); % the index of the maximum degree
|
|
A=[maxdegind];
|
|
B = setdiff([1:length(deg)],maxdegind);
|
|
|
|
wA=deg(maxdegind); % remaining stubs in A
|
|
dB=sum(deg(B)); % total degree of unattached vertices in B
|
|
|
|
gA=[]; % initialize empty edge list
|
|
|
|
while sum(w)>0 % while there are still stubs to connect
|
|
|
|
% STEP 1 (LINK SELECTION)
|
|
if size(didj,1)==0
|
|
if sum(w)>0 % connect all stubs left
|
|
|
|
wstubs=[];
|
|
cnt=1;
|
|
for ww=1:length(w)
|
|
while w(ww)>0
|
|
wstubs=[wstubs; cnt, ww];
|
|
w(ww)=w(ww)-1;
|
|
cnt=cnt+1;
|
|
end
|
|
end
|
|
|
|
for xx=1:size(wstubs,1)/2
|
|
n1=wstubs(xx,2);
|
|
n2=wstubs(xx+size(wstubs,1)/2,2);
|
|
|
|
ind1=find(gA(:,1)==n1);
|
|
|
|
if length(ind1)==0
|
|
first_case=false;
|
|
else
|
|
ind2=find(gA(ind1,2)==n2);
|
|
if length(ind2)==0
|
|
first_case=false;
|
|
else
|
|
first_case=true;
|
|
end
|
|
end
|
|
|
|
ind2=find(gA(:,1)==n2);
|
|
if length(ind2)==0
|
|
second_case=false;
|
|
else
|
|
ind1=find(gA(ind2,2)==n1);
|
|
if length(ind1)==0
|
|
second_case=false;
|
|
else
|
|
second_case=true;
|
|
end
|
|
end
|
|
|
|
if first_case %if [n1,n2,1] in gA and not(n1==n2):
|
|
gA=[gA; n1,n2,1];
|
|
elseif second_case % if [n2,n1,1] in gA and not(n1==n2):
|
|
gA=[gA; n2,n1,1];
|
|
elseif n1==n2
|
|
gA=[gA; n1,n2,1];
|
|
end
|
|
|
|
end
|
|
end
|
|
return % gA
|
|
|
|
end
|
|
|
|
% eliminate zero stubs in didj
|
|
didj_new=[];
|
|
for ii=1:size(didj,1)
|
|
if w(didj(ii,6))>0 && w(didj(ii,7))>0
|
|
didj_new=[didj_new; didj(ii,:)];
|
|
end
|
|
end
|
|
didj=didj_new;
|
|
clear didj_new
|
|
|
|
if size(didj,1)==0; continue; end
|
|
|
|
for ii=1:size(didj,1)
|
|
|
|
edge=[didj(ii,6), didj(ii,7)];
|
|
|
|
if length(find(A==edge(1)))>0 && length(find(A==edge(2)))>0
|
|
didj(ii,:)=[didj(ii,1),100,w(edge(1)),w(edge(2)),100,edge(1),edge(2)];
|
|
elseif length(find(A==edge(1)))>0 && length(find(B==edge(2)))>0
|
|
didj(ii,:)=[didj(ii,1),100,w(edge(1)),w(edge(2)),2,edge(1),edge(2)];
|
|
elseif length(find(B==edge(1)))>0 && length(find(A==edge(2)))>0
|
|
didj(ii,:)=[didj(ii,1),2,w(edge(1)),w(edge(2)),1,edge(1),edge(2)];
|
|
didj(ii,:)=[didj(ii,1),100,w(edge(2)),w(edge(1)),2,edge(2),edge(1)];
|
|
else
|
|
didj(ii,:)=[didj(ii,1),2,w(edge(1)),w(edge(2)),2,edge(1),edge(2)];
|
|
end
|
|
|
|
end
|
|
|
|
didj=sortrows(didj);
|
|
didj=didj(end:-1:1,:);
|
|
link_select=[didj(1,6),didj(1,7)]; % select the first link that starts in A
|
|
|
|
% STEP 2 (LINK ADDITION)
|
|
n1=link_select(1);
|
|
n2=link_select(2);
|
|
|
|
% if (n1 in A and n2 in B) or (n1 in B and n2 in A)
|
|
if (length(find(A==n1))>0 && length(find(B==n2))>0) || (length(find(B==n1))>0 && length(find(A==n2))>0)
|
|
gA=[gA; n1, n2, 1];
|
|
if length(find(A==n1))>0 && length(find(B==n2))>0
|
|
B = setdiff(B,n2);
|
|
A=[A; n2];
|
|
end
|
|
if length(find(B==n1))>0 && length(find(A==n2))>0
|
|
B = setdiff(B,n1);
|
|
A=[A; n1];
|
|
end
|
|
|
|
w(n1)=w(n1)-1;
|
|
w(n2)=w(n2)-1;
|
|
wA=sum(w(A));
|
|
dB=sum(deg(B));
|
|
|
|
didj=didj(2:size(didj,1),:); % remove link from top
|
|
|
|
elseif length(find(A==n1))>0 && length(find(A==n2))>0
|
|
% check the tree condition
|
|
if dB==2*length(B)-wA
|
|
didj=didj(2:size(didj,1),:);
|
|
|
|
elseif wA==2 && length(B)>0 % results in a disconnected graph
|
|
didj=didj(2:size(didj,1),:);
|
|
|
|
else % add it!
|
|
gA=[gA; n1,n2,1];
|
|
|
|
w(n1)=w(n1)-1;
|
|
w(n2)=w(n2)-1;
|
|
|
|
wA=sum(w(A));
|
|
dB=sum(deg(B));
|
|
|
|
didj=didj(2:size(didj,1),:);
|
|
end
|
|
end
|
|
end
|