Skip to content

Commit f0c8fcd

Browse files
feat-hamilitonian_cycle (#227)
1 parent 747bb49 commit f0c8fcd

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Hamiltonian Cycle Detection (Backtracking)
2+
#
3+
# The Hamiltonian Cycle problem determines whether there exists a cycle
4+
# in a graph that visits each vertex exactly once and returns to the start.
5+
# It is an NP-complete problem.
6+
#
7+
# This implementation uses backtracking to explore possible paths.
8+
#
9+
# Time Complexity: O(N!)
10+
# Space Complexity: O(N)
11+
#
12+
# Input: adjacency matrix (square matrix where adj[i][j] = 1 if edge exists)
13+
# Output: list containing:
14+
# - has_cycle: TRUE/FALSE
15+
# - cycle: list of vertices forming the Hamiltonian cycle (if found)
16+
#
17+
# Example usage at the end of this file.
18+
19+
hamiltonian_cycle <- function(graph) {
20+
num_vertices <- nrow(graph)
21+
path <- rep(-1, num_vertices)
22+
23+
# Start at vertex 1 (can be any vertex)
24+
path[1] <- 1
25+
26+
# Helper function to check if vertex v can be added at position pos
27+
is_safe <- function(v, graph, path, pos) {
28+
# Check if current vertex is adjacent to previous vertex
29+
if (graph[path[pos - 1], v] == 0) return(FALSE)
30+
31+
# Check if vertex is already in the path
32+
if (v %in% path[1:(pos - 1)]) return(FALSE)
33+
34+
return(TRUE)
35+
}
36+
37+
# Recursive utility to build Hamiltonian cycle
38+
ham_cycle_util <- function(graph, path, pos) {
39+
if (pos == num_vertices + 1) {
40+
# If last vertex connects to the first → cycle found
41+
if (graph[path[num_vertices], path[1]] == 1) {
42+
return(TRUE)
43+
} else {
44+
return(FALSE)
45+
}
46+
}
47+
48+
# Try adding each vertex as next candidate
49+
for (v in 2:num_vertices) {
50+
if (is_safe(v, graph, path, pos)) {
51+
path[pos] <- v
52+
if (ham_cycle_util(graph, path, pos + 1)) return(TRUE)
53+
# Backtrack
54+
path[pos] <- -1
55+
}
56+
}
57+
return(FALSE)
58+
}
59+
60+
# Start backtracking from vertex 1
61+
if (ham_cycle_util(graph, path, 2)) {
62+
path <- c(path, path[1]) # complete the cycle
63+
return(list(has_cycle = TRUE, cycle = path))
64+
} else {
65+
return(list(has_cycle = FALSE, cycle = NULL))
66+
}
67+
}
68+
69+
# ============================
70+
# Example Usage and Test
71+
# ============================
72+
73+
cat("=== Hamiltonian Cycle Detection ===\n")
74+
75+
# Example graph (Adjacency Matrix)
76+
# Graph:
77+
# 1 - 2 - 3
78+
# | | |
79+
# 4 - 5 - 6
80+
# This graph contains a Hamiltonian cycle
81+
ham_graph <- matrix(
82+
c(0,1,0,1,0,0,
83+
1,0,1,1,1,0,
84+
0,1,0,0,1,1,
85+
1,1,0,0,1,0,
86+
0,1,1,1,0,1,
87+
0,0,1,0,1,0),
88+
nrow = 6, byrow = TRUE
89+
)
90+
91+
cat("Adjacency Matrix:\n")
92+
print(ham_graph)
93+
94+
cat("\nRunning Hamiltonian Cycle detection...\n")
95+
result <- hamiltonian_cycle(ham_graph)
96+
97+
if (result$has_cycle) {
98+
cat("Hamiltonian Cycle found:\n")
99+
cat("Cycle:", paste(result$cycle, collapse = " -> "), "\n")
100+
} else {
101+
cat("No Hamiltonian Cycle exists in this graph.\n")
102+
}

0 commit comments

Comments
 (0)