FormationControlSimulation/SOURCE/networks-toolbox/canonicalNets.m

360 lines
7.8 KiB
Matlab
Raw Normal View History

2019-06-17 14:31:50 +07:00
% Constructing edge lists for simple canonical graphs, ex: trees and lattices.
%
% INPUTS: number of nodes, network type, branch factor (for trees only).
% Network types can be 'line','cycle','star','btree','tree',
% 'hierarchy','trilattice','sqlattice','hexlattice', 'clique'
% OUTPUTS: edge list (mx3)
%
% Note: Produces undirected graphs, i.e. symmetric edge lists.
% Other functions used: symmetrizeEdgeL.m, adj2edgeL.m
% GB: last updated: Oct 27 2012
function el=canonicalNets(n,type,b)
if strcmp(type,'line')
el=buildLine(n);
elseif strcmp(type,'cycle')
el=buildCycle(n);
elseif strcmp(type,'star')
el=buildStar(n);
elseif strcmp(type,'clique')
el=buildClique(n);
elseif strcmp(type,'btree')
el=buildBinaryTree(n);
elseif strcmp(type,'tree')
el=buildTree(n,b);
elseif strcmp(type,'hierarchy')
el=buildHierarchy(n,b);
elseif strcmp(type,'trilattice')
el=buildTriangularLattice(n);
elseif strcmp(type,'sqlattice')
el=buildSquareLattice(n);
elseif strcmp(type,'hexlattice')
el=buildHexagonalLattice(n);
else
printf('invalid network type; see canonicalNets.m header\n');
el = 'invalid network type';
return
end
%---- canonical nets functions -----------------------------------
function el_line=buildLine(n) % line .............................
el_line = [[1:n-1]' [2:n]' ones(n-1,1)];
el_line = symmetrizeEdgeL(el_line);
function el_cyc=buildCycle(n) % cycle ...........................
el_cyc = [[1:n-1]' [2:n]' ones(n-1,1)];
el_cyc = [el_cyc; 1 n 1];
el_cyc = symmetrizeEdgeL(el_cyc);
function el_star=buildStar(n) % star .............................
el_star = [ones(n-1,1) [2:n]' ones(n-1,1)];
el_star = symmetrizeEdgeL(el_star);
function el_clique = buildClique(n) % clique .....................
% clique:= complete graph with "n" nodes
el_clique = adj2edgeL(ones(n)-eye(n));
function el_bt=buildBinaryTree(n) % binary tree ..................
el_bt=[];
for i=2:n
if mod(i,2)==0
el_bt=[el_bt; i i/2 1];
else
el_bt=[el_bt; i (i-1)/2 1];
end
end
el_bt=symmetrizeEdgeL(el_bt);
function el=buildTree(n,b) % a general tree .....................
% tree with n "nodes" and branch factor "b"
nodes=1;
queue=1;
el=[];
while nodes < n
if nodes+b > n
% add (n-nodes) to first stack member
for i=1:n-nodes
el=[el; queue(1) i+nodes 1];
end
nodes=n;
else
% add b new edges:
for bb=1:b
el=[el; queue(1) nodes+bb 1];
queue=[queue nodes+bb];
end
queue=queue(2:length(queue)); % remove first member
nodes=nodes+b; % update node number
end
end
el=symmetrizeEdgeL(el);
function el=buildHierarchy(n,b) % a hierarchy ...................
% build a tree with n nodes and b as a branch factor,
% where nodes on one level are connected
% INPUTs: number of nodes - n, branch factor - b
% OUTPUTs: edge list
L=ceil(log(1+n*(b-1))/log(b)); % L=log(1+n(b-1))/log(b)
el=buildTree(n,b); % build the base
% add the cross-level links
for k=1:L
start_node=1+round((b^(k-1)-1)/(b-1));
for bb=1:b^(k-1)-1
if start_node+bb-1>n || start_node+bb>n
el=symmetrizeEdgeL(el);
return
end
el=[el; start_node+bb-1, start_node+bb,1];
end
end
el=symmetrizeEdgeL(el);
function el_tr=buildTriangularLattice(n) % triangular lattice
% build triangular lattice with n nodes
% as close to a "square" shape as possible
el_tr=[]; % initialize edge list
x=factor(n);
if numel(x)==1
el_tr=[el_tr; n 1 1];
n=n-1;
x=factor(n);
end
if mod(numel(x),2)==0 % if there's an even number of factors, split in two
f1=prod(x(1:numel(x)/2));
f2=prod(x(numel(x)/2+1:numel(x)));
elseif mod(numel(x),2)==1
f1=prod(x(1:(numel(x)+1)/2));
f2=prod(x((numel(x)+1)/2+1:numel(x)));
end
% the lattice will be f1xf2
% inner mesh
for i=2:f1-1
for j=2:f2-1
% (i,j)->f2*(i-1)+j
el_tr=[el_tr; f2*(i-1)+j f2*(i-2)+j 1];
el_tr=[el_tr; f2*(i-1)+j f2*(i)+j 1];
el_tr=[el_tr; f2*(i-1)+j f2*(i-1)+j-1 1];
el_tr=[el_tr; f2*(i-1)+j f2*(i-1)+j+1 1];
el_tr=[el_tr; f2*(i-1)+j f2*i+j+1 1]; % added for tri lattice
end
end
% four corners
el_tr=[el_tr; 1 2 1];
el_tr=[el_tr; 1 f2+1 1];
el_tr=[el_tr; 1 f2+2 1]; % added for tri lattice
el_tr=[el_tr; f2 f2-1 1];
el_tr=[el_tr; f2 2*f2 1];
el_tr=[el_tr; f2*(f1-1)+1 f2*(f1-2)+1 1];
el_tr=[el_tr; f2*(f1-1)+1 f2*(f1-1)+2 1];
el_tr=[el_tr; f1*f2 f2*(f1-1) 1];
el_tr=[el_tr; f1*f2 f2*f1-1 1];
% four walls
for j=2:f2-1
el_tr=[el_tr; j j-1 1];
el_tr=[el_tr; j j+1 1];
el_tr=[el_tr; j f2+j 1];
el_tr=[el_tr; j f2+j+1 1]; % added for tri lattice
el_tr=[el_tr; f2*(f1-1)+j f2*(f1-1)+j-1 1];
el_tr=[el_tr; f2*(f1-1)+j f2*(f1-1)+j+1 1];
el_tr=[el_tr; f2*(f1-1)+j f2*(f1-2)+j 1];
end
for i=2:f1-1
el_tr=[el_tr; f2*(i-1)+1 f2*(i-2)+1 1];
el_tr=[el_tr; f2*(i-1)+1 f2*i+1 1];
el_tr=[el_tr; f2*(i-1)+1 f2*(i-1)+2 1];
el_tr=[el_tr; f2*(i-1)+1 f2*i+2 1]; % added for tri lattice
el_tr=[el_tr; f2*i f2*(i-1) 1];
el_tr=[el_tr; f2*i f2*(i+1) 1];
el_tr=[el_tr; f2*i f2*i-1 1];
end
el_tr=symmetrizeEdgeL(el_tr);
function [el_sq]=buildSquareLattice(n) % square latice
el_sq=[];
x=factor(n);
if numel(x)==1
el_sq=[el_sq; n 1 1];
n=n-1;
x=factor(n);
end
if mod(numel(x),2)==0
f1=prod(x(1:numel(x)/2));
f2=prod(x(numel(x)/2+1:numel(x)));
elseif mod(numel(x),2)==1
f1=prod(x(1:(numel(x)+1)/2));
f2=prod(x((numel(x)+1)/2+1:numel(x)));
end
% the lattice will be f1xf2
% inner mesh
for i=2:f1-1
for j=2:f2-1
% (i,j)->f2*(i-1)+j
el_sq=[el_sq; f2*(i-1)+j f2*(i-2)+j 1];
el_sq=[el_sq; f2*(i-1)+j f2*(i)+j 1];
el_sq=[el_sq; f2*(i-1)+j f2*(i-1)+j-1 1];
el_sq=[el_sq; f2*(i-1)+j f2*(i-1)+j+1 1];
end
end
% four corners
el_sq=[el_sq; 1 2 1];
el_sq=[el_sq; 1 f2+1 1];
el_sq=[el_sq; f2 f2-1 1];
el_sq=[el_sq; f2 2*f2 1];
el_sq=[el_sq; f2*(f1-1)+1 f2*(f1-2)+1 1];
el_sq=[el_sq; f2*(f1-1)+1 f2*(f1-1)+2 1];
el_sq=[el_sq; f1*f2 f2*(f1-1) 1];
el_sq=[el_sq; f1*f2 f2*f1-1 1];
% four walls
for j=2:f2-1
el_sq=[el_sq; j j-1 1];
el_sq=[el_sq; j j+1 1];
el_sq=[el_sq; j f2+j 1];
el_sq=[el_sq; f2*(f1-1)+j f2*(f1-1)+j-1 1];
el_sq=[el_sq; f2*(f1-1)+j f2*(f1-1)+j+1 1];
el_sq=[el_sq; f2*(f1-1)+j f2*(f1-2)+j 1];
end
for i=2:f1-1
el_sq=[el_sq; f2*(i-1)+1 f2*(i-2)+1 1];
el_sq=[el_sq; f2*(i-1)+1 f2*i+1 1];
el_sq=[el_sq; f2*(i-1)+1 f2*(i-1)+2 1];
el_sq=[el_sq; f2*i f2*(i-1) 1];
el_sq=[el_sq; f2*i f2*(i+1) 1];
el_sq=[el_sq; f2*i f2*i-1 1];
end
el_sq=symmetrizeEdgeL(el_sq);
function el_hex=buildHexagonalLattice(n) % hexagonal lattice .......
% construct subgraph of the triangular lattice, f1xf2
el_hex=[];
x=factor(n);
if numel(x)==1
el_hex=[el_hex; n 1 1];
n=n-1;
x=factor(n);
end
if mod(numel(x),2)==0
f1=prod(x(1:numel(x)/2));
f2=prod(x(numel(x)/2+1:numel(x)));
elseif mod(numel(x),2)==1
f1=prod(x(1:(numel(x)+1)/2));
f2=prod(x((numel(x)+1)/2+1:numel(x)));
end
% the lattice will be f1xf2
% inner mesh
fmax=max(f1,f2);
fmin=min(f1,f2);
for ff=1:fmin % from 1 to fmin
% rows are from ff*fmax+1 to (ff+1)*fmax - 1
% (ff+1)*fmax+1 to (ff+2)*fmax - 2
for gg=1:fmax % in range(fmax):
if gg<fmax % if it's not the last node in the row
el_hex=[el_hex; (ff-1)*fmax+gg,(ff-1)*fmax+gg+1,1];
end
if ff<fmin && mod(gg,4)==1 % gg%4==1
% connect (ff-1)*fmax+gg to ff*fmax+gg+1
% and (ff-1)*fmax+gg+3 to ff*fmax+gg+2
n1=(ff-1)*fmax+gg;
n2=ff*fmax+gg+1;
if n1<fmin*fmax && n2<fmin*fmax && gg+1<=fmax
el_hex=[el_hex; n1 n2 1];
end
n1=(ff-1)*fmax+gg+3;
n2=ff*fmax+gg+2;
if n1<fmin*fmax && n2<fmin*fmax && gg+3<=fmax
el_hex=[el_hex; n1 n2 1];
end
end
end
end
el_hex=symmetrizeEdgeL(el_hex);