1+ %{
2+ ***************************************************************************************
3+ * Abstract: Determine Cycle Space of a Graph (weighted & undirected)
4+ * Uses: This file has been compiled using Matlab R2017b
5+ * Author: Michael Vasquez Otazu
6+ * Email: mitxael@hotmail.it
7+ * History: V1.0 - first release
8+ ********************************* START LICENSE BLOCK *********************************
9+ * The MIT License (MIT)
10+ * Copyright (C) 2017 Michael Vasquez Otazu
11+ *
12+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
13+ * software and associated documentation files (the "Software"), to deal in the Software
14+ * without restriction, including without limitation the rights to use, copy, modify, merge,
15+ * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
16+ * to whom the Software is furnished to do so, subject to the following conditions:
17+ *
18+ * The above Copyright notice and this Permission Notice shall be included in all copies
19+ * or substantial portions of the Software.
20+ ********************************** END LICENSE BLOCK **********************************
21+ %}
22+
23+ function CS = CycleSpace(G , varargin )
24+
25+ global A B limit cycleCount ;
26+
27+ %% Convert graph to matrix
28+ A = ConvertAdjLists2AdjMatrix(G );
29+
30+ %% Check consistency
31+ if nargin < 2, varargin = 1e- 10 ; end
32+ if ( isempty( A ) ), return ; end
33+
34+ %% Set variables
35+ nVert = G .numnodes ;
36+ B = zeros( 0 , nVert ) ;
37+ limit = nVert ;
38+ cycleCount = zeros( 1 , nVert ) ;
39+
40+ %% Generate all unique triples of connected vertices which have
41+ % indices v1 < v2 < v3 and connections v2 - v1 - v3, then
42+ % search for paths which connect v2 to v3
43+ for ix = 1 : nVert - 2 % v1
44+ for jx = ix + 1 : nVert - 1 % v2
45+ if ( A( ix , jx ) == 1 ) % there's an edge (v1,v2)
46+ pathV = [ zeros( 1 , ix ), ones( 1 , nVert - ix ) ]; % Initialize pathV, and block v1
47+ pathE = zeros( 1 , nVert );
48+ pathV(jx ) = 0 ; % block v2
49+ pathE(jx ) = ix ; % add edge (v2,v1)
50+ for kx = jx + 1 : nVert % v3
51+ if ( A( kx , ix ) == 1 ) % there's an edge (v3,v1)
52+ % initial path length = 2; now look for extensions
53+ pathE(ix ) = kx ; % add edge (v1,v3)
54+ nextVert( pathV , pathE , 2 , ix , jx , kx ) ;
55+ end
56+ end
57+ end
58+ end
59+ end
60+
61+ CS = B ;
62+
63+ end
64+
65+
66+
67+ %% Scope: Extend current path by one additional vertex
68+ % - pathVrtx: Boolean vector of vertices:
69+ % 1 = vertex available for extension
70+ % 0 = vertex blocked (already in path or index lower than v1)
71+ % - pathEdgs: Vector of edges (index=source; value=destination)
72+ function nextVert( pathVrtx , pathEdgs , pathLength , root , v2 , v3 )
73+
74+ global A B limit cycleCount ;
75+ pathLength = pathLength + 1 ;
76+
77+ % get candidates for extension
78+ edgesV2 = A( v2 , : ); % extract all edges of v2
79+ pathVrtx_A = pathVrtx .* edgesV2 ; % multiply (elem by elem) pathV and A (i.e. set to "0" all edges regarding blocked vertices)
80+ candS = find( pathVrtx_A ); % return col_indexes of non-zero values (i.e. non-blocked vertices with edges to v2)
81+
82+ for mx = 1 : size( candS , 2 )
83+ cand = candS( mx );
84+ if ( cand == v3 ) % found a cycle!
85+ cycleCount( pathLength ) = cycleCount( pathLength ) + 1 ;
86+ pathVrtx(cand ) = 0 ; % add vertex into pathV
87+ pathEdgs(cand ) = v2 ; % add edge (v3,v2)
88+ % pathE(v3) = root;
89+ %{
90+ fprintf( 'Cycle of %4d edges:\n', pathLength);
91+ %cycleDim = sum(pathV~=1,2);
92+ disp(pathV);
93+ %}
94+ cycleN = pathEdgs ; % save the cycle
95+ % for idx = 1:root-1, cycleN(idx)=1; end % clean from old %"blocked" vertices % only if B is generated from pathV
96+ B = [B ;cycleN ]; % INSERT CYCLE into cycleSpace
97+ [rr ,cc ] = size(B );
98+ if (rr == 17 )
99+ disp(' hello' );
100+ end
101+ elseif ( pathLength < limit ) % extend again
102+ pathVrtx_new = pathVrtx ;
103+ pathEdgs_new = pathEdgs ;
104+ pathVrtx_new(cand ) = 0 ; % block vertex just added to path
105+ pathEdgs_new(cand ) = v2 ; % Add edge (v3,v2)
106+ nextVert( pathVrtx_new , pathEdgs_new , pathLength , root , cand , v3 ) ;
107+ end
108+ end
109+ end
0 commit comments