Backtracking is a general algorithm for finding all (or some) solutions to some computational problem, that incrementally builds candidates to the solutions, and abandons each partial candidate c ("backtracks") as soon as it determines that c cannot possibly be completed to a valid solution. (from Wikipedia)

In pseudo-code, a backtracking algorithm looks something like this:

 procedure bt(c)
   if reject(P,c) then return
   if accept(P,c) then output(P,c)
   s ← first(P,c)
   while s ≠ Λ do
     s ← next(P,s)


  1. root(P): return the partial candidate at the root of the search tree.
  2. reject(P,c): return true only if the partial candidate c is not worth completing.
  3. accept(P,c): return true if c is a solution of P, and false otherwise.
  4. first(P,c): generate the first extension of candidate c.
  5. next(P,s): generate the next alternative extension of a candidate, after the extension s.
  6. output(P,c): use the solution c of P, as appropriate to the application.

The backtracking algorithm then starts with the call bt(root(P)).

I'm trying to program this as efficiently as possible in Mathematica. I have already coded the pertinent root, reject, accept, first, and next functions. Since I only need to obtain one solution, I am doing the output through a Throw, Catch combo.

Given that one has the basic logic of root, reject, ..., already coded, are there alternative ways to program the backtracking loop (procedure bt above) in Mathematica?

What I have in mind is a substitution of while with something more Mathematica friendly, such as Fold or Map, but I have no idea of how to do this.

  • 3
    $\begingroup$ It's hard to give a general solution for such a generic description. I do something similar to this in this answer to the Boggle question, where I start down a node and evaluate the partial candidates and reject the subtree if the partial candidate will never lead to a useful solution. I do this with using Condition. See the functions proceedQ and sowWord for the equivalents of reject/accept and output respectively. first/next are implemented via recursion... $\endgroup$
    – rm -rf
    Jun 28, 2012 at 2:26
  • $\begingroup$ @R.M I think I cannot use what you suggest. I cannot store my backtrack tree in a graph (or an analogue like an adjacency matrix) because it is huge. Imagine beginning a scan of chess positions by storing a graph will all the possible positions. Not possible. I haven't read Leonid's enormous answer to the question you reference, but if it also stores a representation of the search space, I can't use it. $\endgroup$
    – a06e
    Jun 28, 2012 at 3:21
  • 1
    $\begingroup$ Anything doable by procedural programming can be done recursively (and functionally). And then the symmetry comes to an end. Iterative (procedural) programming is the way to go if you have severe memory constraints. No le pidas peras al olmo $\endgroup$ Jun 28, 2012 at 4:05
  • 1
    $\begingroup$ @belisarius I think we need to accumulate more non-trivial problems solved by some variant of backtracking, and then see if we have some common implementation patterns (e.g. using linked lists + recursion, etc). I don't believe that we can totally separate the backtracking pattern from implementation in Mathematica, given that efficiency is always one of the main goals, and (particularly in Mathematica) it depends drastically on implementation details (such as the choice of data structures, etc). $\endgroup$ Jun 28, 2012 at 12:14
  • 1
    $\begingroup$ I just discovered the guidelines tag and I think it goes with this question. @DanielLichtblau I do not need to store all the possible chess positions to search them. I just need methods that given a chess position, return other positions to explore (next and first) in an organized fashion. $\endgroup$
    – a06e
    Jun 29, 2012 at 2:09

1 Answer 1


Backtracking is never efficient so I would suggest always using C for this. However if you must do this in mathematica, here is an example of the generalized backtrack algorithm (as taken almost literally from the Combinatorica` package's Backtrack function) specifically applied to graph coloring:

backtrack[space_List, partialQ_, solutionQ_, flag_: 1] := 
 Module[{n = Length[space], all = {}, done, index, v = 2, solution},
    index = Prepend[Table[0, {n - 1}], 1];
    Monitor[While[v > 0,
            done = False;
            While[! done && (index[[v]] < Length[space[[v]]]),
                   done = partialQ[Solution[space, index, v]];
            If[done, v++, index[[v--]] = 0];
            If[v > n,
                solution = Solution[space, index, n];
                    If[SameQ[flag, All],
                            AppendTo[all, solution],
                            all = solution; v = 0;
        ], index];

Solution[space_List, index_List, count_Integer] :=

  Module[{i}, Table[space[[i, index[[i]]]], {i, count}]];

ProperColorQ[color_List] := {} == 
   Cases[EdgeList[gr] /. Thread[Range[Length[color]] -> color], 
    x_ \[UndirectedEdge] x_, \[Infinity], 1];

Ccoloring[c_Integer, g_Graph] :=

 Module[{coloring, x, v = Length[VertexList[g]]},
  coloring = backtrack[Join[{{1}}, Table[Range[c], {i, v - 1}]],
    ({} == 
       Cases[EdgeList[g] /. Thread[Range[Length[#]] -> #], 
        x_ \[UndirectedEdge] x_, \[Infinity], 1]) &,
    ({} == 
       Cases[EdgeList[g] /. Thread[Range[Length[#]] -> #], 
        x_ \[UndirectedEdge] x_, \[Infinity], 1]) &,

chromaticNumber[g_Graph /; ConnectedGraphQ[g]] :=
 Module[{c, i = 2},
  c = Ccoloring[i, gr];
  While[c == {}, c = Ccoloring[i, gr]; i++];
  {i - 1,
    VertexLabels -> 
     Table[i -> Placed[c[[i]], Center], {i, Length[VertexList[g]]}], 
    VertexStyle -> 
     Thread[Range[Length[VertexList[g]]] -> 
       Hue /@ Rescale[c, {0, 0.9}]]]}

gr = RandomGraph[BernoulliGraphDistribution[13, 0.5], 
  VertexLabels -> "Name"]
chromaticNumber[gr] // AbsoluteTiming
  • $\begingroup$ Thanks. In your experience, how much faster can C be compared to Mathematica when doing backtraking? $\endgroup$
    – a06e
    Jul 7, 2012 at 14:35
  • 3
    $\begingroup$ If your code references someone else's, it's worth mentioning, so I edited in the reference $\endgroup$
    – Rojo
    Mar 3, 2014 at 19:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.