Skip to content

Commit 8aad7d1

Browse files
add: hamiltonian cycle in py
1 parent 054809e commit 8aad7d1

File tree

2 files changed

+109
-2
lines changed

2 files changed

+109
-2
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,8 +604,8 @@ In order to achieve greater coverage and encourage more people to contribute to
604604
</a>
605605
</td>
606606
<td> <!-- Python -->
607-
<a href="./CONTRIBUTING.md">
608-
<img align="center" height="25" src="./logos/github.svg" />
607+
<a href="./src/python/hamiltonian_cycle.py">
608+
<img align="center" height="25" src="./logos/python.svg" />
609609
</a>
610610
</td>
611611
<td> <!-- Go -->

src/python/hamiltonian_cycle.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Hamiltonian Cycle is a path in a graph that visits each vertex exactly once and returns to the starting vertex.
2+
3+
# (A)---------------(B)-------------(E)---------------(F)
4+
# | | | |
5+
# | | | |
6+
# | | | |
7+
# (C)---------------(D)--------------- |
8+
# | |
9+
# -----------------------------------
10+
11+
# 6 Vertices
12+
# 9 Edges
13+
14+
class Vertex:
15+
def __init__(self, id):
16+
self.id = id
17+
self.neighbors = []
18+
self.visited = False
19+
20+
def connect_vertices(v1, v2):
21+
v1.neighbors.append(v2)
22+
v2.neighbors.append(v1)
23+
24+
def hamiltonian_cycle_helper(graph, path, pos):
25+
# If all vertices are included in the path
26+
if pos == len(graph):
27+
# Check if last vertex is connected to first vertex
28+
if path[-1] in path[0].neighbors:
29+
return True
30+
return False
31+
32+
# Try different vertices as next candidate
33+
for vertex in graph:
34+
if can_add_to_path(vertex, path, pos):
35+
path[pos] = vertex
36+
vertex.visited = True
37+
38+
if hamiltonian_cycle_helper(graph, path, pos + 1):
39+
return True
40+
41+
# Backtrack
42+
vertex.visited = False
43+
path[pos] = None
44+
45+
return False
46+
47+
def can_add_to_path(vertex, path, pos):
48+
# If vertex is already visited, skip it
49+
if vertex.visited:
50+
return False
51+
52+
# For first vertex, any unvisited vertex is valid
53+
if pos == 0:
54+
return True
55+
56+
# Check if current vertex is connected to the previous vertex in path
57+
if vertex not in path[pos-1].neighbors:
58+
return False
59+
60+
return True
61+
62+
def find_hamiltonian_cycle(graph):
63+
# Initialize the path
64+
path = [None] * len(graph)
65+
66+
# Reset all vertices to unvisited
67+
for vertex in graph:
68+
vertex.visited = False
69+
70+
if hamiltonian_cycle_helper(graph, path, 0):
71+
# Add the first vertex at the end to complete the cycle
72+
return path + [path[0]]
73+
return None
74+
75+
def main():
76+
# Create graph vertices
77+
graph = [
78+
Vertex('A'), # 0
79+
Vertex('B'), # 1
80+
Vertex('C'), # 2
81+
Vertex('D'), # 3
82+
Vertex('E'), # 4
83+
Vertex('F') # 5
84+
]
85+
86+
# Connect vertices according to the graph diagram
87+
connect_vertices(graph[0], graph[1]) # A - B
88+
connect_vertices(graph[0], graph[2]) # A - C
89+
connect_vertices(graph[1], graph[3]) # B - D
90+
connect_vertices(graph[2], graph[3]) # C - D
91+
connect_vertices(graph[1], graph[4]) # B - E
92+
connect_vertices(graph[3], graph[4]) # D - E
93+
connect_vertices(graph[4], graph[5]) # E - F
94+
connect_vertices(graph[3], graph[5]) # D - F
95+
connect_vertices(graph[1], graph[5]) # B - F
96+
97+
# Find Hamiltonian cycle
98+
cycle = find_hamiltonian_cycle(graph)
99+
100+
if cycle:
101+
print("Hamiltonian Cycle found:")
102+
print(" -> ".join(vertex.id for vertex in cycle))
103+
else:
104+
print("No Hamiltonian Cycle exists")
105+
106+
if __name__ == "__main__":
107+
main()

0 commit comments

Comments
 (0)