tarjan
PURPOSE 
function SCC = tarjan(e)
SYNOPSIS 
function [SCC,I] = tarjan(e)
DESCRIPTION 
function SCC = tarjan(e)
Implements tarjan's algorithm for a graph with adjacency matrix e. A value in
e(i,j) indicates an edge from v(j) to v(i). If this is transposed from the
default, well it really shouldn't matter, right?
Returns a cell array of vectors containing scc's, sorted by descending size. The
length of SCC will equal the number of strongly connected components. If (V,E) is
acyclic then SCC will be an Nx1 cell array of single vertices.
function [SCC,I] = tarjan(N,e)
also returns an Nx1 vector of indices into SCC corresponding to nodes in v.
Usage example:
>> E = sparse([2 3 4 5 5 6 6 7 8 4 9 5 10 6 9], ...
[1 2 2 3 4 3 5 6 4 8 8 9 9 10 6], ...
ones(1,15));
>> c = tarjan(E)
c =
[1x4 double] [1x2 double] [7] [3] [2] [1]
>> c{1}
ans =
5 6 9 10
>>
>>
Here E is the adjacency matrix for a directed graph, and the nodes with indices
5, 6, 9, and 10 form the largest strongly connected component in the graph.CROSS-REFERENCE INFORMATION 
This function calls:
- find_loops FIND_LOOPS Compute feedback loops from Jacobian or adjacency matrix.
SUBFUNCTIONS 
SOURCE CODE 
0001 function [SCC,I] = tarjan(e) 0002 % function SCC = tarjan(e) 0003 % Implements tarjan's algorithm for a graph with adjacency matrix e. A value in 0004 % e(i,j) indicates an edge from v(j) to v(i). If this is transposed from the 0005 % default, well it really shouldn't matter, right? 0006 % 0007 % Returns a cell array of vectors containing scc's, sorted by descending size. The 0008 % length of SCC will equal the number of strongly connected components. If (V,E) is 0009 % acyclic then SCC will be an Nx1 cell array of single vertices. 0010 % 0011 % function [SCC,I] = tarjan(N,e) 0012 % also returns an Nx1 vector of indices into SCC corresponding to nodes in v. 0013 % 0014 % Usage example: 0015 % >> E = sparse([2 3 4 5 5 6 6 7 8 4 9 5 10 6 9], ... 0016 % [1 2 2 3 4 3 5 6 4 8 8 9 9 10 6], ... 0017 % ones(1,15)); 0018 % >> c = tarjan(E) 0019 % c = 0020 % [1x4 double] [1x2 double] [7] [3] [2] [1] 0021 % >> c{1} 0022 % ans = 0023 % 5 6 9 10 0024 % >> 0025 % >> 0026 % 0027 % Here E is the adjacency matrix for a directed graph, and the nodes with indices 0028 % 5, 6, 9, and 10 form the largest strongly connected component in the graph. 0029 0030 0031 % using globals because matlab doesn't have shared private variables 0032 global tarjan_v tarjan_SCC tarjan_stack index 0033 0034 tarjan_SCC={}; 0035 tarjan_stack=[]; 0036 0037 N=max(size(e)); 0038 0039 tarjan_v = struct('index',num2cell(zeros(1,N)),'lowlink',num2cell(zeros(1,N)), ... 0040 'onStack',num2cell(logical(zeros(1,N)))); 0041 0042 index=0; 0043 0044 % loop through all nodes 0045 for i=1:N 0046 if tarjan_v(i).index==0 0047 strongconnect(i,e); 0048 end 0049 end 0050 0051 % generate count vector 0052 for j=1:length(tarjan_SCC) 0053 count(j)=length(tarjan_SCC{j}); 0054 tarjan_SCC{j}=sort(tarjan_SCC{j}); % for convenience- sort individual components 0055 end 0056 0057 % sort by decreasing size 0058 [~,q]=sort(count,'descend'); 0059 SCC=tarjan_SCC(q); 0060 0061 for j=1:length(SCC) 0062 I(SCC{j})=j; 0063 end 0064 0065 0066 function strongconnect(i,e) 0067 global tarjan_v tarjan_SCC tarjan_stack index 0068 index=index+1; 0069 0070 % visit the node 0071 tarjan_v(i).index=index; 0072 tarjan_v(i).lowlink=index; 0073 tarjan_stack=[i tarjan_stack]; 0074 tarjan_v(i).onStack=true; 0075 0076 if size(e,2)>=i 0077 out_edges=find(e(:,i)); 0078 else % permit operation on rectangular matrices 0079 out_edges=[]; 0080 end 0081 0082 for k=1:length(out_edges) 0083 j=out_edges(k); 0084 % if not visited, visit 0085 if tarjan_v(j).index==0 0086 strongconnect(j,e); 0087 % carry back lowlink, if lower 0088 tarjan_v(i).lowlink=min(tarjan_v([i j]).lowlink); 0089 elseif tarjan_v(j).onStack==true 0090 % carry back index, if lower 0091 tarjan_v(i).lowlink=min([tarjan_v(i).lowlink tarjan_v(j).index]); 0092 end 0093 end 0094 0095 if tarjan_v(i).lowlink == tarjan_v(i).index 0096 % label a new SCC 0097 theSCC=tarjan_stack(1:find(tarjan_stack==i)); 0098 tarjan_stack=tarjan_stack(length(theSCC)+1:end); 0099 [tarjan_v(theSCC).onStack]=deal(false); 0100 tarjan_SCC=[tarjan_SCC {theSCC}]; 0101 end 0102 0103
Generated on Wed 24-Jun-2020 09:38:33 by m2html © 2005