function path = a_to_b_path ( adj, a, b )
%
%% A_TO_B_PATH: Return a path from node A to node B.
%
%  ADJ(N,N) is the adjacency matrix for the graph G.
%
%  A and B are nodes in the graph.  So we expect 1 <= A, B <= N.
%
%  PATH is output by the function:
%  If a path from A to B was found, then PATH contains the sequence of nodes,
%  beginning with A and ending with B, that form the path.
%  If no path was found, then PATH is the empty list [].
%
  path = [];
%
%  How many nodes are there?
%
  [ n, n ] = size ( adj );
%
%  REACH(I) is the node that first "reached" node I.
%  REACH(A) is -1, to indicate that this is the start of the path.
%
  reach = zeros(1,n);
  reach(a) = -1;
%
%  NEW holds the nodes we have just reached on this step.
%
  new = [ a ];
%
%  As long as NEW isn't empty, we reached some new nodes.
%  Use them as stepping stones, and try to reach more nodes.
%
  while ( 0 < length ( new ) )
    old = new;
    new = [];
%
%  For each node J that we found on the previous step...
%
    for k = 1 : length ( old )
      j = old(k);
%
%  ...look for adjacent neighbors I...
%
      for i = 1 : n
        if ( adj(i,j) == 1 )
%
%  ...and if node I has not been reached already, 
%  point back to node J, and add node I to the "new" list.
%
          if ( reach(i) == 0 )
            reach(i) = j;
            new = [ new, i ];
%
%  If node I is actually our goal, then use REACH to figure out
%  how we got to node B from node A, and RETURN.
%
            if ( i == b )
              node = b;
              while ( node ~= -1 )
                path = [ node, path ];
                node = reach(node);
              end
            end

          end
        end
      end
    end
  end
%
%  If we got here, no path was found.
%
  return
end
