Skip to content

Add Graph Algorithm- hamiltonian cycle #14

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
124 changes: 124 additions & 0 deletions src/main/python/algorithms/other/hamiltonian_cycle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
"""Untitled8.ipynb

Automatically generated by Colaboratory.

Original file is located at
https://colab.research.google.com/drive/1-QUPjAVUrIOdUI3M0shzjgtGOW7t-SLG
"""

# Python program for solution of hamiltonian cycle problem

class Graph:
def __init__(self, vertices):
self.graph = [[0 for column in range(vertices)] for row in range(vertices)]
self.V = vertices

""" Check if this vertex is an adjacent vertex
of the previously added vertex and is not
included in the path earlier """

def isSafe(self, v, pos, path):
# Check if current vertex and last vertex
# in path are adjacent
if self.graph[path[pos - 1]][v] == 0:
return False

# Check if current vertex not already in path
for vertex in path:
if vertex == v:
return False

return True

# A recursive utility function to solve
# hamiltonian cycle problem
def hamCycleUtil(self, path, pos):

# base case: if all vertices are
# included in the path
if pos == self.V:
# Last vertex must be adjacent to the
# first vertex in path to make a cyle
if self.graph[path[pos - 1]][path[0]] == 1:
return True
else:
return False

# Try different vertices as a next candidate
# in Hamiltonian Cycle. We don't try for 0 as
# we included 0 as starting point in in hamCycle()
for v in range(1, self.V):

if self.isSafe(v, pos, path) == True:

path[pos] = v

if self.hamCycleUtil(path, pos + 1) == True:
return True

# Remove current vertex if it doesn't
# lead to a solution
path[pos] = -1

return False

def hamCycle(self):
path = [-1] * self.V

""" Let us put vertex 0 as the first vertex
in the path. If there is a Hamiltonian Cycle,
then the path can be started from any point
of the cycle as the graph is undirected """
path[0] = 0

if self.hamCycleUtil(path, 1) == False:
print("Solution does not exist\n")
return False

self.printSolution(path)
return True

def printSolution(self, path):
print("Solution Exists: Following is one Hamiltonian Cycle")
for vertex in path:
print(vertex, end="")
print(path[0])

# Driver Code

""" Let us create the following graph
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3)-------(4) """
g1 = Graph(5)
g1.graph = [
[0, 1, 0, 1, 0],
[1, 0, 1, 1, 1],
[0, 1, 0, 0, 1],
[1, 1, 0, 0, 1],
[0, 1, 1, 1, 0],
]

# Print the solution
g1.hamCycle()

""" Let us create the following graph
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3) (4) """
g2 = Graph(5)
g2.graph = [
[0, 1, 0, 1, 0],
[1, 0, 1, 1, 1],
[0, 1, 0, 0, 1],
[1, 1, 0, 0, 0],
[0, 1, 1, 0, 0],
]

# Print the solution
g2.hamCycle()
76 changes: 76 additions & 0 deletions src/main/python/algorithms/other/hamiltonian_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
"""path.ipynb

Automatically generated by Colaboratory.

Original file is located at
https://colab.research.google.com/drive/1D67ljfUJfFYRiQOCq0N8E2-jxjvVERlY

A Hamiltonian path, also called a Hamilton path, is a graph path between two vertices of a graph that visits each vertex exactly once.
If a Hamiltonian path exists whose endpoints are adjacent, then the resulting graph cycle is called a Hamiltonian cycle (or Hamiltonian cycle).
"""

# A class to represent a graph object
class Graph:

# Constructor
def __init__(self, edges, N):

# A list of lists to represent an adjacency list
self.adjList = [[] for _ in range(N)]

# add edges to the undirected graph
for (src, dest) in edges:
self.adjList[src].append(dest)
self.adjList[dest].append(src)


def printAllHamiltonianPaths(g, v, visited, path, N):

# if all the vertices are visited, then the Hamiltonian path exists
if len(path) == N:
# print the Hamiltonian path
print(path)
return

# Check if every edge starting from vertex `v` leads to a solution or not
for w in g.adjList[v]:

# process only unvisited vertices as the Hamiltonian
# path visit each vertex exactly once
if not visited[w]:
visited[w] = True
path.append(w)

# check if adding vertex `w` to the path leads to the solution or not
printAllHamiltonianPaths(g, w, visited, path, N)

# backtrack
visited[w] = False
path.pop()


if __name__ == '__main__':
# Test cases
# consider a complete graph having 4 vertices
edges = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
# edges = [(1, 2), (2, 3), (2, 4), (3, 4), (3, 5)]
# edges = [(1, 4), (1, 2), (2, 3), (2, 5), (3, 6)]
# edges = [(1, 4), (1, 2), (2, 3), (2, 5), (3, 6),(5,6)]
# total number of nodes in the graph
N = 4

# build a graph from the given edges
g = Graph(edges, N)

# starting node
start = 0

# add starting node to the path
path = [start]

# mark the start node as visited
visited = [False] * N
visited[start] = True

printAllHamiltonianPaths(g, start, visited, path, N)