I was thinking recently about a possible solution to find, in polynomial time, whether an undirected graph has a Hamiltonian path or not.
The main concept used as part of this implementation is based on an observation that I noticed while trying to find (i.e. on paper) a Hamiltonian path for several undirected graphs.
The steps could be defined as follows:
Read the adjacency matrix of the graph.
While the adjacency matrix is being read, a map (i.e. dictionary-based structure) will be created for all the nodes. Also, the starting node of the path will be selected while the adjacency matrix is being read. These operations can be described as follows:
2.1. The map will store all the nodes from the graph, as a key - value structure.
Each entry in the map will be represented as: (key: node index, value: node class)
The node class will contain the following details about the node: node index, number of incident edges to it, and a flag to indicate if the current node has already been visited or not.
By taking into consideration that each entry in the map will contain just the value corresponding to that node, it can be stated that any read access from the map for a given node index will be constant (i.e. O(1)).
2.2. As part of reading the adjacency matrix and building the map at step 2.1., the starting node will also be retained. The starting node of the path will be represented by the node which has the minimum number of edges incident to it.
If multiple nodes exist in the graph with this property, then the node with the lowest index number will be selected. In this context, we can assume that each node will have an index associated to it, starting from zero: 0, 1, 2, etc.
The starting node identified at step 2.2. will be marked as visited.
The next operations will be followed for the remaining nodes. The loop will end either when the number of visited nodes is equal to the number of nodes from the graph, or when there hasn't been found an unvisited adjacent node for the current node.
Therefore, the next steps will be followed as part of this loop:
4.1. The first operation will be to find the next node to visit.
The next node to be visited will have to respect the following constraints:
- To have an edge to the current node
- To not have been visited so far
- To have the minimum number of edges incident to it, when compared to the other adjacent nodes
to the current node.
4.2. If a next node hasn't been found, then the algorithm will end and indicate that no Hamiltonian paths were found.
4.3. If a next node has been found, then this will represent the current node. It will be marked as visited, and the number of visited nodes will be incremented.
If the number of visited nodes is equal to the number of nodes from the graph, then a Hamiltonian path has been found. Either way, a message will be displayed based on the outcome of the algorithm.
The implementation / tests are available on GitHub: https://github.com/george-cionca/hamiltonian-path
My main questions are:
- Is there an undirected graph which would cause this algorithm to not generate the correct solution?
- On the repository's page, I included a few more details and stated that this implementation provides a solution in quadratic time (i.e. O(n2)). Is there any aspect that I haven't taken into account for the time complexity?