I have this very basic code to count Hamiltonian paths in a graph:
privateCountHamiltonians =
Function[{vertices, current, visited}, Module[{newVisited }, (
newVisited = Append[visited, current];
If[
Length[newVisited] == Length[vertices],
1,
Total[ Map[
If[! MemberQ[newVisited, #],
privateCountHamiltonians[vertices, #, newVisited], 0] &,
vertices[[current]]
]]
])
]];
makeVertices[edges_] := Module[{list}, (
list = ConstantArray[{}, Max[edges]];
Scan[Function[edge, (
AppendTo[list[[edge[[1]]]], edge[[2]]];
AppendTo[list[[edge[[2]]]], edge[[1]]];
list
)], edges];
list
)];
countHamiltonians[edges_] := Module[{vertices}, (
vertices = makeVertices[edges];
Total[
Map[privateCountHamiltonians[vertices, #, {}] &,
Range[1, Length[vertices]]]]
)];
The edges
argument must have the form {{1, 2}, {2, 3}, ...}
where each item inside represents an edge. The bottleneck is privateCountHamiltonians
since is where recursion occurs. I thought using Combinatorica's HamiltonianPath
would be more effective, but surprisingly that one is way slower than mine, at least on not so big graphs, as per this code:
<< Combinatorica`
g = Combinatorica`GridGraph[2, 4];
Timing[countHamiltonians[Combinatorica`Edges[g]]]
Timing[Length[Combinatorica`HamiltonianPath[g, All]]]
Which yielded:
{0.015625, 28}
{21.093750, 28}
I'm not hoping to implement some of the existing advanced algorithms, but since I'm new to Mathematica, I wonder if there is some simple things I'm overlooking that could make my code run faster.