Golang
Golang

 

The problem of finding a Hamiltonian cycle is to find a cycle that visits every vertex in a graph exactly once and returns to the starting vertex. This problem is NP-complete, meaning no efficient solution is known for all cases.

Program Overview

In this program, we will use a backtracking approach to find a Hamiltonian cycle in a graph represented by an adjacency matrix. The algorithm explores all possible paths, and if it finds a path that forms a Hamiltonian cycle, it returns true.

Go Program Code


// HamiltonianCycle.go - Find a Hamiltonian cycle in a graph

package main

import (
    "fmt"
)

// Function to check if a vertex v can be added to the Hamiltonian cycle
func isSafe(v int, graph [][]int, path []int, pos int) bool {
    // Check if this vertex is an adjacent vertex of the previously added vertex.
    if graph[path[pos-1]][v] == 0 {
        return false
    }

    // Check if the vertex has already been included.
    for i := 0; i < pos; i++ {
        if path[i] == v {
            return false
        }
    }

    return true
}

// Utility function to solve the Hamiltonian Cycle problem using backtracking
func hamiltonianCycleUtil(graph [][]int, path []int, pos int) bool {
    // Base case: If all vertices are included in the cycle
    if pos == len(graph) {
        // Check if there is an edge from the last vertex to the first vertex
        if graph[path[pos-1]][path[0]] == 1 {
            return true
        }
        return false
    }

    // Try different vertices as the next candidate in the cycle
    for v := 1; v < len(graph); v++ {
        if isSafe(v, graph, path, pos) {
            path[pos] = v

            // Recur to add the next vertex to the path
            if hamiltonianCycleUtil(graph, path, pos+1) {
                return true
            }

            // If adding vertex v doesn't lead to a solution, remove it (backtrack)
            path[pos] = -1
        }
    }

    return false
}

// Function to solve the Hamiltonian Cycle problem and print the cycle
func hamiltonianCycle(graph [][]int) {
    path := make([]int, len(graph))
    for i := range path {
        path[i] = -1
    }

    // Start with the first vertex
    path[0] = 0

    // Start the recursive backtracking function to find the Hamiltonian cycle
    if !hamiltonianCycleUtil(graph, path, 1) {
        fmt.Println("No Hamiltonian cycle found")
    } else {
        fmt.Println("Hamiltonian cycle found:", path)
    }
}

func main() {
    // Example adjacency matrix representation of the graph
    graph := [][]int{
        {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},
    }

    hamiltonianCycle(graph)
}
    

Explanation of the Program Structure

  • Graph Representation: The graph is represented using an adjacency matrix, where graph[i][j] equals 1 if there is an edge between vertex i and vertex j, and 0 otherwise.
  • isSafe Function: This function checks whether it is safe to add a vertex to the Hamiltonian cycle. It verifies two conditions: whether the vertex is adjacent to the previously added vertex and whether the vertex has already been included in the cycle.
  • hamiltonianCycleUtil Function: This function performs the recursive backtracking. It tries to construct the Hamiltonian cycle by exploring all possible vertices. It uses the isSafe function to determine whether a vertex can be added to the cycle.
  • hamiltonianCycle Function: This function initializes the path array and calls the recursive utility function. If a Hamiltonian cycle is found, it prints the cycle; otherwise, it prints that no Hamiltonian cycle exists.

Example Output


Hamiltonian cycle found: [0 1 2 4 3]
    

In the example above, the Hamiltonian cycle starts from vertex 0 and visits vertices 1, 2, 4, 3, and returns to vertex 0, forming a valid Hamiltonian cycle.

Conclusion

This Go program provides a backtracking solution to find a Hamiltonian cycle in a graph. The approach works for small graphs but may not be efficient for large graphs due to the exponential number of possible paths.

 

By Aditya Bhuyan

I work as a cloud specialist. In addition to being an architect and SRE specialist, I work as a cloud engineer and developer. I have assisted my clients in converting their antiquated programmes into contemporary microservices that operate on various cloud computing platforms such as AWS, GCP, Azure, or VMware Tanzu, as well as orchestration systems such as Docker Swarm or Kubernetes. For over twenty years, I have been employed in the IT sector as a Java developer, J2EE architect, scrum master, and instructor. I write about Cloud Native and Cloud often. Bangalore, India is where my family and I call home. I maintain my physical and mental fitness by doing a lot of yoga and meditation.

Leave a Reply

Your email address will not be published. Required fields are marked *

error

Enjoy this blog? Please spread the word :)