MATLAB graph/cyclebasis: How can I extract labeling-independent “minimal loop units”?

76 views (last 30 days)
I have two undirected graphs that represent the same connectivity (isomorphic up to node relabeling). When I call cyclebasis on each, I get different sets of cycles. I understand a cycle basis can depend on the spanning tree/edge order, but I want a labeling-invariant notion of “minimal loop units.”
Code
clc; clear; close all
node = [
2 7
2 3
3 4
4 5
5 6
6 1
1 4
1 5
3 6
1 3
5 7
6 7
2 6
5 8];
G = graph(node(:,1), node(:,2), []);
cycles = cyclebasis(G)
figure(1); plot(G,'Layout','force');
%%
node2 = [
1 2
2 3
3 4
4 1
1 5
5 6
2 4
6 7
3 6
2 5
3 7
4 7
2 6
6 8];
G2 = graph(node2(:,1), node2(:,2), []);
cycles2 = cyclebasis(G2)
figure(2); plot(G2,'Layout','force');
Result:
cycles =
7×1 cell array
{[1 3 6 5]}
{[ 1 4 5]}
{[ 1 5 6]}
{[ 2 3 6]}
{[2 6 5 7]}
{[3 4 5 6]}
{[ 5 6 7]}
cycles2 =
7×1 cell array
{[ 1 2 4]}
{[ 1 2 5]}
{[ 2 3 4]}
{[ 2 3 6]}
{[2 3 7 6]}
{[2 4 7 6]}
{[ 2 5 6]}
Questions:
I know cyclebasis can vary with spanning tree/edge ordering. What’s the recommended way in MATLAB to obtain “minimal loop units” that do not depend on node labeling or edge input order? For example, in the above case, each cycle is a 3-node triangle, and there should be seven such cycles.
  7 Comments
Taehyub
Taehyub on 25 Aug 2025 at 4:45
@Umar Thank you so much for your comments. However, what I am looking for is not to define maxNodes and then search for cylces within that limit.
Our purpose is that:
  1. Find the basis cycles.
  2. These cycles must be composed of the minimum number of edges (i.e., the shortest possible cycles).
After much consideration, and after reviewing all of your codes and ideas, I believe the most powerful algorithm that can be achieved is:
  1. Find all cycles.
  2. Sort the cycles by the number of edges (length).
  3. Always include triangles (3-cycles) since they are the minimal requirement for forming loops.
  4. For cycles of length 4 or greater, check whether the cycle is already covered by the edges of previously selected cycles (i.e., whether the same sequence of edges is included). Only independent cycles should be selected.
Umar
Umar on 25 Aug 2025 at 14:03
Edited: Umar on 25 Aug 2025 at 14:14

Hi @Taehyub,

You are absolutely correct - avoiding arbitrary maxNodes limits is the right approach. Your 4-step algorithm addresses the core problem, but needs some theoretical refinements:

Responding to Your Algorithm:

Steps 1-2: Correct approach. Finding all cycles and sorting by length is the foundation of minimum cycle basis algorithms.

Step 3: Needs adjustment. "Always include triangles" isn't mathematically sound. Triangles aren't guaranteed to be in every minimum cycle basis - sometimes longer cycles can form a shorter total basis.

Step 4: Critical issue. "Same sequence of edges" doesn't determine linear independence. You need proper linear independence over GF(2), not edge overlap checking.

Refined Implementation with Pseudo-code:

ALGORITHM: Labeling-Invariant Minimum Cycle Basis

INPUT: Graph G OUTPUT: Canonical minimum cycle basis

1. CANONICALIZE_GRAPH(G): edges = sort(G.edges) nodes = canonical_ordering(G) // degree sequence + neighbor degrees G_canon = relabel_graph(G, nodes) return G_canon

2. FIND_ALL_CYCLES(G_canon): cycles = [] for each simple cycle C in G_canon: cycles.append(C) return sort(cycles, by=length)

3. SELECT_BASIS_CYCLES(sorted_cycles): basis = [] cycle_matrix = empty_matrix(num_edges)

   for cycle C in sorted_cycles:
       vector_C = cycle_to_binary_vector(C, edge_list)
       // Check linear independence over GF(2)
       if rank(cycle_matrix + vector_C) > rank(cycle_matrix):
           basis.append(C)
           cycle_matrix.add_row(vector_C)
           if len(basis) == cyclomatic_number:
               break
   return basis

4. CANONICALIZE_CYCLES(basis): for each cycle in basis: start_from_min_node() choose_consistent_direction() return sorted(basis, lexicographically)

Key Functions You Need to Implement:

  • cycle_to_binary_vector(): Maps cycle to GF(2) vector over edges
  • rank(): Matrix rank over GF(2)
  • canonical_ordering(): Consistent node labeling

References: * Horton, J.D. (1987). "Shortest cycle basis algorithm." SIAM J. Computing, 16(2), 358-366 * McKay, B.D. & Piperno, A. (2014). "Practical graph isomorphism, II." J. Symbolic Computation, 60, 94-112

Question: Can you implement the GF(2) linear algebra operations? This is essential for proper independence testing in step 3.

Sign in to comment.

Answers (2)

Matt J
Matt J on 18 Aug 2025 at 8:06
Edited: Matt J on 18 Aug 2025 at 10:44
This might help:
node = [
2 7
2 3
3 4
4 5
5 6
6 1
1 4
1 5
3 6
1 3
5 7
6 7
2 6
5 8];
G = spatialgraph2D( graph(node(:,1), node(:,2), []) );
cycles=pgonNodes(G)
cycles = 7×1 cell array
{[2 7 6]} {[1 5 4]} {[6 7 5]} {[6 5 1]} {[6 3 2]} {[1 3 6]} {[4 3 1]}
mosaic(G)
node2 = [
1 2
2 3
3 4
4 1
1 5
5 6
2 4
6 7
3 6
2 5
3 7
4 7
2 6
6 8];
G2 = spatialgraph2D( graph(node2(:,1), node2(:,2), []) );
cycles2=pgonNodes(G2)
cycles2 = 7×1 cell array
{[1 5 2]} {[3 6 7]} {[2 5 6]} {[2 6 3]} {[2 4 1]} {[3 4 2]} {[7 4 3]}
mosaic(G2)
  3 Comments
Matt J
Matt J on 20 Aug 2025 at 11:10
Edited: Matt J on 20 Aug 2025 at 11:10
It is not clear to me what it means for nodes to "overlap". Nodes occupy a single point, so to my mind overlapping nodes means you have duplicate nodes.
Perhaps you mean that edges can intersect? That would indeed disqualify the spatialgraph2D algorithm.
Taehyub
Taehyub on 21 Aug 2025 at 9:00
@Matt J I'm sorry for the confusion. You are right. What I meant to say is 'edge.' Thank you for your great insight.

Sign in to comment.


Umar
Umar on 19 Aug 2025 at 5:24

Hi @Taehyub,

Thanks for sharing your questions. I understand you want a labeling-independent way to find “minimal loop units,” like the 3-node triangles in your graphs. Below, I’ve addressed your questions step by step and provided a MATLAB script you can run to get consistent results across isomorphic graphs.

Question 1

You mentioned, I know cyclebasis can vary with spanning tree/edge ordering. What’s the recommended way in MATLAB to obtain “minimal loop units” that do not depend on node labeling or edge input order?

Solution


The built-in cyclebasis function depends on the spanning tree and edge order, which can vary with node labeling. To get a labeling-independent set of minimal loops (triangles in your example), the recommended approach is to explicitly enumerate all 3-node cycles and verify which combinations form triangles. This guarantees consistent results for isomorphic graphs.

Question 2

You mentioned, For example, in the above case, each cycle is a 3-node triangle, and there should be seven such cycles. How can I obtain them reliably?

Solution


The MATLAB script below implements this approach:

  • It generates all 3-node combinations of nodes.
  • Checks which combinations form triangles by verifying all three edges exist.
  • Plots the graphs with highlighted triangles, each with a distinct color and label.

This ensures you get the exact seven triangles for each graph, independent of node labels or edge ordering.

Implementation

   clc; clear; close all;
   %% -----------------------------
   %% Graph 1
   %% -----------------------------
   node = [
   2 7
   2 3
   3 4
   4 5
   5 6
   6 1
   1 4
   1 5
   3 6
   1 3
   5 7
   6 7
   2 6
   5 8];
   G = graph(node(:, 1), node(:, 2), []);
   figure(1);
   h1 = plot(G, 'Layout', 'force');
   title('Graph 1');
   labelnode(h1, 1:numnodes(G), arrayfun(@num2str, 1:numnodes(G), 
   'UniformOutput', false));
   T = nchoosek(1:numnodes(G), 3);  % all 3-node combinations
   triangles = [];
   edges = sort(node, 2);
   for k = 1:size(T,1)
    comb = sort(T(k,:));
    if all(ismember(sort([comb(1) comb(2)]), edges, 'rows')) && ...
       all(ismember(sort([comb(2) comb(3)]), edges, 'rows')) && ...
       all(ismember(sort([comb(1) comb(3)]), edges, 'rows'))
        triangles = [triangles; comb];
    end
  end
disp('Triangles in Graph 1:');
disp(triangles);
colors = lines(size(triangles,1));
hold on
for k = 1:size(triangles,1)
  highlight(h1, triangles(k,:), 'EdgeColor', colors(k,:), 'LineWidth', 2);
  coords = mean([h1.XData(triangles(k,:))' h1.YData(triangles(k,:))'], 1);
  text(coords(1), coords(2), ['T' num2str(k)], 'FontWeight','bold', 'Color',   
 colors(k,:));
end
   %% -----------------------------
  %% Graph 2
  %% -----------------------------
  node2 = [
  1 2
  2 3
  3 4
  4 1
  1 5
  5 6
  2 4
  6 7
  3 6
  2 5
  3 7
  4 7
  2 6
  6 8];
G2 = graph(node2(:, 1), node2(:, 2), []);
figure(2);
h2 = plot(G2, 'Layout', 'force');
title('Graph 2');
labelnode(h2, 1:numnodes(G2), arrayfun(@num2str, 1:numnodes(G2), 
'UniformOutput', false));
T2 = nchoosek(1:numnodes(G2), 3);  
triangles2 = [];
edges2 = sort(node2, 2);
for k = 1:size(T2,1)
  comb = sort(T2(k,:));
  if all(ismember(sort([comb(1) comb(2)]), edges2, 'rows')) && ...
     all(ismember(sort([comb(2) comb(3)]), edges2, 'rows')) && ...
     all(ismember(sort([comb(1) comb(3)]), edges2, 'rows'))
      triangles2 = [triangles2; comb];
  end
end
disp('Triangles in Graph 2:');
disp(triangles2);
colors = lines(size(triangles2,1));
hold on
for k = 1:size(triangles2,1)
  highlight(h2, triangles2(k,:), 'EdgeColor', colors(k,:), 'LineWidth', 2);
  coords = mean([h2.XData(triangles2(k,:))' h2.YData(triangles2(k,:))'], 1);
  text(coords(1), coords(2), ['T' num2str(k)], 'FontWeight','bold', 'Color', 
colors(k,:));
end

Please see attached.


This script gives a reliable, labeling-independent set of minimal loops (triangles) for any graph. You can run it for both graphs in your example and verify that each has exactly seven triangles. Each triangle is plotted with a distinct color and labeled for clarity.

  3 Comments
Umar
Umar on 19 Aug 2025 at 14:59

@Matt J, Agreed, this approach is not scalable in general. My graphs are relatively small, and the minimal loops of interest are triangles, so brute-force enumeration is simple, labeling-invariant, and guarantees the exact set of loops I need. For larger or more complex graphs, I would turn to more efficient methods such as spatialgraph2D or minimum cycle basis algorithms.

Taehyub
Taehyub on 20 Aug 2025 at 8:38
@Umar Thank you very much for the comment. As I mentioned above, our system is quite large, as shown in the original nodes I attached newly. Your 3-node combinations approach seems like a truly innovative idea. I will look into it more deeply.

Sign in to comment.

Categories

Find more on Graph and Network Algorithms in Help Center and File Exchange

Products


Release

R2025a

Community Treasure Hunt

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

Start Hunting!