Hamiltonian Cycle or Circuit in a graph G is a cycle that visits every vertex of G exactly once and returns to the starting vertex.
If a graph contains a Hamiltonian cycle, it is called Hamiltonian graph otherwise it is non-Hamiltonian.
Finding a Hamiltonian Cycle in a graph is a well-known NP-complete problem, which means that there's no known efficient algorithm to solve it for all types of graphs. However, it can be solved for small or specific types of graphs.
The Hamiltonian Cycle problem has practical applications in various fields, such as logistics, network design, and computer science.
What is Hamiltonian Path?
Hamiltonian Path in a graph G is a path that visits every vertex of G exactly once and it doesn't have to return to the starting vertex. It's an open path.
Similar to the Hamiltonian Cycle problem, finding a Hamiltonian Path in a general graph is also NP-complete and can be challenging. However, it is often a more easier problem than finding a Hamiltonian Cycle.
Hamiltonian Paths have applications in various fields, such as finding optimal routes in transportation networks, circuit design, and graph theory research.
Problem Statement
Given an undirected graph, the task is to determine whether the graph contains a Hamiltonian cycle or not. If it contains, then print the path, else print "Solution does not exist".
Generate all possible configurations of vertices and print a configuration that satisfies the given constraints. There will be n! (n factorial) configurations. So the overall Time Complexity of this approach will be at least n!.
[Expected Approach] Using Backtracking - O(2^n) Time and
The idea is to use backtracking to determine whether the given graph contains a Hamiltonian Cycle. Initialize an empty path array and place the starting vertex (e.g., vertex 0) at the first position. Recursively try to add the remaining vertices one by one. Before placing a vertex, ensure it is adjacent to the previously added vertex and has not already been used in the path. If a valid vertex is found, proceed forward; otherwise, backtrack and try another option.
Illustrations:
Let's find out the Hamiltonian cycle for the following graph:
Start with the node 0 .
Apply DFS for finding the Hamiltonian path.
When base case reach (i.e. total no of node traversed == n (total vertex)):
Check whether current node is a neighbour of starting node.
As node 2 and node 0 are not neighbours of each other so return from it.
Starting from start node 0 calling DFS
As cycle is not found in path {0, 3, 1, 4, 2}. So, return from node 2, node 4.
Now, explore another option for node 1 (i.e node 2)
When it hits the base condition again check for Hamiltonian cycle
As node 4 is not the neighbour of node 0, again cycle is not found then return.
Return from node 4, node 2, node 1.
Now, explore other options for node 3.
Hamiltonian Cycle
In the Hamiltonian path {0,3,4,2,1,0} we get cycle as node 1 is the neighbour of node 0.
So print this cyclic path .
This is our Hamiltonian cycle.
Note: The algorithm always begins constructing the cycle from a fixed starting vertex, but in a Hamiltonian cycle, the starting point is arbitrary. To allow flexibility in choosing the starting vertex, minor adjustments are needed so the cycle can initiate from any node rather than a predefined one.
C++
// C++ Code to check whether the given graph// contains Hamiltonian Cycle using backtracking#include<bits/stdc++.h>usingnamespacestd;// Check if it's valid to place vertex at current positionboolisSafe(intvertex,vector<vector<int>>&graph,vector<int>&path,intpos){// The vertex must be adjacent to the previous vertexif(!graph[path[pos-1]][vertex]){returnfalse;}// The vertex must not already be in the pathfor(inti=0;i<pos;i++){if(path[i]==vertex){returnfalse;}}returntrue;}// Recursive backtracking to construct Hamiltonian CycleboolhamCycleUtil(vector<vector<int>>&graph,vector<int>&path,intpos,intn){// Base case: all vertices are in the pathif(pos==n){// Check if there's an edge from // last to first vertexreturngraph[path[pos-1]][path[0]];}// Try all possible vertices as next candidatefor(intv=1;v<n;v++){if(isSafe(v,graph,path,pos)){path[pos]=v;if(hamCycleUtil(graph,path,pos+1,n)){returntrue;}// Backtrack if v doesn't lead to a solutionpath[pos]=-1;}}returnfalse;}// Initialize path and invoke backtracking functionvector<int>hamCycle(vector<vector<int>>&graph){intn=graph.size();vector<int>path(n,-1);// Start path with vertex 0path[0]=0;if(!hamCycleUtil(graph,path,1,n)){return{-1};}returnpath;}// Driver Codeintmain(){// Representation of the given graph// (0)-(1)-(2) // | / \ | // | / \ | // |/ \| // (3)-----(4)vector<vector<int>>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}};vector<int>path=hamCycle(graph);if(path[0]==-1){cout<<"Solution does not Exist";}else{for(inti=0;i<path.size();i++){cout<<path[i]<<" ";}// Print the first vertex again // to complete the cyclecout<<path[0];}return0;}
Java
// Java Code to check whether the given graph// contains Hamiltonian Cycle using backtrackingclassGfG{// Check if it's valid to place vertex at current positionstaticbooleanisSafe(intvertex,int[][]graph,int[]path,intpos){// The vertex must be adjacent to the previous vertexif(graph[path[pos-1]][vertex]==0){returnfalse;}// The vertex must not already be in the pathfor(inti=0;i<pos;i++){if(path[i]==vertex){returnfalse;}}returntrue;}// Recursive backtracking to construct Hamiltonian CyclestaticbooleanhamCycleUtil(int[][]graph,int[]path,intpos,intn){// Base case: all vertices are in the pathif(pos==n){// Check if there's an edge from // last to first vertexreturngraph[path[pos-1]][path[0]]==1;}// Try all possible vertices as next candidatefor(intv=1;v<n;v++){if(isSafe(v,graph,path,pos)){path[pos]=v;if(hamCycleUtil(graph,path,pos+1,n)){returntrue;}// Backtrack if v doesn't lead to a solutionpath[pos]=-1;}}returnfalse;}// Initialize path and invoke backtracking functionstaticint[]hamCycle(int[][]graph){intn=graph.length;int[]path=newint[n];for(inti=0;i<n;i++){path[i]=-1;}// Start path with vertex 0path[0]=0;if(!hamCycleUtil(graph,path,1,n)){returnnewint[]{-1};}returnpath;}// Driver Codepublicstaticvoidmain(String[]args){// Representation of the given graph// (0)-(1)-(2) // | / \ | // | / \ | // |/ \| // (3)-----(4)int[][]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}};int[]path=hamCycle(graph);if(path[0]==-1){System.out.print("Solution does not Exist");}else{for(inti=0;i<path.length;i++){System.out.print(path[i]+" ");}// Print the first vertex again // to complete the cycleSystem.out.print(path[0]);}}}
Python
# Python Code to check whether the given graph# contains Hamiltonian Cycle using backtracking# Check if it's valid to place vertex at current positiondefisSafe(vertex,graph,path,pos):# The vertex must be adjacent to the previous vertexifnotgraph[path[pos-1]][vertex]:returnFalse# The vertex must not already be in the pathforiinrange(pos):ifpath[i]==vertex:returnFalsereturnTrue# Recursive backtracking to construct Hamiltonian CycledefhamCycleUtil(graph,path,pos,n):# Base case: all vertices are in the pathifpos==n:# Check if there's an edge from # last to first vertexreturngraph[path[pos-1]][path[0]]# Try all possible vertices as next candidateforvinrange(1,n):ifisSafe(v,graph,path,pos):path[pos]=vifhamCycleUtil(graph,path,pos+1,n):returnTrue# Backtrack if v doesn't lead to a solutionpath[pos]=-1returnFalse# Initialize path and invoke backtracking functiondefhamCycle(graph):n=len(graph)path=[-1]*n# Start path with vertex 0path[0]=0ifnothamCycleUtil(graph,path,1,n):return[-1]returnpath# Driver Codeif__name__=="__main__":# Representation of the given graph# (0)-(1)-(2) # | / \ | # | / \ | # |/ \| # (3)-----(4)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]]path=hamCycle(graph)ifpath[0]==-1:print("Solution does not Exist")else:foriinrange(len(path)):print(path[i],end=" ")# Print the first vertex again # to complete the cycleprint(path[0])
C#
// C# Code to check whether the given graph// contains Hamiltonian Cycle using backtrackingusingSystem;classGfG{// Check if it's valid to place vertex at current positionstaticboolisSafe(intvertex,int[,]graph,int[]path,intpos){// The vertex must be adjacent to the previous vertexif(graph[path[pos-1],vertex]==0){returnfalse;}// The vertex must not already be in the pathfor(inti=0;i<pos;i++){if(path[i]==vertex){returnfalse;}}returntrue;}// Recursive backtracking to construct Hamiltonian CyclestaticboolhamCycleUtil(int[,]graph,int[]path,intpos,intn){// Base case: all vertices are in the pathif(pos==n){// Check if there's an edge from // last to first vertexreturngraph[path[pos-1],path[0]]==1;}// Try all possible vertices as next candidatefor(intv=1;v<n;v++){if(isSafe(v,graph,path,pos)){path[pos]=v;if(hamCycleUtil(graph,path,pos+1,n)){returntrue;}// Backtrack if v doesn't lead to a solutionpath[pos]=-1;}}returnfalse;}// Initialize path and invoke backtracking functionstaticint[]hamCycle(int[,]graph){intn=graph.GetLength(0);int[]path=newint[n];for(inti=0;i<n;i++){path[i]=-1;}// Start path with vertex 0path[0]=0;if(!hamCycleUtil(graph,path,1,n)){returnnewint[]{-1};}returnpath;}// Driver CodestaticvoidMain(){// Representation of the given graph// (0)-(1)-(2) // | / \ | // | / \ | // |/ \| // (3)-----(4)int[,]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}};int[]path=hamCycle(graph);if(path[0]==-1){Console.Write("Solution does not Exist");}else{for(inti=0;i<path.Length;i++){Console.Write(path[i]+" ");}// Print the first vertex again // to complete the cycleConsole.Write(path[0]);}}}
JavaScript
// JavaScript Code to check whether the given graph// contains Hamiltonian Cycle using backtracking// Check if it's valid to place vertex at current positionfunctionisSafe(vertex,graph,path,pos){// The vertex must be adjacent to the previous vertexif(!graph[path[pos-1]][vertex]){returnfalse;}// The vertex must not already be in the pathfor(leti=0;i<pos;i++){if(path[i]===vertex){returnfalse;}}returntrue;}// Recursive backtracking to construct Hamiltonian CyclefunctionhamCycleUtil(graph,path,pos,n){// Base case: all vertices are in the pathif(pos===n){// Check if there's an edge from // last to first vertexreturngraph[path[pos-1]][path[0]];}// Try all possible vertices as next candidatefor(letv=1;v<n;v++){if(isSafe(v,graph,path,pos)){path[pos]=v;if(hamCycleUtil(graph,path,pos+1,n)){returntrue;}// Backtrack if v doesn't lead to a solutionpath[pos]=-1;}}returnfalse;}// Initialize path and invoke backtracking functionfunctionhamCycle(graph){constn=graph.length;constpath=newArray(n).fill(-1);// Start path with vertex 0path[0]=0;if(!hamCycleUtil(graph,path,1,n)){return[-1];}returnpath;}// Driver Code// Representation of the given graph// (0)-(1)-(2) // | / \ | // | / \ | // |/ \| // (3)-----(4)constgraph=[[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]];constpath=hamCycle(graph);if(path[0]===-1){console.log("Solution does not Exist");}else{for(leti=0;i<path.length;i++){process.stdout.write(path[i]+" ");}// Print the first vertex again // to complete the cycleconsole.log(path[0]);}
Output
0 1 2 4 3 0
Time Complexity: O(n!), backtracking tries all permutations of n vertices. Each recursive call explores (n − 1) possibilities for remaining vertices. Space Complexity: O(n), path array takes O(n) space, and recursion stack also takes O(n).
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.