← Back to list

Punnett Squares, Flowers and Bayesian Networks

Here’s a simple science puzzle from Brilliant.org that I am working on.

Pascal Bercker · 2026-03-08 21:50 · 4 claps · 5.1 min read
#probability #bayesian-networks #mendelian-genetics #punnett-square #netica
Open on Medium ↗
Wiki topics: 📐 · Mathematics 🔬 · Science · General

Punnett Squares, Flowers and Bayesian Networks

Here’s a simple science puzzle from Brilliant.org that I am working on.

P is a dominant trait for round petal while p is a recessive trait for long petal

P is a dominant trait for round petal while p is a recessive trait for long petal

The alleles correspond to these traits:

Dominant and recessive traits

Dominant and recessive traits

We are given the following choices:

If you look carefully at the parental alleles you will know the tricky answer immediately!

If you look carefully at the parental alleles you will know the tricky answer immediately!

To some extent, this is a trick question and only asks that you pay careful attention to the parental alleles. But we are here to learn more than just tricks!

Suppose you didn’t see the trick. You could instead work out how to model this with a Bayesian network, which is really very well adapted to modeling this kind of genotype problem.

Let’s first model a generic Punnett Square, the typical representation for showing how dominant and recessive traits cross over in simple Mendelian genetics.

https://en.wikipedia.org/wiki/Punnett_square

https://en.wikipedia.org/wiki/Punnett_square

Below is a (small) typical generic Punnett square where B is the dominant allele and b is the recessive allele. The child is equally likely to inherit B or b from each parent, generating this genotype pattern. This is a micro-Punnett square:

Child genotype has 25% of being BB, 50% of being Bb, and 25% of being bb. Allele B is dominant in 75% of cases.

Child genotype has 25% of being BB, 50% of being Bb, and 25% of being bb. Allele B is dominant in 75% of cases.

Once the genotype is in place, the revealed traits (the phenotype) become manifest.

Let’s do this more dynamically with a Bayesian network. Let’s start with a generic network with two parent nodes and a child node with their possible alleles as states.

The generic network with uniform probabilities across the board

The generic network with uniform probabilities across the board

This is the child node table to fill in to determine the probabilities of the child inheriting various possible genotypes:

We could fill the relevant % in the table manually

We could fill the relevant % in the table manually

But you can also just enter a raw count as unnormalized and let Netica figure out the %. You can get the count by constructing a micro-punnett square (as above) for each line. The total must equal 4 (there are 4 squares), and this will be normalized and converted to % by Netica.

We derive the count this way: for example:

The count must always sum to 4

The count must always sum to 4

Let’s watch how this works in action:

The manual entry of the child’s possible genotype given the parent’s genotype.

The manual entry of the child’s possible genotype given the parent’s genotype.

This was tedious to do manually!

Netica normalizes and converts to %:

After normalization and converted to %

After normalization and converted to %

Once the table is filled in, we have this updated network. We will update the phenotype as well, where A is dominant, so AA and Aa yield A for the phenotype.

The updated child genotype and phenotype

The updated child genotype and phenotype

But we want to generalize this process and write an equation for this task. I’ve become very fond of the select function in Netica to speed things up, so let’s use it. What do we need? I asked Claude:

We can accomplish this with state numbers for AA, Aa and aa

We can accomplish this with state numbers for AA, Aa and aa

Our generic network before compiling equation to table but with state numbers 1, 0.5 and 0

Our generic network before compiling equation to table but with state numbers 1, 0.5 and 0

It’s crucial to understand that these state numbers will function as probabilities that will be used in our equations:

This is the clue showing us how to build our CPT table

This is the clue showing us how to build our CPT table

And now for the moment of truth: We accomplish this calculation with this equation. The select0 function acts like a “for” loop over the index numbers 0, 1, 2, but crucially uses the state numbers as probabilities in our formula above:

P (Child_genotype | Mother_genotype, Father_genotype) = 

select0 (Child_genotype, 

        Mother_genotype * Father_genotype,                // p1 * p2
        Mother_genotype * (1 - Father_genotype) +         // p1 (1 - p2) + 
        (1 - Mother_genotype) * Father_genotype ,         // (1 - p1) p2
         ( 1 - Mother_genotype) * (1 - Father_genotype) ) // (1 - p1)(1 - p2) 

Once we compile the equation into a table, we get this updated table:

This is identical to our manually entered table

This is identical to our manually entered table

And we get this updated network:

This reproduces the result we did manually above

This reproduces the result we did manually above

Notice that we left the priors for the parental genotypes as uniform distributions. But we don’t need to. We can change them to standard values:

we have updated the parental priors for their phenotype but it makes no difference!

we have updated the parental priors for their phenotype but it makes no difference!

We are now ready to tackle our original problem, which we started with. The network structure is the same as above, except that we have four genotypes to worry about, one for each flower trait. (I have specially arranged the nodes!) The outer layer are the parent nodes and the inner layer (in teal) are the child nodes:

The network of parent node and child node for the flower puzzle

The network of parent node and child node for the flower puzzle

We don’t need to rehearse the equations needed since they are the same style as discussed above, but here they are anyway (four equations):

P(Color3 | Color1, Color2) =

   select0(Color3,
      Color1 * Color2,
      Color1 * (1 - Color2) + (1 - Color1) * Color2,
      (1 - Color1) * (1 - Color2)
   )

P(Fragrance3 | Fragrance1, Fragrance2) =

   select0(Fragrance3,
      Fragrance1 * Fragrance2,
      Fragrance1 * (1 - Fragrance2) + (1 - Fragrance1) * Fragrance2,
      (1 - Fragrance1) * (1 - Fragrance2)
   )

P (Petal3 | Petal1, Petal2) = 

select0 (Petal3, 

       Petal1 * Petal2 , 
       Petal1 * (1 - Petal2) + 
       (1 - Petal1) * Petal2 , 
       ( 1 - Petal1 ) * (1 - Petal2) )  

P(Stem3 | Stem1, Stem2) =

   select0(Stem3,
      Stem1 * Stem2,
      Stem1 * (1 - Stem2) + (1 - Stem1) * Stem2,
      (1 - Stem1) * (1 - Stem2)
   )

The equation needed for “no dominant” traits is simple. There will be no dominant traits if ALL the child node genotypes only have recessive alleles, pp, cc, ff, and ss.

No Dominant trait if and only ALL alleles are recessive

No Dominant trait if and only ALL alleles are recessive

Once compiled, we have this updated network:

At 0.39% there is very little chance indeed. But we are not done!

At 0.39% there is very little chance indeed. But we are not done!

Recall that we were given the Alleles for the parent genotypes: One has alleles Pp Cc FF ss, and the other has alleles Pp cc Ff Ss. So we need to enter that as observations in our network: Watch what happens and see exactly where the no_dominant node goes to zero:

Watch carefully for when no_dominant goes to zero

Watch carefully for when no_dominant goes to zero

If you missed it, the blue node went to zero with the Fragrance1 node, which has alleles FF and cannot produce anything but a dominant trait!

The no_dominant trait goes to zero probability because of Fragrance1 node

The no_dominant trait goes to zero probability because of Fragrance1 node

Are not these brilliant flowers beautiful!

Are not these brilliant flowers beautiful!

SOURCES & REFERENCES

Brilliantiums Are Lovely Flowers | Brilliant

https://en.wikipedia.org/wiki/Punnett_square


메타데이터
post_id
b92ccd17a366
slug
punnett-squares-flowers-and-bayesian-networks-b92ccd17a366
url
https://medium.com/@pbercker/punnett-squares-flowers-and-bayesian-networks-b92ccd17a366
canonical_url
https://medium.com/@pbercker/punnett-squares-flowers-and-bayesian-networks-b92ccd17a366
author_url
https://medium.com/@pbercker
status
ok
fetched_at
2026-06-09 15:37:30