Importance measures

library(dist.structure)
library(algebraic.dist)

Four measures, four questions

Importance measures quantify how much a component matters to system reliability. Different definitions answer different questions. dist.structure provides four classical measures:

Measure Question
Structural How often is j pivotal across all states of the other components?
Birnbaum (reliability) At component reliabilities p, how much does dR/dp_j change R?
Criticality Given the system failed by t, what fraction attributable to j failing and being critical?
Vesely-Fussell Given the system failed by t, what is the probability that some cut set containing j is fully failed?

Each reduces to a closed form in simple topologies but diverges on complex ones. The bridge network is a canonical case where all four matter, so we’ll use it throughout.

Setting up the bridge

sys <- bridge_dist(replicate(5, exponential(1), simplify = FALSE))
min_paths(sys)
#> [[1]]
#> [1] 1 4
#> 
#> [[2]]
#> [1] 2 5
#> 
#> [[3]]
#> [1] 1 3 5
#> 
#> [[4]]
#> [1] 2 3 4
min_cuts(sys)
#> [[1]]
#> [1] 1 2
#> 
#> [[2]]
#> [1] 1 3 5
#> 
#> [[3]]
#> [1] 2 3 4
#> 
#> [[4]]
#> [1] 4 5

Components 1 and 2 appear in two minimal paths each; components 4 and 5 likewise. Component 3 (the cross-link) appears in two paths but not the “primary” ones {1,4} and {2,5}.

Structural importance

Structural importance is purely topological: it ignores component distributions.

sapply(1:5, function(j) structural_importance(sys, j))
#> [1] 0.375 0.375 0.125 0.375 0.375

For the bridge, components 1, 2, 4, 5 are structurally equivalent; component 3 is less structurally important (smaller fraction of pivotal states).

Birnbaum reliability importance

Birnbaum importance is dR/dp_j at given component reliabilities p:

p <- 0.9
sapply(1:5, function(j) birnbaum_importance(sys, j, p))
#> [1] 0.1062 0.1062 0.0162 0.1062 0.1062

At iid p = 0.9, the ordering agrees with structural importance (same symmetry). Where they diverge is at non-iid p or time-varying p.

Time-dependent importance via criticality

Criticality importance turns Birnbaum into a time-varying quantity by plugging in p_j(t) = S_j(t):

t_vals <- c(0.1, 0.5, 1, 2)
sapply(t_vals, function(t) {
  sapply(1:5, function(j) criticality_importance(sys, j, t))
})
#>            [,1]      [,2]       [,3]      [,4]
#> [1,] 0.49407384 0.4197486 0.30424486 0.1300665
#> [2,] 0.49407384 0.4197486 0.30424486 0.1300665
#> [3,] 0.07258585 0.1356168 0.09658171 0.0246675
#> [4,] 0.49407384 0.4197486 0.30424486 0.1300665
#> [5,] 0.49407384 0.4197486 0.30424486 0.1300665

Each column is a time point; each row is a component. Read it as: “at time t, what fraction of system-failure probability is attributable to component j having failed AND being critical”.

At small t (high reliability), the breakdown looks like structural importance (because all components have similar F_j(t)). At larger t, the contributions of each component to system failure diverge.

Vesely-Fussell importance

Vesely-Fussell uses minimal cut sets instead of direct pivotality:

t0 <- 1
sapply(1:5, function(j) vesely_fussell_importance(sys, j, t0))
#> [1] 0.6957551 0.6957551 0.5710693 0.6957551 0.6957551

Component j’s Vesely-Fussell importance at time t is the conditional probability that some minimal cut set containing j is fully failed, given that the system has failed by t. It tends to be larger than criticality importance for components that appear in small cuts.

Comparison

# Build a comparison table at p = 0.9 and t s.t. S(t) = 0.9 for all components.
# For iid Exp(1), S(t) = 0.9 -> t = -log(0.9)
t_star <- -log(0.9)

tab <- data.frame(
  j = 1:5,
  structural = sapply(1:5, function(j) structural_importance(sys, j)),
  birnbaum = sapply(1:5, function(j) birnbaum_importance(sys, j, 0.9)),
  criticality = sapply(1:5, function(j) criticality_importance(sys, j, t_star)),
  vesely_fussell = sapply(1:5, function(j) vesely_fussell_importance(sys, j, t_star))
)
tab
#>   j structural birnbaum criticality vesely_fussell
#> 1 1      0.375   0.1062  0.49349442     0.50650558
#> 2 2      0.375   0.1062  0.49349442     0.50650558
#> 3 3      0.125   0.0162  0.07527881     0.09247212
#> 4 4      0.375   0.1062  0.49349442     0.50650558
#> 5 5      0.375   0.1062  0.49349442     0.50650558

For the bridge at iid p = 0.9 (equivalent to t = t_star), all four measures agree on the ordering (components 1, 2, 4, 5 identical; component 3 different). Under heterogeneous reliabilities the measures can rank components differently.

Closed-form checks

Some importance values have simple closed forms worth remembering:

# Series: Birnbaum importance of j equals product of the OTHER p's.
series3 <- series_dist(replicate(3, exponential(1), simplify = FALSE))
p_vec <- c(0.9, 0.8, 0.7)
birnbaum_importance(series3, j = 1, p = p_vec)
#> [1] 0.56
prod(p_vec[-1])
#> [1] 0.56
# Parallel: Birnbaum importance of j equals product of the OTHER (1 - p_i).
parallel3 <- parallel_dist(replicate(3, exponential(1), simplify = FALSE))
birnbaum_importance(parallel3, j = 1, p = p_vec)
#> [1] 0.06
prod(1 - p_vec[-1])
#> [1] 0.06
# Series: Vesely-Fussell equals F_j / F_sys at time t, since each
# component forms its own min cut.
t0 <- 1
F_j_1 <- 1 - exp(-t0)
F_sys <- 1 - exp(-3 * t0)   # Exp(sum(rates) = 3)
vesely_fussell_importance(series3, j = 1, t = t0)
#> [1] 0.665241
F_j_1 / F_sys
#> [1] 0.665241

When to use which

All four are computed from the same primitives (phi, min_cuts, the component survivals and failures) and the differences are in which event you condition on and which counting you do.