*This note refers to strict intransitivity and almost-intransivity in decision theory, game theory, logic, and social choice theory. For almost-intransivity in nonlinear systems applied to climatology, see [[almost-intransivity]].*
>[!abstract]
>Intransitivity refers to a breakdown of the usual [[transitivity|transitive]] property of preference or relation ordering, such that if A is preferred to B and B is preferred to C, it does not follow that A is preferred to C.
>
>In **strict intransitivity**, these seemingly-paradoxical relations form a deterministic closed cycle (e.g., $A > B$, $B > C$, yet $C > A$), as seen in games like rock–paper–scissors. This challenges assumptions of rational choice theory and linear ranking systems, showing that preferences can be cyclical rather than hierarchical. Intransitivity is significant in decision theory, social choice, and game theory because it exposes how collective or contextual comparisons can undermine the notion of stable, global orderings.
>
>In **almost-intransitivity**, this cycle does not hold universally but emerges statistically: given enough iterations of the dynamics, we observe cyclic dominance or non-hierarchical relations with overwhelming frequency, even though exceptions exist. This happens in situations in decision theory and probability where preferences or comparisons between options are nearly, but not fully, intransitive—meaning that while A is preferred to B and B to C, C is not strictly preferred to A, yet the cycle is weak or probabilistic rather than absolute. This phenomenon arises in contexts such as competitive games, voting systems, and probabilistic choice, where small margins or uncertainty create preference loops. Almost-intransivity highlights the instability of ranking systems under uncertainty and the challenges of modeling rational choice when preferences approach intransitivity without fully violating transitive order.
>[!note]
> Closed cycles such that $A > B$, $B > C$, yet $C > A$ remind me of M. C. Escher's 1960 *Ascending and Descending* lithography — in both cases a seemingly-paradoxical loop appears, but the paradox itself is only illusory and disappears once the mechanism is understood.
>
>![[intransitivity.jpg]]
## Demonstrating almost-intransitivity in R
In this example, I will explore the concept of almost-intransitivity using non-standard dice. Almost-intransitivity occurs when we have three options (in this case, dice) such that option A *tends to* beat option B, option B *tends to* beat option C, but option C *tends to* beat option A. "Tends to” here comes from the probabilities of winning in pairwise comparisons between the dice (e.g., dice A beats dice B most but not all of the time). This is unlike the game of rock-paper-scissors, which is perfectly intransitive with no probabilistic/statistical emergence (e.g., rock always beats scissors).
Assume three six-sided dice $A, B, C$ with non-standard numbering of the dice as follows:
``` r
A <- c(3, 3, 3, 3, 3, 6)
B <- c(2, 2, 2, 5, 5, 5)
C <- c(1, 4, 4, 4, 4, 4)
```
Let's define and run a function that generates a $6 \times 6$ matrix comparing the outcomes of any two dice:
``` r
outcome_matrix <- function(d1, d2) {
D <- outer(d1, d2, "-") # Pairwise differences
M <- (D > 0) - (D < 0) # Maps to 1 for win, 0 for tie, -1 for loss
dimnames(M) <- list(d1, d2) # Set row & column names to dice values
M
}
# Generate all outcomes
M_AB <- outcome_matrix(A, B) # A vs B
M_BC <- outcome_matrix(B, C) # B vs C
M_CA <- outcome_matrix(C, A) # C vs A
```
Let's now look at those three matrices, which reveal in which combinations of outcomes die A beats die B ($P(A>B)$), die B beats die C ($P(B>C)$), and die C beats die A ($P(C>A)$). The winning probabilities (where the value of the first die in rows is greater than the value of the second die in columns) appear as 1s in the matrices.
``` r
# Convert matrices to data frame for nice Markdown rendering
as_table <- function(M, row_values, col_values) {
df <- as.data.frame(M) # Convert to dataframe
names(df) <- as.character(col_values) # Set column names
rownames(df) <- NULL # Remove row names
df <- cbind(Die = as.character(row_values), df) # Add row names as a column
df
}
# Render die A vs die B
knitr::kable(as_table(M_AB, A, B), format = "pipe")
```
| Die | 2 | 2 | 2 | 5 | 5 | 5 |
|:----|----:|----:|----:|----:|----:|----:|
| 3 | 1 | 1 | 1 | -1 | -1 | -1 |
| 3 | 1 | 1 | 1 | -1 | -1 | -1 |
| 3 | 1 | 1 | 1 | -1 | -1 | -1 |
| 3 | 1 | 1 | 1 | -1 | -1 | -1 |
| 3 | 1 | 1 | 1 | -1 | -1 | -1 |
| 6 | 1 | 1 | 1 | 1 | 1 | 1 |
``` r
# Render die B vs die C
knitr::kable(as_table(M_BC, B, C), format = "pipe")
```
| Die | 1 | 4 | 4 | 4 | 4 | 4 |
|:----|----:|----:|----:|----:|----:|----:|
| 2 | 1 | -1 | -1 | -1 | -1 | -1 |
| 2 | 1 | -1 | -1 | -1 | -1 | -1 |
| 2 | 1 | -1 | -1 | -1 | -1 | -1 |
| 5 | 1 | 1 | 1 | 1 | 1 | 1 |
| 5 | 1 | 1 | 1 | 1 | 1 | 1 |
| 5 | 1 | 1 | 1 | 1 | 1 | 1 |
``` r
# Render die C vs die A
knitr::kable(as_table(M_CA, C, A), format = "pipe")
```
| Die | 3 | 3 | 3 | 3 | 3 | 6 |
|:----|----:|----:|----:|----:|----:|----:|
| 1 | -1 | -1 | -1 | -1 | -1 | -1 |
| 4 | 1 | 1 | 1 | 1 | 1 | -1 |
| 4 | 1 | 1 | 1 | 1 | 1 | -1 |
| 4 | 1 | 1 | 1 | 1 | 1 | -1 |
| 4 | 1 | 1 | 1 | 1 | 1 | -1 |
| 4 | 1 | 1 | 1 | 1 | 1 | -1 |
Lastly, let's define and run a function that returns the win probabilities for each dice pair:
``` r
prob <- function(mat) {
wins <- sum(mat == 1)
ties <- sum(mat == 0)
total <- length(mat)
list(
wins = wins,
total = total,
win_prob = wins / total,
tie_prob = ties / total
)
}
# Calculate and print win probabilities
pAB <- prob(M_AB); cat("P(A > B) =", pAB$wins, "/", pAB$total, "=", pAB$win_prob, "\n")
```
P(A > B) = 21 / 36 = 0.5833333
``` r
pBC <- prob(M_BC); cat("P(B > C) =", pBC$wins, "/", pBC$total, "=", pBC$win_prob, "\n")
```
P(B > C) = 21 / 36 = 0.5833333
``` r
pCA <- prob(M_CA); cat("P(C > A) =", pCA$wins, "/", pCA$total, "=", pCA$win_prob, "\n")
```
P(C > A) = 25 / 36 = 0.6944444
We see that die A beats die B with a probability of ~56%, die B beats die C with a probability of ~53%, and die C beats die A with a probability of ~53%. This is an example of almost-transitivity, and the seemingly-paradoxical loop that it creates.
If you played this game of dice against a friend, you could always choose the die that is most likely to beat your friend's choice. If your friend chooses die A, you should choose die C; if they choose die B, you should choose die A; and if they choose die C, you should choose die B. This strategy would give you a statistical edge in the game.
Now, let's assume your opponent picks up on this strategy and decides to let you choose a die first, so that they can pick up a winning die after you. You agree but offer them to roll the dice twice, sum the results, and then compare the sums.
So, let's build a function that generates a $36 \times 36$ matrix comparing the outcomes of any two dice being rolled twice:
``` r
two_roll_sums <- function(d) as.vector(outer(d, d, "+")) # All 36 sums (with multiplicity)
outcome_matrix_twice <- function(d1, d2) {
s1 <- two_roll_sums(d1)
s2 <- two_roll_sums(d2)
D <- outer(s1, s2, "-")
M <- (D > 0) - (D < 0)
dimnames(M) <- list(s1, s2)
M
}
# Generate all outcomes
M_AB2 <- outcome_matrix_twice(A, B)
M_BC2 <- outcome_matrix_twice(B, C)
M_CA2 <- outcome_matrix_twice(C, A)
```
Let's display the resulting win probabilities:
``` r
pAB2 <- prob(M_AB2); cat("P(A > B) =", pAB2$wins, "/", pAB2$total, "=", pAB2$win_prob, "\n")
```
P(A > B) = 531 / 1296 = 0.4097222
``` r
pBC2 <- prob(M_BC2); cat("P(B > C) =", pBC2$wins, "/", pBC2$total, "=", pBC2$win_prob, "\n")
```
P(B > C) = 531 / 1296 = 0.4097222
``` r
pCA2 <- prob(M_CA2); cat("P(C > A) =", pCA2$wins, "/", pCA2$total, "=", pCA2$win_prob, "\n")
```
P(C > A) = 625 / 1296 = 0.4822531
We see that die A now loses to die B ~59% of the time, die B loses to die C ~59% of the time, and die C loses to die A ~52% of the time. Fascinatingly, rolling the dice twice has reversed the direction of the almost-intransitive loop!
>[!related]
>- **North** (upstream): [[Social choice theory]]
>- **West** (similar): [[Condorcet's paradox]] (collective preferences can be cyclic even if individual ones are transitive)
>- **East** (different): [[Transitivity]] (classical rational choice axiom: if A > B and B > C, then A > C)
>- **South** (downstream): [[Preference cycles]] (situations where group or individual preferences loop without a stable ordering)