6

How many different trees are there with $(n-1)$ red vertices and $1$ blue vertex, such that the blue vertex has degree less than or equal to $3$, and each red vertex has degree less than or equal to $4$? Derive an explicit formula if possible.

The background of this problem is I was counting the number of isomers of $\mathrm C_n\mathrm H_{2n+1}\mathrm{Cl}$. Each carbon atom not connected to the chlorine atom can form bonds with at most $4$ other carbon atoms. The carbon atom connected to the chlorine atom can form bonds with at most $3$ other carbon atoms. Hence the counting problem described above.

Here is my idea: we observe the carbon atom connected to the chlorine atom (the red vertex). It is connected to three other alkyls so we might apply some kind of recursion. But this doesn't seem to lead to an explicit formula.

RobPratt
  • 50,938
youthdoo
  • 3,663
  • Related: The number of structural isomers of an alkane is $2^{n-4}-1$, where $4 \le n \le 7$. The question now becomes; How many unique positions can I substitute the Chlorine atom for a hydrogen atom, as well as how can we properly count the branches for alkanes with $n\ge 8$ – Tveltzel Mar 29 '25 at 11:45

2 Answers2

6

Your sequence can be found in A000598, the "number of unlabeled rooted trees in which each node has out-degree <= 3".

What does your problem have to do with rooted ternary trees? These are trees with a fixed root (the blue vertex) where every vertex has at most 3 children. Imagine letting your tree "hang" from the blue vertex. Note that the blue vertex has at most 3 vertices directly below it (since it has degree at most 3) and the red vertices all also have at most 3 vertices directly below them (since they have degree at most 4, but one of those connections points "upward").

Write $T(z) = \sum_n t_n z^n$ for the generating function where $t_n$ is the number of rooted ternary trees with $n$ total vertices. We want another (recursive) expression for $T$ that we can use to solve for these coefficients. To find one, we recognize every such tree falls into one of the following cases:

  • just the root
  • the root with one child, which is recursively a rooted ternary tree
  • the root with two children, each of which is a rooted ternary tree
  • the root with three children, each of which is a rooted ternary tree

This gives the recurrence $T = z + zT + zT^2 + zT^3$, which is unfortunately not quite right. This counts ordered ternary trees, where we keep track of which subtree is the first/seconds/third child. But as a warmup, we solve $z = T/(1 + T + T^2 + T^3)$, and lagrange inversion lets us invert this to get $T$ as a function of $z$. We compute it to be $T(z) = z + z^2 + 2z^3 + 5z^4 + 13z^5 + 36z^6 + \ldots$ which OEIS tells us is A036765, "the number of ordered unlabeled rooted trees on n+1 nodes where each node has no more than 3 children."

Ok, so how do we remove the dependence on order? Well if we have 2 children we should count orbits of the symmetric group $\mathfrak{S}_2$ acting on pairs of trees. And if we have 3 children we should count orbits of $\mathfrak{S}_3$ acting on triples of trees. This sounds like a difficult task unless you know about the extension of Pólya-Redfield Counting that works with arbitrary generating functions! See, for instance, the end of this blog post or pp. 85-86 of Flajolet and Sedgewick's Analytic Combinatorics.

Say we have a set $X$ acted on by a group $G$, and we want to count the number of ways to "color" the points in $X$ by objects counted by a generating function $F(z)$... up to the $G$ action! Then this general version of Pólya-Redfield tells us the relevant generating function is $P_G \left (F(z), F(z^2), F(z^3), \ldots, F(z^{|X|}) \right )$ where $P_G$ is the cycle index polynomia for $G$ (viewed as a subset of $\mathfrak{S}_{|X|}$).

For us, we want to "color" the points of $\{1,2\}$ and $\{1,2,3\}$ by rooted ternary trees and count the colorings up to an action of the symmetric group!

One can compute (or look up) the cycle index polynomials for $\mathfrak{S}_1$, $\mathfrak{S}_2$, and $\mathfrak{S}_3$ are:

  • $P_{\mathfrak{S}_1}(x_1) = x_1$
  • $P_{\mathfrak{S}_2}(x_1,x_2) = \frac{1}{2}(x_1^2 + x_2)$
  • $P_{\mathfrak{S}_3}(x_1,x_2,x_3) = \frac{1}{6}(x_1^3 + 3x_1x_2 + 2 x_3)$

So finally we get to the recurrence we want for $T$:

$$ T(z) = z + zP_{\mathfrak{S}_1} \big (T(z) \big ) + z P_{\mathfrak{S}_2} \big (T(z), T(z^2) \big ) + z P_{\mathfrak{S}_3} \big (T(z), T(z^2), T(z^3) \big ) $$

Note that this is the same relation Marko has, where I'm writing $P_G(-)$ instead of $Z(G;-)$ and I'm making all the variables explicit. Now if we expand out both sides, we get a (complicated!) recurrence relation for our $t_n$:

$$ t_1 z + t_2 z^2 + t_3 z^3 + t_4 z^4 + \ldots = z + t_{1} z^{2} + \left( \frac{1}{2} t_{1}^{2} + \frac{1}{2} t_{1} + t_{2} \right) z^{3} + \left( \frac{1}{6} t_{1}^{3} + \frac{1}{2} t_{1}^{2} + t_{1} t_{2} + \frac{1}{3} t_{1} + t_{3} \right) z^{4} + \ldots $$

We can ask sagemath to solve this for us, and we see:

# how many coefficients do you want?
n = 10

a polynomial ring in variables t[0], t[1], t[2], t[3], ... t[n]

B = PolynomialRing(QQ, 't', n+1) t = B.gens()

power series ring with coefficients in QQ[t[0], t[1],... t[n]]

R.<z> = B[[]]

cycle index polynomials

S.<x1,x2,x3> = QQ[] P1 = x1 P2 = (x1^2 + x2)/2 P3 = (x1^3 + 3x1x2 + 2*x3)/6

build our recurrence

T = sum([t[i] * z^i for i in range(1,n+1)]) + O(z^(n+1))

lhs = T rhs = z + zP1.subs(x1=T(z)) + zP2.subs(x1=T(z), x2=T(z^2)) + z*P3.subs(x1=T(z), x2=T(z^2), x3=T(z^3))

solve the recurrence by quotienting the relation that the ith coefficient

on the left hand side minus the ith coefficient on the right hand side equals 0

I = B.ideal([lhs.coefficients()[i] - rhs.coefficients()[i] for i in range(n)])

now reduce each of the coefficents modulo this ideal and sum them up again

to get a new, cleaner, version of T

Tnew = sum([I.reduce(t[i]) * z^i for i in range(1,n+1)]) print(Tnew)

When you run this code, sage happily prints out

$$z + z^{2} + 2 z^{3} + 4 z^{4} + 8 z^{5} + 17 z^{6} + 39 z^{7} + 89 z^{8} + 211 z^{9} + 507 z^{10}$$

which agrees with A000598.


I hope this helps ^_^

  • Very nice to see another contribution. I also have a Maxima program which gives the same output as the Maple code. I wonder though how OEIS A036376 can possibly be right -- did you read their functional equation? It has outdegree of each node being exactly three, whereas OP asks for at most three (since we can use hydrogen atoms, the fourth connects to the carbon atom parent). Maybe you want to check this one more time. – Marko Riedel Mar 30 '25 at 02:05
  • @MarkoRiedel -- interesting... Do you see what the difference in our approaches is, then? It's extremely unclear to me why my code or method (which I believe agrees with your method, but it's hard to tell since I'm not sure how to interpret $Z(S_3; T)$) would be related to "full" ternary trees, which each internal node has exactly 3 children. I tried to explain my logic in detail so that you might be able to spot the discrepancy between our answers (since again, I don't fully understand yours. If you're willing to say more about what your notation means, I can do the legwork of comparing) – Chris Grossack Mar 30 '25 at 02:31
  • @MarkoRiedel -- Ah, in fact, the wrong sequence came up first. See A000598, which is "Number of unlabeled rooted trees in which each node has out-degree <= 3." This is a pretty unambiguous description, and agrees with my computation. – Chris Grossack Mar 30 '25 at 02:47
  • 1
    Thanks ever so much for alerting me to the bug. I was able to generalize my PET code with your observations. – Marko Riedel Mar 30 '25 at 20:27
  • @MarkoRiedel -- Glad to hear it! ^_^ – Chris Grossack Mar 30 '25 at 20:53
3

With the following we set a modest goal, namely to compute enough data for lookup in the OEIS. We have using the cycle index of the symmetric group and an ordinary GF $T(z)$

$$T(z) = z + z \times (Z(S_3; T(z))+Z(S_2; T(z))+Z(S_1; T(z))).$$

where $[z^0] T(z) = 0.$ Here the blue vertex is the root and the red vertices are the subnodes. We assume that for a vertex of some degree less than four the bonds are filled with hydrogen atoms to make a total of four bonds. Using combinatorial classes as in Analytic Combinatorics by Flajolet and Sedgewick the above implements the specification

$$\def\textsc#1{\dosc#1\csod} \def\dosc#1#2\csod{{\rm #1{\small #2}}} \mathcal{T} = \mathcal{Z} + \mathcal{Z} \times \textsc{MSET}_{=3}(\mathcal{T}) + \mathcal{Z} \times \textsc{MSET}_{=2}(\mathcal{T}) + \mathcal{Z} \times \textsc{MSET}_{=1}(\mathcal{T}).$$

We get the sequence

$$1, 1, 1, 2, 4, 8, 17, 39, 89, 211, 507, 1238, 3057, \\ 7639, 19241, 48865, 124906$$

This is sequence A000598 from the OEIS where a considerable variety of relevant material awaits. In particular an alternative functional equation is proposed where we include hydrogen atoms with the specification in hydrogens and carbons being

$$\def\textsc#1{\dosc#1\csod} \def\dosc#1#2\csod{{\rm #1{\small #2}}} \mathcal{T} = \mathcal{H} + \mathcal{C} \times \textsc{MSET}_{=3}(\mathcal{T})$$

which gives the equation

$$T(z) = 1 + z \times Z(S_3; T(z))$$

The code below was used to compute this sequence, in two ways, by solving a system of equations for the coefficients of an initial segment of $T$ which gave results fast and a recurrence that is considerably more efficient. We use the second functional equation to implement the recurrence so as to get the minimum number of memoized recursive calls.

Thanks go to @ChrisGrossack for alerting me to a bug in my code.

with(combinat);
with(numtheory);

pet_varinto_cind := proc(poly, ind, excl) local subs1, subs2, polyvars, indvars, v, pv, pot, res;

res := ind;

polyvars := {};

for pv in indets(poly) do
    if not member(op(0, pv), excl)  then
        polyvars := {op(polyvars), pv};
    fi;
od;

indvars := indets(ind);

for v in indvars do
    pot := op(1, v);

    subs1 :=
    [seq(polyvars[k]=polyvars[k]^pot,
         k=1..nops(polyvars))];

    subs2 := [v=subs(subs1, poly)];

    res := subs(subs2, res);
od;

res;

end;

pet_cycleind_symm := proc(n) option remember;

if n=0 then return 1; fi;

expand(1/n*add(a[l]*pet_cycleind_symm(n-l), l=1..n));

end;

CFS := proc(n) option remember; local T, R, k, sys; T := add(q[k]*z^k, k=0..n);

R := z
+ z*pet_varinto_cind(T, pet_cycleind_symm(3), {q})
+ z*pet_varinto_cind(T, pet_cycleind_symm(2), {q})
+ z*pet_varinto_cind(T, pet_cycleind_symm(1), {q});

R := expand(R);

sys := {seq(q[k] = coeff(R, z, k), k=0..n)};

subs(solve(sys), [seq(q[k], k=0..n)]);

end;

REC := proc(n) option remember; local res, a, b, c;

if n=0 or n=1 then return 1 fi;

res := 0;

for a from 0 to n-1 do
    for b from 0 to n-1-a do
        c := n-1-a-b;
        res := res + 1/6*REC(a)*REC(b)*REC(c);
    od;
od;

for a from 0 to floor((n-1)/2) do
    b := n-1-2*a;
    res := res + 1/2*REC(a)*REC(b);
od;

if n-1 mod 3 = 0 then
    a := (n-1)/3;
    res := res + 1/3*REC(a);
fi;

res;

end;

Marko Riedel
  • 64,728
  • Thanks. By the way, the code is Maple right? – youthdoo Mar 30 '25 at 00:07
  • This is Maple. I also have a version in Maxima, which is GPLed and free if you want to see that, always supposing I have the right problem definition. The count of hydrogen atoms matches the above. – Marko Riedel Mar 30 '25 at 00:28
  • @MarkoRiedel -- I think there might be a bug in your code, but I'm not sure where... see my answer – Chris Grossack Mar 30 '25 at 01:17