12.4 Decisions and games in software
Software 12.4.1 (Decision criteria). The criteria of the subsection on decisions under uncertainty, and the EMV, applied to Example 12.1.1, with the action each selects; then the EVPI:
>>> import numpy as np
>>> from scipy.optimize import linprog
>>> acts = ['large', 'medium', 'small']
>>> P = np.array([[200, 50, -120], # payoff (Rs. lakh) by demand:
... [120, 80, -30], # high, medium, low
... [60, 40, 20]])
>>> prob = np.array([0.3, 0.5, 0.2])
>>> regret = P.max(axis=0) - P
>>> crit = {'maximin': P.min(axis=1), 'maximax': P.max(axis=1),
... 'Hurwicz 0.6': 0.6 * P.max(axis=1) + 0.4 * P.min(axis=1),
... 'Laplace': P.mean(axis=1), 'minimax regret': -regret.max(axis=1),
... 'EMV': P @ prob}
>>> for name, score in crit.items():
... print(f"{name:15s}", np.round(score, 2), acts[int(np.argmax(score))])
...
maximin [-120 -30 20] small
maximax [200 120 60] large
Hurwicz 0.6 [72. 60. 44.] large
Laplace [43.33 56.67 40. ] medium
minimax regret [-140 -80 -140] medium
EMV [61. 70. 42.] medium
>>> evpi = prob @ P.max(axis=0) - (P @ prob).max(); evpi
34.0
Reading the output. Maximin chooses the small plant, maximax and Hurwicz (\(\alpha = 0.6\)) the large, Laplace, minimax regret (printed with a minus sign, so that the largest is best) and EMV the medium. The EVPI is \(34\).
MATLAB/Octave: min(P, [], 2), max(P, [], 2) and P*prob’ give the same columns.
Software 12.4.2 (The value of a survey). Example 12.2.1: the probability of a favourable report, the posterior probabilities after each report, the best action and its expected payoff after each, and the expected payoff with the survey, the EVSI and the efficiency:
>>> like = np.array([0.8, 0.5, 0.1]) # P(favourable survey | demand)
>>> pf = prob @ like # P(favourable)
>>> post_f = prob * like / pf; post_u = prob * (1 - like) / (1 - pf)
>>> round(pf, 3), np.round(post_f, 4), np.round(post_u, 4)
(0.51, array([0.4706, 0.4902, 0.0392]), array([0.1224, 0.5102, 0.3673]))
>>> best_f, best_u = (P @ post_f).max(), (P @ post_u).max()
>>> choose = lambda post: acts[int(np.argmax(P @ post))]
>>> (choose(post_f), round(best_f, 2)), (choose(post_u), round(best_u, 2))
(('large', 113.92), ('medium', 44.49))
>>> with_survey = pf * best_f + (1 - pf) * best_u
>>> evsi = with_survey - (P @ prob).max()
>>> round(with_survey, 2), round(evsi, 2), round(evsi / evpi, 3) # efficiency
(79.9, 9.9, 0.291)
Reading the output. A favourable report (probability \(0.51\)) makes high demand much more likely (\(0.47\)) and leads to the large plant, worth \(113.9\); an unfavourable one leads to the medium plant, worth \(44.5\). With the survey the expected payoff is \(79.9\); the EVSI is \(9.9\), \(29\%\) of the EVPI.
MATLAB/Octave: the same vector arithmetic, prob.*like/(prob*like’).
Software 12.4.3 (Games by linear programming). A function that solves any zero-sum game by the two LPs of the proof of Theorem 12.3.1 (after adding a constant to make all entries positive, so that the value is positive and the variables \(y = p/v\) can be used); a check for a saddle point; and three games:
>>> def solve_game(A): # value and optimal mixed strategies ... A = np.asarray(A, float); m, n = A.shape ... k = 1 - A.min(); B = A + k # shift so that every entry is > 0 ... # row player: minimise sum y with B^T y >= 1; then p = y / sum y ... r = linprog(np.ones(m), A_ub=-B.T, b_ub=-np.ones(n), method='highs') ... p = r.x / r.x.sum(); v = 1 / r.x.sum() - k ... s = linprog(-np.ones(n), A_ub=B, b_ub=np.ones(m), method='highs') ... q = s.x / s.x.sum() ... return round(v, 6), np.round(p, 4), np.round(q, 4) ... >>> A1 = [[4, 2, 3], [5, 3, 4], [1, 0, 6]] # has a saddle point >>> np.max(np.min(A1, axis=1)), np.min(np.max(A1, axis=0)) (3, 3) >>> solve_game([[3, -1], [-2, 4]]) # 2 x 2 without a saddle point (1.0, array([0.6, 0.4]), array([0.5, 0.5])) >>> solve_game([[0, -1, 1], [1, 0, -1], [-1, 1, 0]]) # rock, paper, scissors (0.0, array([0.3333, 0.3333, 0.3333]), array([0.3333, 0.3333, 0.3333])) >>> solve_game([[2, -1, 3], [-1, 3, -2], [1, 0, 1]]) (0.714286, array([0.5714, 0.4286, 0. ]), array([0.5714, 0.4286, 0. ]))
Reading the output. The first matrix has maximin \(=\) minimax \(= 3\), a saddle point. The \(2 \times 2\) game has value \(1\) with \(p = (0.6, 0.4)\) and \(q = (0.5, 0.5)\), as the formula gives. Rock–paper–scissors has value \(0\) and the uniform strategies. The last game has value \(0.714 = \frac 57\), both players mixing their first two strategies in the ratio \(4 : 3\).
MATLAB/Octave: the same two linprog calls.
Questions on this section
Stuck on something here? Ask below and it stays attached to this topic.