UNIT 07 β€’ PROBABILISTIC REASONING & DECISION MAKING

Uncertain Knowledge & Reasoning

An engineering masterclass on intelligent reasoning under real-world noise: probability axioms, Bayes' Theorem, Bayesian Networks with exact and approximate sampling inference, temporal reasoning with Hidden Markov Models (HMMs), Markov Decision Processes (MDPs) with Bellman equations, and Decision Theory with Maximum Expected Utility.

πŸ“– Standard: Russell & Norvig (AIMA 4th Edition)
⏱️ Study Depth: 6.5 Hours β€’ Theory & Python Implementation
πŸ’» Implementation: Python 3.12 (Bayesian Net Inference & GridWorld MDP)
🎯 Verification: 100% Pure Natural English Language
01

Why Uncertainty Arises in Artificial Intelligence

In pure mathematical logic, an agent deals with absolute certainties: facts are either definitively True or definitively False. However, in physical reality, intelligent systems (autonomous vehicles, medical diagnostics, robotics, financial forecasting) must act under pervasive Uncertainty.

1. Partial Observability

Sensors cannot see through walls or perceive the entire global state of the environment. The agent operates with incomplete or ambiguous sensory snapshots.

2. Sensor Noise & Wear

Real sensors (cameras, LiDAR, medical blood panels) have inherent tolerances, electromagnetic noise, and physical degradation, yielding noisy measurements.

3. Non-Deterministic Actions

Actuators are imperfect. Commanding a robot to move forward 1.0 meter might result in 0.98 meters due to wheel slippage, carpet friction, or battery voltage drops.

⚠️ The Failure of First-Order Logic: The Qualification Problem

Why can't we simply use First-Order Logic to diagnose diseases or drive cars? Consider the logical rule:

FOR-ALL patient [ Toothache(patient) → Cavity(patient) ]

This rule is false because toothaches can also be caused by gum disease, abscesses, or sinus infections. Trying to fix it by enumerating every possible exception creates the Qualification Problem:

Toothache → Cavity UNLESS GumDisease OR SinusInfection OR ImpactedWisdomTooth OR JawFracture...

The list of caveats is theoretically infinite! Even if all exceptions could be written down, testing every single one in a patient is economically and physically impossible. Probability replaces this infinite exception list with a single, calibrated summary number: P(Cavity | Toothache) = 0.80.

02

Probability Basics, Conditional Probability & Bayes' Rule

Probability provides a rigorous mathematical framework for representing an agent's degree of belief in propositions given available evidence.

πŸ“ Kolmogorov's Axioms of Probability
  • Axiom 1 (Non-negativity): For any proposition A, the probability is bounded: 0 <= P(A) <= 1.
  • Axiom 2 (Total Certainty): The probability of the entire sample space is 1: P(True) = 1, and P(False) = 0.
  • Axiom 3 (Additivity for Disjoint Events): For any two mutually exclusive events A and B:
    P(A OR B) = P(A) + P(B) - P(A AND B)
Conditional Probability & Product Rule

The probability of proposition A occurring given that evidence proposition B is already known to be True:

P(A | B) = P(A AND B) / P(B) (where P(B) > 0)
Rearranging yields the Product Rule:
P(A AND B) = P(A | B) * P(B) = P(B | A) * P(A)
Marginalization (Summing Out)

We can compute the marginal probability of variable Y by summing across all possible values of another variable Z in the joint distribution:

P(Y) = Sum over all values z of [ P(Y, Z = z) ]
Using the product rule (Law of Total Probability):
P(Y) = Sum over z of [ P(Y | Z = z) * P(Z = z) ]
πŸ† Bayes' Theorem (The Foundation of Probabilistic AI)

Equating the two forms of the Product Rule yields Bayes' Rule, which allows an agent to update its belief in an unobservable hypothesis given observed sensory evidence:

Posterior Probability P(Hypothesis | Evidence) = [ Likelihood P(Evidence | Hypothesis) * Prior P(Hypothesis) ] / Marginal Evidence P(Evidence)
  • Prior Probability P(H): The initial degree of belief in the hypothesis before seeing any new sensory data.
  • Likelihood P(E | H): The probability that the observed evidence would occur if the hypothesis were indeed True.
  • Marginal Evidence P(E): Normalization constant: P(E) = P(E | H) * P(H) + P(E | NOT H) * P(NOT H).
  • Posterior Probability P(H | E): The refined degree of belief in the hypothesis after absorbing evidence E.

Worked Real-World Example: The False Positive Paradox in Medical Screening

Suppose a rare medical condition affects 1 in 1,000 people (Prior P(Disease) = 0.001). A diagnostic test has a 99% Sensitivity (P(Positive | Disease) = 0.99) and a 95% Specificity (P(Positive | Healthy) = 0.05). If a random patient tests positive, what is the probability they actually have the disease?

1. Numerator = P(Positive | Disease) * P(Disease) = 0.99 * 0.001 = 0.00099
2. P(Positive) = (0.99 * 0.001) + (0.05 * 0.999) = 0.00099 + 0.04995 = 0.05094
3. Posterior P(Disease | Positive) = 0.00099 / 0.05094 ≈ 0.0194 (Only 1.94%!)

Key Insight: Despite the test being "99% accurate", because the disease is so rare, false positives vastly outnumber true positives! Understanding Bayes' theorem prevents catastrophic clinical and algorithmic misdiagnoses.

03

Bayesian Networks (Belief Networks & DAGs)

A full joint probability distribution over n boolean variables requires 2^n - 1 parametersβ€”an exponential explosion that quickly exhausts computational memory and statistical sample sizes. A Bayesian Network (Belief Network / Bayes Net) is a compact graphical model that exploits Conditional Independence to represent complex joint distributions with exponential parameter savings.

πŸ“ Formal Anatomy of a Bayesian Network
  • Directed Acyclic Graph (DAG): Nodes represent random variables (discrete or continuous). Directed edges represent direct probabilistic causal influences.
  • Conditional Probability Tables (CPTs): Each node Xi has an associated conditional probability distribution given its immediate parents: P(Xi | Parents(Xi)).
The Master Chain Rule of Bayesian Networks:
The full joint probability distribution is factored into the product of local conditional distributions:
P(X1, X2, ..., Xn) = Product over all i from 1 to n of [ P(Xi | Parents(Xi)) ]
The Classic Burglar Alarm Bayesian Network (Russell & Norvig)
             [ Burglary ] (B)             [ Earthquake ] (E)
             P(B) = 0.001                  P(E) = 0.002
                    \                             /
                     \                           /
                      v                         v
                           [   Alarm   ] (A)
                           CPT conditioned on B, E
                               /        \
                              /          \
                             v            v
                   [ JohnCalls ] (J)     [ MaryCalls ] (M)
                   CPT on A              CPT on A

   CPT for Alarm:
     B     E   | P(A | B, E)
   -------------------------
     T     T   |   0.95
     T     F   |   0.94
     F     T   |   0.29
     F     F   |   0.001

   Joint Probability Query: What is P(B, ~E, A, J, ~M)?
   = P(B) * P(~E) * P(A | B, ~E) * P(J | A) * P(~M | A)
   = 0.001 * 0.998 * 0.94 * 0.90 * 0.30 = 0.000062
1. Linear Chain (Causal)

A → B → C
If B is unobserved, A and C are dependent. But if B is observed, A and C become conditionally independent! B blocks the path.

2. Common Cause (Fork)

A ← B → C
A and C share common cause B. If B is unobserved, A and C are correlated. Once B is observed, A and C become conditionally independent.

3. Common Effect (Collider / V)

A → B ← C
If B is unobserved, A and C are completely independent! But if B (or any child of B) is observed, A and C become dependent! (Explaining Away effect).

04

Inference in Bayesian Networks: Exact & Approximate

Inference is the task of computing the posterior probability distribution for a set of query variables X given observed evidence variables E = e: P(X | E = e).

1. Exact Inference (Variable Elimination)

Computes the exact posterior probability distribution by summing out hidden (unobserved) variables from the joint distribution.

  • Enumeration: Recursively loops through all possible variable combinations. Inefficient due to repeated re-computations: O(2^n).
  • Variable Elimination: Dynamic programming optimization that factors out sub-expressions and caches intermediate factor tables. Complexity is exponential only in the tree width of the network graph.

Complexity Note: Exact inference in arbitrary multiply-connected Bayesian networks is provably NP-hard.

2. Approximate Inference (Monte Carlo Sampling)

When exact inference is intractable in massive networks, AI engines generate stochastic samples to approximate true probabilities:

  • Prior Sampling: Samples variables in topological order according to prior CPTs.
  • Rejection Sampling: Rejects (discards) any generated sample that does not match the observed evidence E = e. (Inefficient if evidence is rare).
  • Likelihood Weighting: Never discards samples! Forces evidence variables to match observations and weights each sample by the likelihood of the evidence: Weight = Product over evidence of [ P(evidence | parents) ].
  • Markov Chain Monte Carlo (MCMC / Gibbs Sampling): Generates a sequence of samples by randomly updating one non-evidence variable at a time conditioned on its Markov Blanket.
05

Markov Models & Hidden Markov Models (HMMs)

When reasoning over temporal sequences (speech recognition, stock prices, patient vitals over time, robot localization), the state of the world evolves dynamically across discrete time steps: t = 0, 1, 2, ....

⏱️ The First-Order Markov Assumption

The Markov Property assumes that the future state depends strictly on the current state, and is conditionally independent of all past historical states:

P(X_t+1 | X_t, X_t-1, ..., X_0) = P(X_t+1 | X_t)

The state transition probabilities P(X_t+1 | X_t) are represented by a square Transition Matrix. If transitions do not change over time, the system is stationary.

πŸ‘οΈ Hidden Markov Models (HMMs)

In an HMM, the true physical state of the world X_t is hidden (unobservable). The agent only perceives noisy sensory evidence E_t emitted by the hidden state:

  • Transition Model: P(X_t | X_t-1) β€” How the hidden state evolves over time.
  • Sensor / Emission Model: P(E_t | X_t) β€” How the noisy evidence depends on the current hidden state.

The 3 Fundamental HMM Algorithmic Tasks:

HMM Task Formal Probability Query Standard Algorithm Primary Industry Use Case
1. Filtering (Monitoring) P(X_t | e_1:t) β€” Estimate current state given all observations up to now. Forward Algorithm (computes recursive alpha passes in O(t) time). Robot online localization, missile tracking, patient vitals monitoring.
2. Smoothing (Hindsight) P(X_k | e_1:t) where k < t β€” Better estimate past state using future evidence. Forward-Backward Algorithm (combines past evidence and future evidence). Post-game analysis, historical financial auditing, forensic track reconstruction.
3. Most Likely Explanation argmax over x_1:t of [ P(x_1:t | e_1:t) ] β€” Find the single best sequence of hidden states. Viterbi Algorithm (dynamic programming keeping max paths). Speech-to-text recognition, DNA sequence alignment, automated translation.
06

Markov Decision Processes (MDPs) & Sequential Decisions

While Markov models observe passive processes, an agent in a Markov Decision Process (MDP) actively selects actions to influence future states and maximize cumulative numerical rewards.

πŸ“ Formal 5-Tuple Definition: MDP = (S, A, T, R, γ)
  • States S: The set of all possible environmental configurations.
  • Actions A: The set of actions available to the agent.
  • Transition Model T(s, a, s'): The probability of reaching state s' when taking action a in state s: P(s' | s, a).
  • Reward Function R(s, a, s'): The immediate numeric reward received after transitioning from s to s' via action a.
  • Discount Factor γ (gamma): A real number between 0 and 1 (0 <= γ < 1) that weights immediate rewards higher than distant future rewards. (Guarantees that infinite-horizon cumulative sums converge to finite numbers!).
Cumulative Discounted Return:
Return G = R_0 + γ * R_1 + γ^2 * R_2 + γ^3 * R_3 + ... = Sum over t of [ γ^t * R_t ]
βš–οΈ The Bellman Equation & Bellman Optimality

A Policy π(s) specifies what action the agent should take in each state s. The Optimal Value V*(s) is the maximum expected discounted return starting from state s under the optimal policy:

The Bellman Optimality Equation:
V*(s) = Maximum over all actions a of [ Sum over s' of [ P(s' | s, a) * ( R(s, a, s') + γ * V*(s') ) ] ]

Intuition: The value of state s is the expected immediate reward plus the discounted expected value of the resulting next state, choosing the action that maximizes this sum!

The Value Iteration Algorithm:

  1. Initialize V_0(s) = 0 for all states s.
  2. Repeatedly update each state value simultaneously using the Bellman update:
    V_k+1(s) ← max over a [ Sum over s' [ P(s' | s, a) * ( R(s, a, s') + γ * V_k(s') ) ] ]
  3. Stop when the maximum change between iterations is tiny: max |V_k+1(s) - V_k(s)| < epsilon * (1 - γ) / γ.
  4. Extract the optimal policy: π*(s) = argmax over a [ Sum over s' [ P(s' | s, a) * V*(s') ] ].
07

Decision Theory, Utility Theory & Expected Utility

Decision Theory unifies Probability Theory with Utility Theory to define what it means for an agent to act rationally when outcomes are uncertain:

Decision Theory = Probability Theory (Beliefs) + Utility Theory (Desires)
🎯 The Maximum Expected Utility (MEU) Principle

An agent is rational if and only if it chooses the action that yields the highest Expected Utility (EU) averaged across all possible resulting states:

Expected Utility: EU(Action a | Evidence e) = Sum over outcomes s' [ P(s' | Action a, Evidence e) * Utility U(s') ]
Optimal Action a* = argmax over a [ EU(Action a | Evidence e) ]
1. Risk-Averse (Concave)

Prefers a guaranteed payoff over a risky gamble with the same expected monetary value.
Utility curve is concave (e.g., U(w) = ln(w)).
Explains insurance and conservative portfolios.

2. Risk-Neutral (Linear)

Completely indifferent between a guaranteed payoff and a gamble with equal expected value.
Utility curve is a straight line: U(w) = k * w.
Standard assumption for corporations evaluating small investments.

3. Risk-Seeking (Convex)

Prefers a gamble with high variance over a certain payoff with equal expected value.
Utility curve is convex: U(w) = w^2.
Explains lottery ticket purchases and high-stakes venture bets.

08

Complete Python Implementations: Bayes Net & MDP Solver

Below is a complete, executable Python script demonstrating: 1. Exact Inference by Enumeration on the Burglar Alarm Bayesian Network. 2. A Value Iteration Solver computing the optimal policy for a 2D stochastic GridWorld MDP.

probabilistic_ai_engine.py β€” Bayes Net & GridWorld MDP Engine
"""
AI Track Unit 7: Probabilistic Reasoning & Decision Making
1. Bayesian Network Exact Inference by Enumeration
2. Markov Decision Process (MDP) Value Iteration Solver
Author: DevAscent Engineering Team
"""

from typing import Dict, List, Tuple
import itertools

# =====================================================================
# 1. BAYESIAN NETWORK INFERENCE BY ENUMERATION
# =====================================================================
# Classic Burglar Alarm Network CPTs
CPT = {
    'B': {(): 0.001},
    'E': {(): 0.002},
    'A': {
        (True, True): 0.95,
        (True, False): 0.94,
        (False, True): 0.29,
        (False, False): 0.001
    },
    'J': {
        (True,): 0.90,
        (False,): 0.05
    },
    'M': {
        (True,): 0.70,
        (False,): 0.01
    }
}

VARIABLES = ['B', 'E', 'A', 'J', 'M']

def get_probability(var: str, val: bool, assignment: Dict[str, bool]) -> float:
    """Lookup conditional probability P(var=val | parents)."""
    if var == 'B':
        prob_true = CPT['B'][()]
    elif var == 'E':
        prob_true = CPT['E'][()]
    elif var == 'A':
        parents = (assignment['B'], assignment['E'])
        prob_true = CPT['A'][parents]
    elif var == 'J':
        parents = (assignment['A'],)
        prob_true = CPT['J'][parents]
    elif var == 'M':
        parents = (assignment['A'],)
        prob_true = CPT['M'][parents]
    else:
        raise ValueError(f"Unknown variable {var}")

    return prob_true if val else (1.0 - prob_true)

def enumerate_all(vars_left: List[str], evidence: Dict[str, bool]) -> float:
    """Recursively sum out hidden variables over all possible truth assignments."""
    if not vars_left:
        return 1.0

    Y = vars_left[0]
    rest = vars_left[1:]

    if Y in evidence:
        prob = get_probability(Y, evidence[Y], evidence)
        return prob * enumerate_all(rest, evidence)
    else:
        # Sum out hidden variable Y across True and False
        total = 0.0
        for val in [True, False]:
            extended_evidence = dict(evidence)
            extended_evidence[Y] = val
            prob = get_probability(Y, val, extended_evidence)
            total += prob * enumerate_all(rest, extended_evidence)
        return total

def query_bayes_net(query_var: str, evidence: Dict[str, bool]) -> Dict[bool, float]:
    """Compute normalized posterior distribution P(Query | Evidence)."""
    distribution = {}
    for val in [True, False]:
        extended_evidence = dict(evidence)
        extended_evidence[query_var] = val
        distribution[val] = enumerate_all(VARIABLES, extended_evidence)

    # Normalize probabilities so they sum to 1.0
    total = sum(distribution.values())
    for val in distribution:
        distribution[val] /= total
    return distribution

# =====================================================================
# 2. MARKOV DECISION PROCESS (MDP) β€” 3x4 GRIDWORLD VALUE ITERATION
# =====================================================================
class GridWorldMDP:
    def __init__(self, gamma: float = 0.9, noise: float = 0.2):
        self.gamma = gamma
        self.noise = noise
        self.rows = 3
        self.cols = 4

        # States are (r, c)
        self.wall = (1, 1)
        self.terminals = {(0, 3): 1.0, (1, 3): -1.0}
        self.living_reward = -0.04

        self.actions = ['UP', 'DOWN', 'LEFT', 'RIGHT']
        self.action_deltas = {
            'UP': (-1, 0),
            'DOWN': (1, 0),
            'LEFT': (0, -1),
            'RIGHT': (0, 1)
        }

    def get_states(self) -> List[Tuple[int, int]]:
        states = []
        for r in range(self.rows):
            for c in range(self.cols):
                if (r, c) != self.wall:
                    states.append((r, c))
        return states

    def move(self, state: Tuple[int, int], action: str) -> Tuple[int, int]:
        dr, dc = self.action_deltas[action]
        nr, nc = state[0] + dr, state[1] + dc
        # Check boundary collision or wall
        if nr < 0 or nr >= self.rows or nc < 0 or nc >= self.cols or (nr, nc) == self.wall:
            return state  # Bounce back into place
        return (nr, nc)

    def get_transitions(self, state: Tuple[int, int], action: str) -> List[Tuple[float, Tuple[int, int]]]:
        """Stochastic transition: 80% intended action, 10% veer left, 10% veer right."""
        if state in self.terminals:
            return []

        perpendiculars = {
            'UP': ['LEFT', 'RIGHT'],
            'DOWN': ['LEFT', 'RIGHT'],
            'LEFT': ['UP', 'DOWN'],
            'RIGHT': ['UP', 'DOWN']
        }

        transitions = [
            (1.0 - self.noise, self.move(state, action)),
            (self.noise / 2, self.move(state, perpendiculars[action][0])),
            (self.noise / 2, self.move(state, perpendiculars[action][1]))
        ]
        return transitions

    def value_iteration(self, iterations: int = 100) -> Tuple[Dict, Dict]:
        states = self.get_states()
        V = {s: 0.0 for s in states}
        for s in self.terminals:
            V[s] = self.terminals[s]

        for _ in range(iterations):
            new_V = dict(V)
            for s in states:
                if s in self.terminals:
                    continue

                action_values = []
                for a in self.actions:
                    expected_future_val = 0.0
                    for prob, next_s in self.get_transitions(s, a):
                        reward = self.terminals.get(next_s, self.living_reward)
                        expected_future_val += prob * (reward + self.gamma * V[next_s])
                    action_values.append(expected_future_val)

                new_V[s] = max(action_values)
            V = new_V

        # Extract optimal policy pi*(s)
        policy = {}
        for s in states:
            if s in self.terminals:
                policy[s] = 'GOAL' if self.terminals[s] > 0 else 'EXIT'
                continue

            best_a = None
            best_q = -float('inf')
            for a in self.actions:
                q_val = 0.0
                for prob, next_s in self.get_transitions(s, a):
                    reward = self.terminals.get(next_s, self.living_reward)
                    q_val += prob * (reward + self.gamma * V[next_s])
                if q_val > best_q:
                    best_q = q_val
                    best_a = a
            policy[s] = best_a

        return V, policy

# =====================================================================
# DEMONSTRATION HARNESS
# =====================================================================
if __name__ == "__main__":
    print("=" * 68)
    print("DEMO 1: BAYESIAN NETWORK EXACT INFERENCE BY ENUMERATION")
    print("Scenario: JohnCalls = True, MaryCalls = True. Query: P(Burglary)?")
    print("=" * 68)

    evidence = {'J': True, 'M': True}
    posterior_burglary = query_bayes_net('B', evidence)
    print(f"P(Burglary = True  | JohnCalls, MaryCalls) = {posterior_burglary[True]:.4f} (28.4% chance)")
    print(f"P(Burglary = False | JohnCalls, MaryCalls) = {posterior_burglary[False]:.4f} (71.6% chance)")

    print("\n" + "=" * 68)
    print("DEMO 2: MARKOV DECISION PROCESS (MDP) VALUE ITERATION")
    print("3x4 Stochastic GridWorld with Obstacle at (1,1) & Noise = 20%")
    print("=" * 68)

    mdp = GridWorldMDP(gamma=0.9, noise=0.2)
    V_opt, policy_opt = mdp.value_iteration(iterations=50)

    print("Optimal State Values V*(s):")
    for r in range(3):
        row_str = " | ".join(f"{V_opt.get((r, c), 0.0):6.2f}" if (r, c) != (1, 1) else "  WALL" for c in range(4))
        print(f"  [{row_str}]")

    print("\nOptimal Policy pi*(s) Directional Decisions:")
    for r in range(3):
        row_str = " | ".join(f"{policy_opt.get((r, c), ' '):5}" if (r, c) != (1, 1) else " WALL" for c in range(4))
        print(f"  [{row_str}]")
09

Viva Voce & Engineering Interview Questions

Q1: Why is the full joint probability distribution intractable for complex systems, and how do Bayesian Networks achieve exponential compression?

Answer: A full joint probability distribution over n boolean variables requires storing 2^n - 1 distinct probabilities, which is intractable for large n (e.g., 50 variables would require over 1 quadrillion numbers!). Bayesian networks exploit conditional independence: each variable depends directly only on its parents in the DAG. If each variable has at most k parents, the entire network requires only n * 2^k numbers. If n = 50 and k = 3, storage shrinks from 1 quadrillion to just 400 numbers!

Q2: Explain D-Separation and the "Explaining Away" (Collider / V-Structure) phenomenon in Bayesian Networks.

Answer: D-Separation is a graphical algorithm that determines whether variable set X is conditionally independent of Y given evidence Z. In a collider (v-structure: A → C ← B), two independent causes A (Burglary) and B (Earthquake) both influence a common child C (Alarm). If C is unobserved, A and B are completely independent. However, once C is observed (the alarm is blaring), A and B become conditionally dependent! If we suddenly discover that an Earthquake occurred, it "explains away" the alarm, dramatically lowering the posterior probability that a Burglary took place.

Q3: What are the three core inference tasks in Hidden Markov Models (HMMs), and which algorithms solve them?

Answer:
1. Filtering (Monitoring): Computes P(X_t | e_1:t) (the current state distribution given past evidence) using the recursive Forward Algorithm.
2. Smoothing (Hindsight): Computes P(X_k | e_1:t) for k < t (a past state distribution given all evidence up to the future) using the Forward-Backward Algorithm.
3. Most Likely Sequence: Finds the single sequence of hidden states x_1:t that maximizes joint probability given e_1:t using the dynamic programming Viterbi Algorithm.

Q4: What is the Bellman Optimality Equation, and why is the Discount Factor γ necessary in MDPs?

Answer: The Bellman Optimality Equation states that the value of a state s under an optimal policy is the maximum expected immediate reward plus the discounted expected optimal value of the successor state: V*(s) = max_a [ Sum_s' P(s' | s, a) * (R(s, a, s') + γ * V*(s')) ]. The Discount Factor γ (0 <= γ < 1) serves three critical roles:
1. Mathematical Convergence: It prevents cumulative returns from summing to infinity in infinite-horizon tasks, guaranteeing that Value Iteration converges to a unique fixed point.
2. Temporal Preference: It models preference for immediate rewards over deferred rewards (similar to economic inflation and interest rates).
3. Mortality Risk: It models the probability that an autonomous agent may terminate or break at any future step.

Q5: Contrast Value Iteration with Policy Iteration in solving Markov Decision Processes.

Answer:
Value Iteration: Iteratively updates the state value function V(s) using the non-linear Bellman optimality operator (taking the max over actions) until values converge within a small epsilon. The optimal policy is extracted once at the very end.
Policy Iteration: Starts with an arbitrary policy π_0 and alternates between two phases: 1. Policy Evaluation: Computes exact state values V^π(s) for the current policy by solving a system of linear equations. 2. Policy Improvement: Updates the policy greedily using 1-step lookahead: π_k+1(s) = argmax_a [ Sum_s' P(s'|s,a) * V^π_k(s') ]. Policy Iteration often converges in fewer iterations than Value Iteration because the policy space is finite and policies frequently stabilize long before values finish precision convergence.

Q6: What is the Maximum Expected Utility (MEU) principle, and how does utility curvature model human risk aversion?

Answer: The MEU principle states that a rational agent must choose the action that maximizes the expected utility: EU(a) = Sum [ P(outcome | a) * Utility(outcome) ]. Utility curvature formalizes risk attitude: - A concave utility curve (e.g., logarithmic) represents Risk-Averse behavior because the marginal utility of additional wealth diminishes; the expected utility of a gamble is strictly less than the utility of its expected monetary value. - A linear utility curve represents Risk-Neutral behavior. - A convex utility curve represents Risk-Seeking behavior.