BPMN Mining
VI EN
Log in Sign up free
Docs / Formulas

Loops — Markov chains

Solving nᵀ(I − P) = e₀ᵀ instead of cutting the loop.

This is the core part where the tool differs from most spreadsheets: loops are solved exactly with linear algebra, not by trying a few turns and stopping.

The idea

Treat the process as an absorbing Markov chain: each step is a state, each flow is a transition probability, and the end points are absorbing states. The question “how many times on average does step v run in one pass of a case” is exactly the classic question about the expected number of visits.

The formula

nv=e0(v)+∑u ∈ Vnu·P(u→v)
(5)

Written compactly in matrix form:

nT(I−P)=e0T
(5′)

Read out in words: “the number of visits to step v equals 1 if v is the start point, plus the total number of times the other steps transition into v”. This is a system of linear equations — solve it once and you have them all, and the solution already includes the infinite number of loop turns.

The case of a single rework loop

For a simple loop, system (5) reduces to the geometric series formula:

E[k]=11−p
(5″)

A hand-calculated example

🧮 Document reconciliation with 22% mismatches

The step Reconcile (35 minutes) → gateway Match? → 22% goes to Handle the mismatch (90 minutes) and back to reconciliation; 78% carries on to Payment.

Let nreconcile be the number of runs of the reconciliation step:

nrec=1+0,22·nrec   ⇒   nrec=10,78=1,2821

The mismatch-handling step runs less often, exactly as often as cases are sent back:

nfix=0,22·1,2821=0,2821

The time this cluster contributes:

35·1,2821+90·0,2821=44,87+25,38=70,25 minutes

For comparison: ignore the rework and you count only 35 minutes. Naively “add 22%” and you get 42,7 minutes. The correct number is 70,25 minutes — double the rough estimate.

How the tool solves this

How the expected number of runs is solved
def expected_visits(node_ids, transitions, start):
    # Dựng (I - P^T), vế phải là e_0
    matrix = [[1.0 if r == c else 0.0 for c in range(size)] for r in range(size)]
    for source, targets in transitions.items():
        for target, probability in targets.items():
            matrix[index[target]][index[source]] -= probability

    vector = [0.0] * size
    vector[index[start]] = 1.0

    return solve(matrix, vector)      # khử Gauss có chọn trục
⛔
When the system has no solution
If there is a loop in which every step has no escape branch, the matrix is singular — mathematically, the expected time is infinite. The tool raises a clear error instead of returning a wrong finite number. Note: a loop-back flow with probability 100% is perfectly normal, as long as somewhere in the loop there is a branch that escapes.
Anything unclear or missing?