graphrackethamiltonian-cyclerecursive-backtracking

Recursive backtracking in Racket?


A while ago, as a proof of concept (and because I was using Logo with my autistic son) I wrote a program in Logo to find a Hamiltonian circuit in a graph (if it exists) using a backtracking method. The basic backtracking schema I used was:

boolean hamilton(path p, graph g) 
  {
  if p has as many vertices as g 
    {
    if the last and first vertices in p are adjacent, 
      return true
    else 
      return false
    } 
  else 
    {
    for each vertex x of g not in p and adjacent to the last vertex of p
      {
      if hamilton(path p + x,graph g) succeeds, 
        return true
      }
    return false
    }
  }

and you can see a discussion here. I could do this easily in Logo because it allows multiple exit points from a function with the OUTPUT command.

However, Racket doesn't allow multiple exit points (at least, not easily). So I'm hoping to be pointed in the direction of some material which would explain (a) how to manage multiple exit points from a function (I have a vague notion I can do it with continuations, as with let/ec) or (b) how to manage recursive backtracking in Racket in a way maybe better suited to the language.

As a newcomer to Racket, I'm sure this could be done in the twinkling of an eye by an expert, or even by anybody less of a raw beginner then me. But right now I fund myself quite stumped. Thanks!


Solution

  • I think this will work:

    (define (hamilton p g)
      (if (>= (number-of-vertices p)
              (number-of-vertices g))
          (first-and-last-vertex-adjacent? p)
          (for/or ([v (in-vertices g)])
            (and (not (belongs-to-path v p))
                 (not (adjacent v) (last-vertex p))
                 (hamilton (append-vertex p x) g)))))