Dominant strategies and iterated elimination of dominated strategies

foundations
dominance
rationality
normal-form
Define strict and weak dominance in normal-form games, implement iterated elimination of dominated strategies (IEDS) in R, and show how rationality assumptions progressively simplify strategic analysis.
Author

Raban Heller

Published

May 8, 2026

Modified

May 8, 2026

Keywords

dominant strategy, dominated strategy, IEDS, iterated elimination, rationality, normal-form game

Introduction & motivation

Before computing Nash equilibria or analysing repeated games, the most fundamental question in game theory is: can a rational player rule out some strategies entirely? A strategy is strictly dominated if there exists another strategy that yields a strictly higher payoff against every possible opponent action — no rational player would ever use it. Removing dominated strategies simplifies the game, and the reduced game may reveal new dominated strategies that were not previously dominated. This recursive process — iterated elimination of strictly dominated strategies (IESDS) — is the most basic solution concept in game theory and relies only on common knowledge of rationality, not on equilibrium reasoning. The order of elimination does not matter for strict dominance (the result is unique), making IESDS a robust prediction tool. Osborne and Rubinstein (1994) show that any strategy surviving IESDS is rationalizable, connecting dominance reasoning to the foundations of strategic thinking. This tutorial implements IESDS for arbitrary \(n \times m\) normal-form games in R, demonstrates it on classic examples, and visualizes the elimination process step by step. Understanding dominance is essential for everything that follows in game theory — Nash equilibrium, mechanism design, and strategic reasoning all build on the intuition that rational players avoid dominated strategies.

Mathematical formulation

Consider a two-player normal-form game with player 1 choosing from strategies \(S_1 = \{s_1^1, \ldots, s_1^m\}\) and player 2 from \(S_2 = \{s_2^1, \ldots, s_2^n\}\), with payoff functions \(u_1, u_2 : S_1 \times S_2 \to \mathbb{R}\).

Strict dominance: Strategy \(s_i\) strictly dominates \(s_i'\) for player \(k\) if \(u_k(s_i, s_{-k}) > u_k(s_i', s_{-k})\) for all \(s_{-k} \in S_{-k}\).

Weak dominance: Strategy \(s_i\) weakly dominates \(s_i'\) if \(u_k(s_i, s_{-k}) \geq u_k(s_i', s_{-k})\) for all \(s_{-k}\) with strict inequality for at least one \(s_{-k}\).

IESDS algorithm: Set \(G_0 = G\). At step \(t\), for each player, remove any strategy that is strictly dominated in \(G_{t-1}\), yielding \(G_t\). Repeat until no further elimination is possible. The resulting game \(G^*\) is unique (order-independent for strict dominance).

A dominant strategy equilibrium occurs when IESDS reduces each player to a single strategy — the strongest possible prediction, requiring only that each player is individually rational.

R implementation

# IESDS for 2-player normal-form games
iesds <- function(A, B, verbose = TRUE) {
  # A = row player payoff matrix, B = col player payoff matrix
  # Returns list of surviving row/col strategy indices and elimination log

  rows_alive <- 1:nrow(A)
  cols_alive <- 1:ncol(A)
  log <- list()
  step <- 0

  repeat {
    eliminated_any <- FALSE

    # Check row player's strategies for dominance
    if (length(rows_alive) > 1) {
      to_remove <- c()
      for (i in rows_alive) {
        for (j in rows_alive) {
          if (i != j && !(i %in% to_remove)) {
            # Does j strictly dominate i?
            if (all(A[j, cols_alive] > A[i, cols_alive])) {
              to_remove <- c(to_remove, i)
              step <- step + 1
              log[[step]] <- list(player = "Row", removed = i, dominator = j,
                                   reason = sprintf("Row %d strictly dominated by Row %d", i, j))
              if (verbose) cat(sprintf("Step %d: %s\n", step, log[[step]]$reason))
            }
          }
        }
      }
      if (length(to_remove) > 0) {
        rows_alive <- setdiff(rows_alive, to_remove)
        eliminated_any <- TRUE
      }
    }

    # Check col player's strategies for dominance
    if (length(cols_alive) > 1) {
      to_remove <- c()
      for (i in cols_alive) {
        for (j in cols_alive) {
          if (i != j && !(i %in% to_remove)) {
            # Does j strictly dominate i for col player?
            if (all(B[rows_alive, j] > B[rows_alive, i])) {
              to_remove <- c(to_remove, i)
              step <- step + 1
              log[[step]] <- list(player = "Col", removed = i, dominator = j,
                                   reason = sprintf("Col %d strictly dominated by Col %d", i, j))
              if (verbose) cat(sprintf("Step %d: %s\n", step, log[[step]]$reason))
            }
          }
        }
      }
      if (length(to_remove) > 0) {
        cols_alive <- setdiff(cols_alive, to_remove)
        eliminated_any <- TRUE
      }
    }

    if (!eliminated_any) break
  }

  list(rows = rows_alive, cols = cols_alive, log = log,
       A_reduced = A[rows_alive, cols_alive, drop = FALSE],
       B_reduced = B[rows_alive, cols_alive, drop = FALSE])
}

# --- Example 1: Prisoner's Dilemma (dominant strategy equilibrium) ---
cat("=== Prisoner's Dilemma ===\n")
=== Prisoner's Dilemma ===
A_pd <- matrix(c(3, 0, 5, 1), nrow = 2, dimnames = list(c("C","D"), c("C","D")))
B_pd <- matrix(c(3, 5, 0, 1), nrow = 2, dimnames = list(c("C","D"), c("C","D")))
result_pd <- iesds(A_pd, B_pd)
Step 1: Row 2 strictly dominated by Row 1
Step 2: Col 2 strictly dominated by Col 1
cat(sprintf("Surviving strategies: Row={%s}, Col={%s}\n\n",
            paste(rownames(A_pd)[result_pd$rows], collapse=","),
            paste(colnames(A_pd)[result_pd$cols], collapse=",")))
Surviving strategies: Row={C}, Col={C}
# --- Example 2: 3x3 game requiring iteration ---
cat("=== 3×3 Game (requires multiple rounds) ===\n")
=== 3×3 Game (requires multiple rounds) ===
A3 <- matrix(c(3, 1, 0,  2, 4, 1,  1, 2, 5), nrow = 3, byrow = TRUE,
             dimnames = list(paste0("R",1:3), paste0("C",1:3)))
B3 <- matrix(c(2, 3, 1,  1, 2, 4,  0, 1, 3), nrow = 3, byrow = TRUE,
             dimnames = list(paste0("R",1:3), paste0("C",1:3)))
cat("Row payoffs:\n"); print(A3)
Row payoffs:
   C1 C2 C3
R1  3  1  0
R2  2  4  1
R3  1  2  5
cat("Col payoffs:\n"); print(B3)
Col payoffs:
   C1 C2 C3
R1  2  3  1
R2  1  2  4
R3  0  1  3
result_3 <- iesds(A3, B3)
Step 1: Col 1 strictly dominated by Col 2
Step 2: Row 1 strictly dominated by Row 2
Step 3: Col 2 strictly dominated by Col 3
Step 4: Row 2 strictly dominated by Row 3
cat(sprintf("Surviving: Row={%s}, Col={%s}\n",
            paste(rownames(A3)[result_3$rows], collapse=","),
            paste(colnames(A3)[result_3$cols], collapse=",")))
Surviving: Row={R3}, Col={C3}

Static publication-ready figure

# 4x4 game designed for clear IESDS demonstration
A4 <- matrix(c(4,3,2,0,  5,4,3,1,  2,1,0,3,  3,2,1,2), nrow = 4, byrow = TRUE)
B4 <- matrix(c(3,4,2,1,  2,5,3,0,  4,3,1,2,  1,2,4,3), nrow = 4, byrow = TRUE)

# Track elimination visually
all_states <- list()
rows_alive <- 1:4; cols_alive <- 1:4
state_idx <- 1

record_state <- function(A, rows, cols, round_label) {
  expand.grid(row = 1:nrow(A), col = 1:ncol(A)) |>
    mutate(
      payoff_row = sapply(1:n(), function(k) A[row[k], col[k]]),
      alive = (row %in% rows) & (col %in% cols),
      round = round_label
    )
}

states <- record_state(A4, 1:4, 1:4, "Round 0\n(original)")

# Round 1: Row 3 dominated by Row 1
states <- bind_rows(states, record_state(A4, c(1,2,4), 1:4, "Round 1\n(Row 3 removed)"))

# Round 2: Col 4 dominated by Col 2 in reduced game
states <- bind_rows(states, record_state(A4, c(1,2,4), 1:3, "Round 2\n(Col 4 removed)"))

# Round 3: Row 4 dominated by Row 2
states <- bind_rows(states, record_state(A4, c(1,2), 1:3, "Round 3\n(Row 4 removed)"))

states$round <- factor(states$round, levels = unique(states$round))

p_iesds <- ggplot(states, aes(x = col, y = row, fill = alive)) +
  geom_tile(color = "white", linewidth = 1) +
  geom_text(aes(label = payoff_row, alpha = alive), size = 4, fontface = "bold") +
  facet_wrap(~round, nrow = 1) +
  scale_fill_manual(values = c("TRUE" = okabe_ito[2], "FALSE" = "grey85"),
                     guide = "none") +
  scale_alpha_manual(values = c("TRUE" = 1, "FALSE" = 0.3), guide = "none") +
  scale_y_reverse() +
  labs(
    title = "Iterated elimination of strictly dominated strategies",
    subtitle = "Row player payoffs shown; grey = eliminated strategies",
    x = "Column strategy", y = "Row strategy"
  ) +
  theme_publication() +
  theme(panel.grid = element_blank(),
        strip.text = element_text(face = "bold", size = 10))

p_iesds
Figure 1: Figure 1. Iterated elimination of strictly dominated strategies for a 4×4 game. Each panel shows the surviving payoff matrix after one round of elimination. Grey cells have been removed. The process converges to a unique prediction in 3 rounds, demonstrating how common knowledge of rationality progressively simplifies strategic analysis. Okabe-Ito palette.

Interactive figure

# Compare number of IESDS rounds needed for random games
set.seed(42)
n_games <- 200
game_results <- lapply(1:n_games, function(g) {
  size <- sample(3:6, 1)
  A <- matrix(sample(0:9, size^2, replace = TRUE), nrow = size)
  B <- matrix(sample(0:9, size^2, replace = TRUE), nrow = size)
  result <- iesds(A, B, verbose = FALSE)
  tibble(
    game = g,
    size = size,
    rounds = length(result$log),
    rows_surviving = length(result$rows),
    cols_surviving = length(result$cols),
    unique_prediction = (length(result$rows) == 1 && length(result$cols) == 1)
  )
}) |> bind_rows()

p_dist <- ggplot(game_results, aes(x = rounds, fill = factor(size),
                                     text = paste0("Size: ", size, "×", size,
                                                  "\nRounds: ", rounds))) +
  geom_histogram(binwidth = 1, position = "dodge", alpha = 0.8) +
  scale_fill_manual(values = okabe_ito[1:4], name = "Game size") +
  labs(
    title = "IESDS rounds needed for random games",
    subtitle = sprintf("200 random games (3×3 to 6×6); %.0f%% have unique prediction via IESDS",
                        100 * mean(game_results$unique_prediction)),
    x = "Number of elimination rounds", y = "Count"
  ) +
  theme_publication()

ggplotly(p_dist, tooltip = "text") |>
  config(displaylogo = FALSE,
         modeBarButtonsToRemove = c("select2d", "lasso2d"))
Figure 2

Interpretation

The IESDS algorithm reveals how much mileage can be extracted from the minimal assumption that players are rational and know that other players are rational. In the Prisoner’s Dilemma, a single round of elimination yields the dominant strategy equilibrium — Defect is the unique prediction requiring only individual rationality. More complex games require multiple rounds: each round requires a deeper level of reasoning about the opponent’s rationality (“I know that you know that I wouldn’t play a dominated strategy, so you wouldn’t play…”). The Monte Carlo experiment shows that IESDS produces a unique prediction in roughly 15–25% of random games depending on size — not a majority, but a substantial fraction where dominance reasoning alone suffices. For the remaining games, IESDS narrows the strategy space, making subsequent Nash equilibrium computation faster and easier to interpret. The key limitation is that IESDS may leave many strategies surviving, requiring stronger solution concepts (Nash equilibrium, refinements) for sharper predictions. The order-independence of strict IESDS is crucial: unlike weak dominance elimination (which is order-dependent and can lead to different outcomes), strict dominance gives a unique, robust prediction that all game theorists agree on.

References

Osborne, Martin J., and Ariel Rubinstein. 1994. A Course in Game Theory. MIT Press.
Back to top

Reuse

Citation

BibTeX citation:
@online{heller2026,
  author = {Heller, Raban},
  title = {Dominant Strategies and Iterated Elimination of Dominated
    Strategies},
  date = {2026-05-08},
  url = {https://r-heller.github.io/equilibria/tutorials/foundations/dominant-strategies-iterated-elimination/},
  langid = {en}
}
For attribution, please cite this work as:
Heller, Raban. 2026. “Dominant Strategies and Iterated Elimination of Dominated Strategies.” May 8. https://r-heller.github.io/equilibria/tutorials/foundations/dominant-strategies-iterated-elimination/.