Submitted:
19 August 2025
Posted:
19 August 2025
Read the latest preprint version here
Abstract
Keywords:
1. Introduction
- Decision Version: Determine whether G contains at least one triangle—a set of three vertices where edges all exist.
- Listing Version: Enumerate all such triangles in G.
2. State-of-the-Art Algorithms
2.1. Naive Approach
2.2. Matrix Multiplication-Based Methods
2.3. Algorithms for Sparse Graphs
2.4. Algorithms for Dense Graphs
3. The Aegypti Algorithm
3.1. Key Features
- Input Validation: Ensures G is a NetworkX graph.
- Visited Tracking: Uses a set to mark processed nodes, preventing cycles.
- DFS Traversal: Employs a stack for iterative DFS, tracking each node’s parent.
- Triangle Detection: Identifies a triangle when is visited and an edge exists between and .
- Avoiding Duplicates: Stores triangles as in a set.
- Early Termination: Returns after the first triangle if .
- Disconnected Graphs: Outer loop ensures all components are explored.
3.2. Correctness
3.2.1. Completeness
-
Case 1: DFS processes .
- −
- u is visited, v is processed with .
- −
- w is processed with , .
- −
- Since and (as G is undirected, ), is detected.
-
Case 2: DFS processes .
- −
- w is visited, u is processed with .
- −
- v is processed with , .
- −
- Since and , is detected.
-
Case 3: DFS processes .
- −
- u is visited, w is processed with .
- −
- v is processed with , .
- −
- Since and , is detected.
3.2.2. Soundness
- (via DFS tree edge),
- (neighbor relation),
- (explicit check),
- (distinct nodes).
3.2.3. Conclusion
4. Runtime Analysis
-
Forfirst_triangle=True:
- −
- Best-case runtime:
- −
- Worst-case runtime:
-
Forfirst_triangle=False:
- −
- Best-case runtime: (when )
- −
- Worst-case runtime:
4.1. General Observations
- Graph Representation: The graph is stored as an adjacency list (e.g., using NetworkX), enabling edge existence checks and efficient neighbor traversal.
- DFS Traversal: DFS visits each node and edge exactly once in the worst case, yielding a baseline complexity of .
- Triangle Detection: For each edge , the algorithm checks for a triangle by verifying an edge between v and the parent of u, an operation per edge.
4.2. Case 1: first_triangle=True
- The algorithm may traverse the entire graph if no triangle exists or if the first triangle is found late, visiting all n nodes and m edges in time.
- For each edge, an triangle check is performed, contributing time in total.
- Thus, the worst-case runtime is .
- If a triangle is detected early (e.g., after exploring only a few nodes), the algorithm terminates in as little as time, depending on the traversal depth at termination.
4.3. Case 2: first_triangle=False
- DFS traversal covers all n nodes and m edges, requiring time.
- Each edge undergoes an triangle check, totaling time across all edges.
- Each of the t detected triangles is stored in a set (e.g., as a frozenset), with an average insertion time of per triangle, adding time.
- Thus, the total worst-case runtime is .
- If no triangles exist (), the algorithm still completes a full DFS traversal, taking time.
4.4. Summary of Runtime Analysis
| Case | Best-Case Runtime | Worst-Case Runtime |
| first_triangle=True | ||
| first_triangle=False |
4.5. Key Observations
- Early Termination (first_triangle=True): The algorithm’s efficiency shines when a triangle is found early, potentially avoiding a full graph traversal.
- Full Exploration (first_triangle=False): The runtime grows linearly with t, becoming significant in dense graphs with many triangles.
- DFS Efficiency: Processing each node and edge at most once ensures efficiency, particularly in sparse graphs.
- Space Complexity: The algorithm uses space for tracking visited nodes and space for storing triangles.
4.6. Practical Implications
- For first_triangle=True, the algorithm is ideal when only one triangle is needed, offering potential early termination.
- For first_triangle=False, large t values in dense graphs may necessitate optimizations, such as depth limits or approximate methods.
5. Research Data
6. Illustrative Examples
6.1. Example 1: Simple Triangle
- Nodes:
- Edges:
- Start DFS traversal from node 1.
- Process neighbors of 1: 2 is visited next.
-
Process neighbors of 2: 3 is visited next.
- −
- When processing 3, its neighbor 1 is already visited. The algorithm checks if 2 (parent of 3) is connected to 1. Since exists, the triangle is detected.
- If first_triangle=True: Returns .
- If first_triangle=False: Returns .
6.2. Example 2: Two Disconnected Triangles
- Nodes:
- Edges:
- Start DFS traversal from node 1:
-
Detects triangle as described in Example 1.
- −
- Continue DFS traversal from node 4:
- −
- Process 5, then 6.
- −
- When processing 6, its neighbor 4 is already visited. The algorithm checks if 5 (parent of 6) is connected to 4. Since exists, the triangle is detected.
- If first_triangle=True: Returns (stops after finding the first triangle).
- If first_triangle=False: Returns (finds both triangles).
6.3. Example 3: Overlapping Triangles
- Nodes:
- Edges:
-
Start DFS traversal from node 1:
- −
-
Process 2, then 3.
- *
- When processing 3, its neighbor 1 is already visited. The algorithm checks if 2 (parent of 3) is connected to 1. Since exists, the triangle is detected.
- −
-
Process 4 (neighbor of 3):
- *
- When processing 4, its neighbor 1 is already visited. The algorithm checks if 3 (parent of 4) is connected to 1. Since exists, the triangle is detected.
- If first_triangle=True: Returns (stops after finding the first triangle).
- If first_triangle=False: Returns (finds both triangles).
6.4. Example 4: Graph Without Triangles
- Nodes:
- Edges:
-
Start DFS traversal from node 1:
- −
- Process 2, then 3, then 4.
- −
- No back edges are found that form a triangle.
- If first_triangle=True: Returns None (no triangles exist).
- If first_triangle=False: Returns None (no triangles exist).
6.5. Example 5: Complex Graph with Multiple Triangles
- Nodes:
- Edges:
-
Start DFS traversal from node 1:
- −
- Detects triangle .
-
Continue DFS traversal from node 3:
- −
-
Process 4, then 5.
- *
- When processing 5, its neighbor 3 is already visited. The algorithm checks if 4 (parent of 5) is connected to 3. Since exists, the triangle is detected.
- −
-
Process 6 (neighbor of 5).
- *
- When processing 6, its neighbor 4 is already visited. The algorithm checks if 5 (parent of 6) is connected to 4. Since exists, the triangle is detected.
- If first_triangle=True: Returns (stops after finding the first triangle).
- If first_triangle=False: Returns (finds all triangles).
6.6. Summary of Results
| Example | first_triangle=True | first_triangle=False |
| Simple Triangle | ||
| Two Disconnected | ||
| Overlapping Triangles | ||
| No Triangles | None | None |
| Complex Graph |
6.7. Conclusion
7. Impact
7.1. Theoretical Impact
7.2. Practical Impact
- Efficiency in Large-Scale Graphs: Linear-time algorithms enable efficient triangle detection in massive graphs, such as social networks or web graphs, where m and n can grow into the millions or billions.
- Scalability: These algorithms allow real-time or near-real-time analysis of dynamic graphs, which is crucial for applications like fraud detection, recommendation systems, and community detection in social networks.
- Foundation for Advanced Algorithms: Linear-time triangle finding serves as a building block for more complex graph algorithms, such as clustering coefficient computation, motif counting, and dense subgraph discovery.
7.3. Applications
7.4. Conclusion
8. Conclusion
- Sparse Triangle Hypothesis: For , beats , suggesting , violating the conjecture.
- Dense Triangle Hypothesis: For , outperforms , with .
Acknowledgments
Appendix A

References
- Alon, N.; Yuster, R.; Zwick, U. Finding and counting given length cycles. Algorithmica 1997, 17, 209–223. [Google Scholar] [CrossRef]
- Chiba, N.; Nishizeki, T. Arboricity and Subgraph Listing Algorithms. SIAM Journal on computing 1985, 14, 210–223. [Google Scholar] [CrossRef]
- Vega, F. Aegypti: Triangle-Free Solver. https://pypi.org/project/aegypti. Accessed August 4, 2025.
- Milo, R.; Shen-Orr, S.; Itzkovitz, S.; Kashtan, N.; Chklovskii, D.; Alon, U. Network Motifs: Simple Building Blocks of Complex Networks. Science 2002, 298, 824–827. [Google Scholar] [CrossRef] [PubMed]
- Newman, M.E. The Structure and Function of Complex Networks. SIAM Review 2003, 45, 167–256. [Google Scholar] [CrossRef]
- Patrascu, M. Towards polynomial lower bounds for dynamic problems. In Proceedings of the Proceedings of the Forty-Second ACM Symposium on Theory of Computing, New York, NY, USA, 2010; STOC ’10, p. 603–610. [CrossRef]
| Nr. | Code metadata description | Metadata |
|---|---|---|
| C1 | Current code version | v0.3.3 |
| C2 | Permanent link to code/repository used for this code version | https://github.com/frankvegadelgado/finlay |
| C3 | Permanent link to Reproducible Capsule | https://pypi.org/project/aegypti/ |
| C4 | Legal Code License | MIT License |
| C5 | Code versioning system used | git |
| C6 | Software code languages, tools, and services used | python |
| C7 | Compilation requirements, operating environments & dependencies | Python ≥ 3.12 |
Disclaimer/Publisher’s Note: The statements, opinions and data contained in all publications are solely those of the individual author(s) and contributor(s) and not of MDPI and/or the editor(s). MDPI and/or the editor(s) disclaim responsibility for any injury to people or property resulting from any ideas, methods, instructions or products referred to in the content. |
© 2025 by the authors. Licensee MDPI, Basel, Switzerland. This article is an open access article distributed under the terms and conditions of the Creative Commons Attribution (CC BY) license (http://creativecommons.org/licenses/by/4.0/).