Using directed graphs to count the number of patterns
How many n-digit numbers are there which do not contain 122 and 213 in them? Numbers start with a nonzero digit.
We can write a directed graph to solve that, the weighted adjacency matrix for which is given by:
'I' is the initial state, '1' and '2' are the states if those digits are the last encountered. \(A\) is for any other valid digits. It goes to state \(12\) or \(21\) if we see a sequence of 12 or 21, respectively. The number of ways of valid transitions are given as the weights.
There, the hard work is done. Leave the remaining to Sage!
Obtain the characteristic polynomial of the matrix, which also is the characteristic equation of the required recurrence equation.
am=matrix([ [0, 7, 1, 1, 0, 0], [0, 8, 1, 1, 0, 0], [0, 8, 1, 0, 1, 0], [0, 8, 0, 1, 0, 1], [0, 8, 0, 0, 0, 1], [0, 7, 1, 0, 1, 0] ]) print am.characteristic_polynomial() |
The characteristic equation is:
So, the recurrence would be:
Wonder if anyone can come up with a combinatorial argument for that equation?!
Initial conditions can be easily obtained by matrix exponentiation or using a program to iterate through the sequences, e.g.
print sum((am^4)[0,:].list()) |
or
cnt = 0 for i in range(1000,10000): if str(i).find('122')==-1 and str(i).find('213')==-1: cnt += 1 print cnt |
We can also automatically get the generating function of the obtained recurrence by using a small program (method is given in "Lectures on generating functions" by S. K. Lando):
which gives the g.f.
There are tremendous uses of generating functions, one of which is to obtain an asymptotic formula. (See William Feller's book on probability for a brief explanation on the topic)
If we have a generating function of the form \(G(x)=U(x)/V(x)\), then the asymptotic form is given by
We will visually inspect where the roots lie, to get an idea about the closest root to the origin
complex_plot(x^5 - 2*x^3 + 10*x - 1,(-2, 2), (-2, 2)) |
and we see that there is only one real root (also the nearest to origin) and other four are complex.
We can proceed with the following steps in Sage:
s1=find_root(x^5 - 2*x^3 + 10*x - 1, 0, 4) rho1=(1-s1)/diff(x^5 - 2*x^3 + 10*x - 1,x).subs(x=s1) f(n)=rho1/s1^(n+1) print int(f(15)),f(n) |
We find the approximation to be
The \(15^{th}\) term using the asymptotic formula gives about \(876700051238642\), which is only a little more than the actual value of \(876700051238641\).