Turning generative recursion results (leaves of a tree) into connected components (where each neighbour differs by one element)
EDIT My initial interpretation was clearly incorrect although some of the content may be useful to someone so I'll leave it at the bottom of all this. 

With that, it seems like each step further into the tree will lead you to a mutually exclusive path (e.g. timetables can't have $A_1$ and $A_2$). This split is what we can call a "decision point". Assuming all your leaf-node timetables are stored in a list, you could figure out where the decision point was, and then bounce over to the corresponding node with the alternate decision.

Example: Let's say, similar to your example we have courses $A$ and $B$, with sections $A_1, A_2, A_3, B_1, B_2$. We then get a decision tree:



You can see the decision point of course $A$ is at the first level. Similarly you see the decision point of course $B$ is at the second level. The red line in there represents an example of two timetables that differ only by their grandparent, rather than just their parent. We can use some math and indexing to figure out how they're related.

As long as your course decision at each level is consistent, we can use some math and indexing to figure this out pretty easily. 

Let's say you have $n$ courses: $c_1, c_2, \dots, c_n$. 

Now let's define the size of a course as the number of sections = $|c_i|$.

It's pretty clear to see that, in the end, the number of leaf node timetables we'll have is $m = \prod_{i=1}^n |c_i|$. Let's assume courses are decided in increasing order (i.e. $c_1$ is decided at level 1 in the decision tree, $c_2$ is decided at level 2, etc.). If your leaf nodes are contained in a list, we can easily find related nodes based on the level of a particular course decision.

Let's say we look at leaf node timetable $j$. If we want to find all timetables that only differ at course $i$, we know they will be $\frac{m}{\prod_{k = 1}^i |c_k|}$ away. 

An example might help, it's extremely clear if we're only dealing with a binary tree (each course has 2 sections). Let's say we have 3 courses: $A, B, C$. We then end up with a list of leaf nodes:

$$\left[(A_1, B_1, C_1), (A_1, B_1, C_2), (A_1, B_2, C_1), (A_1, B_2, C_2), (A_2, B_1, C_1), (A_2, B_1, C_2), (A_2, B_2, C_1), (A_2, B_2, C_2)\right]$$

We can represent these in binary:

$$\left[000, 001, 010, 011, 100, 101, 110, 111\right]$$

If we wanted to find where $111$ differs at course $B$. We find the distance between them is:

$$
\begin{align}
d &amp; = \frac{m}{\prod_{k = 1}^i |c_k|}\\ 
&amp; = \frac{8}{\prod_{k = 1}^2 |c_k|}\\
&amp; = \frac{8}{2 \cdot 2}\\
&amp; = 2\\
\end{align}
$$

Now deciding whether to subtract or add this distance is left up to simple edge case handling. But we see that 2 indices away from $111$ is $101$, which is the difference at course $B$ we were looking for. You should be able to take this approach to determine each differing timetable without having to compare everyone.

Misinterpretted Response Below

This algorithm seems similar to itemset lattice generation in association rule mining. Not the actual machine learning part, just the itemset generation. With this in mind, memoization in general would help downsize the repeated timetables. If you find that a child subproblem has already been solved, you can link the parent to that memoized solution, reducing the amount of links in your tree while keeping the children/parent connections consistent. 

Memoization could also help with the "one section swap" connection. You already know all siblings will be "one section swap" connections. From there, it's simple to see that all leaf siblings will be connected. Using memoization these leaf-to-leaf sibling relationships will be much tighter and should basically figure themselves out. 

Let's take an example with 5 sections $A, B, C, D, E$, assume a timetable is full when it gets 3 courses and just to add some variation let's say section $A$ conflicts with section $E$. If my understanding is correct your graph should look like the following, where green edges are "memoized" edges from parent to memoized child. Red crossed nodes are conflicting timetables. 



Then, you may notice that we can construct a sibling graph of the leaf nodes:



Interestingly (but expected) the sibling graph connects all valid complete timetables and all connections are "one section swap" connections! So I definitely think memoization is the way to go.