Skip to content

add: hamiltonian cycle in py #349

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -604,8 +604,8 @@ In order to achieve greater coverage and encourage more people to contribute to
</a>
</td>
<td> <!-- Python -->
<a href="./CONTRIBUTING.md">
<img align="center" height="25" src="./logos/github.svg" />
<a href="./src/python/hamiltonian_cycle.py">
<img align="center" height="25" src="./logos/python.svg" />
</a>
</td>
<td> <!-- Go -->
Expand Down
107 changes: 107 additions & 0 deletions src/python/hamiltonian_cycle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Hamiltonian Cycle is a path in a graph that visits each vertex exactly once and returns to the starting vertex.

# (A)---------------(B)-------------(E)---------------(F)
# | | | |
# | | | |
# | | | |
# (C)---------------(D)--------------- |
# | |
# -----------------------------------

# 6 Vertices
# 9 Edges

class Vertex:
def __init__(self, id):
self.id = id
self.neighbors = []
self.visited = False

def connect_vertices(v1, v2):
v1.neighbors.append(v2)
v2.neighbors.append(v1)

def hamiltonian_cycle_helper(graph, path, pos):
# If all vertices are included in the path
if pos == len(graph):
# Check if last vertex is connected to first vertex
if path[-1] in path[0].neighbors:
return True
return False

# Try different vertices as next candidate
for vertex in graph:
if can_add_to_path(vertex, path, pos):
path[pos] = vertex
vertex.visited = True

if hamiltonian_cycle_helper(graph, path, pos + 1):
return True

# Backtrack
vertex.visited = False
path[pos] = None

return False

def can_add_to_path(vertex, path, pos):
# If vertex is already visited, skip it
if vertex.visited:
return False

# For first vertex, any unvisited vertex is valid
if pos == 0:
return True

# Check if current vertex is connected to the previous vertex in path
if vertex not in path[pos-1].neighbors:
return False

return True

def find_hamiltonian_cycle(graph):
# Initialize the path
path = [None] * len(graph)

# Reset all vertices to unvisited
for vertex in graph:
vertex.visited = False

if hamiltonian_cycle_helper(graph, path, 0):
# Add the first vertex at the end to complete the cycle
return path + [path[0]]
return None

def main():
# Create graph vertices
graph = [
Vertex('A'), # 0
Vertex('B'), # 1
Vertex('C'), # 2
Vertex('D'), # 3
Vertex('E'), # 4
Vertex('F') # 5
]

# Connect vertices according to the graph diagram
connect_vertices(graph[0], graph[1]) # A - B
connect_vertices(graph[0], graph[2]) # A - C
connect_vertices(graph[1], graph[3]) # B - D
connect_vertices(graph[2], graph[3]) # C - D
connect_vertices(graph[1], graph[4]) # B - E
connect_vertices(graph[3], graph[4]) # D - E
connect_vertices(graph[4], graph[5]) # E - F
connect_vertices(graph[3], graph[5]) # D - F
connect_vertices(graph[1], graph[5]) # B - F

# Find Hamiltonian cycle
cycle = find_hamiltonian_cycle(graph)

if cycle:
print("Hamiltonian Cycle found:")
print(" -> ".join(vertex.id for vertex in cycle))
else:
print("No Hamiltonian Cycle exists")

if __name__ == "__main__":
main()
Loading