香港中文大學數學系

1 排列與組合 (Permutations and Combinations)

兩種核心的計數技巧是排列和組合。排列 (permutation) 計算的是順序重要時的不同排列方式的數量。

1.1 說明範例:從 5 張卡片中有順序地選擇 3 張

我們有五張不同的卡片,分別標示為 \(1, 2, 3, 4, 5\)。我們選擇其中三張卡片,且選擇的順序很重要。

\[ 5 \times 4 \times 3 = 60 \]

\[ \begin{array}{ccc} \bf \fbox{1} & \fbox{2} & \fbox{3} \\ \textrm{(5 張卡片選 1 張)} & \textrm{(剩餘 4 張選 1 張)} & \textrm{(剩餘 3 張選 1 張)} \end{array} \]

1.2 逐步邏輯推理:

我們將選出的三張卡片放入有順序的位置 1、2、3:

  • 位置 \(\bf 1\):有 5 個可用的數字:\(1,2,3,4,5\)(共 5 種選擇)。
  • 位置 \(\bf 2\):位置 \(\bf 1\) 已經使用了一張卡片,剩下 4 張未使用的卡片(共 4 種選擇)。
  • 位置 \(\bf 3\):位置 \(\bf 1\)\(\bf 2\) 已經使用了兩張卡片,只剩下 3 張未使用的卡片(共 3 種選擇)。

根據計數的乘法原理,將每個位置的選擇數量相乘: \[ \text{總有序結果數量} = 5 \times 4 \times 3 = \boldsymbol{60} \]

1.3 排列的一般定義與公式

\(n\) 個不同項目中保留順序地選擇 \(k\) 個不同項目時,這種計數稱為排列,記為 \(\boldsymbol{{}_n P_k}\)

基本乘積形式(有限遞減乘積): \[ {}_n P_k = n\,(n-1)\,(n-2)\cdots(n-k+1), \quad \text{其中 } k \le n \]

如果我們選擇所有的 \(n\) 個項目 (\(k=n\)): \[ {}_n P_n = n\,(n-1)\,(n-2)\cdots 2 \cdot 1 \] 此乘積被定義為 \(n\)階乘 (factorial),記作 \(n!\)(讀作「\(n\) 階乘」)。

1.4 階乘等價推導(逐步代數):

將分子和分母同時乘以尾部乘積 \((n-k)(n-k-1)\cdots 2\cdot 1 = (n-k)!\)\[ \begin{aligned} {}_n P_k &= n\,(n-1)\cdots(n-k+1) \\ &= \frac{\big[n\,(n-1)\cdots(n-k+1)\big] \cdot \big[(n-k)\cdots 2\cdot 1\big]}{(n-k)\cdots 2\cdot 1} \\ &= \frac{n!}{(n-k)!} \end{aligned} \]

1.5 範例 1:卡片範例的數值驗證 (\(n=5,\,k=3\))

\[\begin{align*} {}_5 P_3 &= \frac{5!}{(5-3)!} = \frac{5!}{2!} \\ 5! &= 5\times4\times3\times2\times1 = 120 \\ 2! &= 2\times1 = 2 \\ {}_5 P_3 &= \frac{120}{2} = \boldsymbol{60} \end{align*}\] 與直接計算乘積的結果一致,確認正確。

def compute_factorial(x):
    """計算階乘並印出展開步驟"""
    if x == 0 or x == 1:
        print(f"{x}! = 1 (standard factorial definition)")
        return 1
    running_product = 1
    term_list = []
    for val in range(x, 0, -1):
        term_list.append(str(val))
        running_product *= val
    expansion_str = " × ".join(term_list)
    print(f"{x}! = {expansion_str} = {running_product}")
    return running_product

def permutation(n, k):
    """計算 _nP_k = n!/(n−k)! 並印出完整步驟"""
    print(f"\n=== Calculating Permutation _nP_k for n={n}, k={k} ===")
    print(f"Formula: _nP_k = {n}! / ({n} - {k})! = {n}! / {n - k}!")
    
    n_fact = compute_factorial(n)
    nk_fact = compute_factorial(n - k)
    
    perm_result = n_fact // nk_fact
    print(f"\nDivision step: {n_fact} ÷ {nk_fact} = {perm_result}")
    return perm_result

# 測試文中的 5 張卡片選 3 張範例
result = permutation(n=5, k=3)
## 
## === Calculating Permutation _nP_k for n=5, k=3 ===
## Formula: _nP_k = 5! / (5 - 3)! = 5! / 2!
## 5! = 5 × 4 × 3 × 2 × 1 = 120
## 2! = 2 × 1 = 2
## 
## Division step: 120 ÷ 2 = 60
print(f"\nFinal total ordered card arrangements: {result}")
## 
## Final total ordered card arrangements: 60
import math

def perm(n, k):
    # 整數除法以求得整數排列數
    return math.factorial(n) // math.factorial(n - k)

# 評估教材範例
card_arrangements = perm(5, 3)
print(f"Permutation P(5,3) = {card_arrangements}")
## Permutation P(5,3) = 60

2 組合定義與公式 (Combination Definition and Formula)

組合 (combination) 計算的是順序不重要時選擇項目的方式數量。

2.1 說明範例:從標示為 \(1,2,3,4,5\) 的 5 張卡片中無序選擇 3 張

直接計算: \[ \frac{5 \times 4 \times 3}{3!} = 10 \]

2.2 步驟 1:解釋順序的等價性

假設選出的數值為 \(1,2,3\)

  • 如果順序重要(排列),則有 \(3! = 3\times2\times1 = 6\) 種不同的有序排列: \[(1,2,3),\;(1,3,2),\;(2,1,3),\;(2,3,1),\;(3,1,2),\;(3,2,1)\]

  • 對於組合來說,所有 6 種有序分組都被視為同一個相同的無序分組。 為了消除 \(k\) 個被選項目之間多餘的排列,我們將總排列數除以 \(k!\)

2.3 步驟 2:使用階乘改寫分子

分子 \(5\times4\times3\) 就是排列 \({}_5 P_3 = \frac{5!}{(5-3)!} = \frac{5!}{2!}\)。 展開階乘定義: \[ 5! = 5\times4\times3\times2\times1,\quad 2! = 2\times1 \] 將分子與分母中的 \(2!\) 抵消後,剩下 \(5\times4\times3\)。 代回組合表達式: \[ \frac{5\times4\times3}{3!} = \frac{\dfrac{5!}{2!}}{3!} = \frac{5!}{3!\cdot 2!} \]

2.4 步驟 3:逐步驗證數值

\[\begin{align*} 3! &= 3\times2\times1 = 6 \\ 5\times4\times3 &= 60 \\ \frac{60}{6} &= \boldsymbol{10} \end{align*}\]

2.5 一般組合公式

當從 \(n\) 個不同項目中選擇 \(k\) 個項目而不考慮順序時,組合數記為 \({}_n C_k\)(也寫作二項式係數 \(\dbinom{n}{k}\))。 \[ {}_n C_k = \frac{{}_n P_k}{k!} = \frac{n!}{(n-k)!\,k!} = \binom{n}{k},\quad \text{其中 } k\le n \]

2.6 範例 2:從 500 條領帶中選擇 5 條

問題:找出從總共 500 條領帶中無序挑選 5 條領帶的方式數量。 根據組合公式,\(n=500,\;k=5\)\[ \binom{500}{5} = \frac{500!}{5!\cdot (500-5)!} = \frac{500!}{5!\cdot 495!} \]

2.6.1 為了便於手動計算而化簡分數(抵消 \(495!\)):

\[ \begin{aligned} \binom{500}{5} &= \frac{500 \times 499 \times 498 \times 497 \times 496 \times 495!}{5! \times 495!} \\ &= \frac{500 \times 499 \times 498 \times 497 \times 496}{5\times4\times3\times2\times1} \end{aligned} \]

2.6.2 完整的算術計算步驟:

分子乘積: \[ 500 \times 499 = 249500,\quad 249500 \times 498 = 124251000,\quad 124251000 \times 497 = 61752747000,\quad 61752747000 \times 496 = 30629362512000 \] 分母 \(5! = 120\) \[ \binom{500}{5} = \frac{30629362512000}{120} = \boldsymbol{255244687600} \]

def factorial(x):
    """計算階乘並印出展開步驟"""
    if x == 0 or x == 1:
        print(f"{x}! = 1")
        return 1
    prod = 1
    terms = []
    for num in range(x, 0, -1):
        terms.append(str(num))
        prod *= num
    expr = " × ".join(terms)
    print(f"{x}! = {expr} = {prod}")
    return prod

def combination(n, k):
    """計算 C(n,k) = n!/(k!*(n-k)!) 並顯示明細"""
    print(f"\n=== Calculating Combination C({n}, {k}) ===")
    print(f"Formula: C(n,k) = {n}! / ( {k}! × ({n}-{k})! ) = {n}! / ( {k}! × {n-k}! )")
    
    n_fact = factorial(n)
    k_fact = factorial(k)
    nk_fact = factorial(n - k)
    
    comb_val = n_fact // (k_fact * nk_fact)
    print(f"\nFinal division: {n_fact} ÷ ({k_fact} × {nk_fact}) = {comb_val}")
    return comb_val

# 測試 1:從 5 張卡片無序選擇 3 張
print("===== Test 1: Pick 3 unordered cards from 5 =====")
## ===== Test 1: Pick 3 unordered cards from 5 =====
res1 = combination(5, 3)
## 
## === Calculating Combination C(5, 3) ===
## Formula: C(n,k) = 5! / ( 3! × (5-3)! ) = 5! / ( 3! × 2! )
## 5! = 5 × 4 × 3 × 2 × 1 = 120
## 3! = 3 × 2 × 1 = 6
## 2! = 2 × 1 = 2
## 
## Final division: 120 ÷ (6 × 2) = 10
print(f"Answer (unordered card groups): {res1}\n")
## Answer (unordered card groups): 10
# 測試 2:從 500 條領帶選擇 5 條
print("===== Test 2: Pick 5 unordered ties from 500 =====")
## ===== Test 2: Pick 5 unordered ties from 500 =====
res2 = combination(500, 5)
## 
## === Calculating Combination C(500, 5) ===
## Formula: C(n,k) = 500! / ( 5! × (500-5)! ) = 500! / ( 5! × 495! )
## 500! = 500 × 499 × 498 × 497 × 496 × 495 × 494 × 493 × 492 × 491 × 490 × 489 × 488 × 487 × 486 × 485 × 484 × 483 × 482 × 481 × 480 × 479 × 478 × 477 × 476 × 475 × 474 × 473 × 472 × 471 × 470 × 469 × 468 × 467 × 466 × 465 × 464 × 463 × 462 × 461 × 460 × 459 × 458 × 457 × 456 × 455 × 454 × 453 × 452 × 451 × 450 × 449 × 448 × 447 × 446 × 445 × 444 × 443 × 442 × 441 × 440 × 439 × 438 × 437 × 436 × 435 × 434 × 433 × 432 × 431 × 430 × 429 × 428 × 427 × 426 × 425 × 424 × 423 × 422 × 421 × 420 × 419 × 418 × 417 × 416 × 415 × 414 × 413 × 412 × 411 × 410 × 409 × 408 × 407 × 406 × 405 × 404 × 403 × 402 × 401 × 400 × 399 × 398 × 397 × 396 × 395 × 394 × 393 × 392 × 391 × 390 × 389 × 388 × 387 × 386 × 385 × 384 × 383 × 382 × 381 × 380 × 379 × 378 × 377 × 376 × 375 × 374 × 373 × 372 × 371 × 370 × 369 × 368 × 367 × 366 × 365 × 364 × 363 × 362 × 361 × 360 × 359 × 358 × 357 × 356 × 355 × 354 × 353 × 352 × 351 × 350 × 349 × 348 × 347 × 346 × 345 × 344 × 343 × 342 × 341 × 340 × 339 × 338 × 337 × 336 × 335 × 334 × 333 × 332 × 331 × 330 × 329 × 328 × 327 × 326 × 325 × 324 × 323 × 322 × 321 × 320 × 319 × 318 × 317 × 316 × 315 × 314 × 313 × 312 × 311 × 310 × 309 × 308 × 307 × 306 × 305 × 304 × 303 × 302 × 301 × 300 × 299 × 298 × 297 × 296 × 295 × 294 × 293 × 292 × 291 × 290 × 289 × 288 × 287 × 286 × 285 × 284 × 283 × 282 × 281 × 280 × 279 × 278 × 277 × 276 × 275 × 274 × 273 × 272 × 271 × 270 × 269 × 268 × 267 × 266 × 265 × 264 × 263 × 262 × 261 × 260 × 259 × 258 × 257 × 256 × 255 × 254 × 253 × 252 × 251 × 250 × 249 × 248 × 247 × 246 × 245 × 244 × 243 × 242 × 241 × 240 × 239 × 238 × 237 × 236 × 235 × 234 × 233 × 232 × 231 × 230 × 229 × 228 × 227 × 226 × 225 × 224 × 223 × 222 × 221 × 220 × 219 × 218 × 217 × 216 × 215 × 214 × 213 × 212 × 211 × 210 × 209 × 208 × 207 × 206 × 205 × 204 × 203 × 202 × 201 × 200 × 199 × 198 × 197 × 196 × 195 × 194 × 193 × 192 × 191 × 190 × 189 × 188 × 187 × 186 × 185 × 184 × 183 × 182 × 181 × 180 × 179 × 178 × 177 × 176 × 175 × 174 × 173 × 172 × 171 × 170 × 169 × 168 × 167 × 166 × 165 × 164 × 163 × 162 × 161 × 160 × 159 × 158 × 157 × 156 × 155 × 154 × 153 × 152 × 151 × 150 × 149 × 148 × 147 × 146 × 145 × 144 × 143 × 142 × 141 × 140 × 139 × 138 × 137 × 136 × 135 × 134 × 133 × 132 × 131 × 130 × 129 × 128 × 127 × 126 × 125 × 124 × 123 × 122 × 121 × 120 × 119 × 118 × 117 × 116 × 115 × 114 × 113 × 112 × 111 × 110 × 109 × 108 × 107 × 106 × 105 × 104 × 103 × 102 × 101 × 100 × 99 × 98 × 97 × 96 × 95 × 94 × 93 × 92 × 91 × 90 × 89 × 88 × 87 × 86 × 85 × 84 × 83 × 82 × 81 × 80 × 79 × 78 × 77 × 76 × 75 × 74 × 73 × 72 × 71 × 70 × 69 × 68 × 67 × 66 × 65 × 64 × 63 × 62 × 61 × 60 × 59 × 58 × 57 × 56 × 55 × 54 × 53 × 52 × 51 × 50 × 49 × 48 × 47 × 46 × 45 × 44 × 43 × 42 × 41 × 40 × 39 × 38 × 37 × 36 × 35 × 34 × 33 × 32 × 31 × 30 × 29 × 28 × 27 × 26 × 25 × 24 × 23 × 22 × 21 × 20 × 19 × 18 × 17 × 16 × 15 × 14 × 13 × 12 × 11 × 10 × 9 × 8 × 7 × 6 × 5 × 4 × 3 × 2 × 1 = 1220136825991110068701238785423046926253574342803192842192413588385845373153881997605496447502203281863013616477148203584163378722078177200480785205159329285477907571939330603772960859086270429174547882424912726344305670173270769461062802310452644218878789465754777149863494367781037644274033827365397471386477878495438489595537537990423241061271326984327745715546309977202781014561081188373709531016356324432987029563896628911658974769572087926928871281780070265174507768410719624390394322536422605234945850129918571501248706961568141625359056693423813008856249246891564126775654481886506593847951775360894005745238940335798476363944905313062323749066445048824665075946735862074637925184200459369692981022263971952597190945217823331756934581508552332820762820023402626907898342451712006207714640979456116127629145951237229913340169552363850942885592018727433795173014586357570828355780158735432768888680120399882384702151467605445407663535984174430480128938313896881639487469658817504506926365338175055478128640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
## 5! = 5 × 4 × 3 × 2 × 1 = 120
## 495! = 495 × 494 × 493 × 492 × 491 × 490 × 489 × 488 × 487 × 486 × 485 × 484 × 483 × 482 × 481 × 480 × 479 × 478 × 477 × 476 × 475 × 474 × 473 × 472 × 471 × 470 × 469 × 468 × 467 × 466 × 465 × 464 × 463 × 462 × 461 × 460 × 459 × 458 × 457 × 456 × 455 × 454 × 453 × 452 × 451 × 450 × 449 × 448 × 447 × 446 × 445 × 444 × 443 × 442 × 441 × 440 × 439 × 438 × 437 × 436 × 435 × 434 × 433 × 432 × 431 × 430 × 429 × 428 × 427 × 426 × 425 × 424 × 423 × 422 × 421 × 420 × 419 × 418 × 417 × 416 × 415 × 414 × 413 × 412 × 411 × 410 × 409 × 408 × 407 × 406 × 405 × 404 × 403 × 402 × 401 × 400 × 399 × 398 × 397 × 396 × 395 × 394 × 393 × 392 × 391 × 390 × 389 × 388 × 387 × 386 × 385 × 384 × 383 × 382 × 381 × 380 × 379 × 378 × 377 × 376 × 375 × 374 × 373 × 372 × 371 × 370 × 369 × 368 × 367 × 366 × 365 × 364 × 363 × 362 × 361 × 360 × 359 × 358 × 357 × 356 × 355 × 354 × 353 × 352 × 351 × 350 × 349 × 348 × 347 × 346 × 345 × 344 × 343 × 342 × 341 × 340 × 339 × 338 × 337 × 336 × 335 × 334 × 333 × 332 × 331 × 330 × 329 × 328 × 327 × 326 × 325 × 324 × 323 × 322 × 321 × 320 × 319 × 318 × 317 × 316 × 315 × 314 × 313 × 312 × 311 × 310 × 309 × 308 × 307 × 306 × 305 × 304 × 303 × 302 × 301 × 300 × 299 × 298 × 297 × 296 × 295 × 294 × 293 × 292 × 291 × 290 × 289 × 288 × 287 × 286 × 285 × 284 × 283 × 282 × 281 × 280 × 279 × 278 × 277 × 276 × 275 × 274 × 273 × 272 × 271 × 270 × 269 × 268 × 267 × 266 × 265 × 264 × 263 × 262 × 261 × 260 × 259 × 258 × 257 × 256 × 255 × 254 × 253 × 252 × 251 × 250 × 249 × 248 × 247 × 246 × 245 × 244 × 243 × 242 × 241 × 240 × 239 × 238 × 237 × 236 × 235 × 234 × 233 × 232 × 231 × 230 × 229 × 228 × 227 × 226 × 225 × 224 × 223 × 222 × 221 × 220 × 219 × 218 × 217 × 216 × 215 × 214 × 213 × 212 × 211 × 210 × 209 × 208 × 207 × 206 × 205 × 204 × 203 × 202 × 201 × 200 × 199 × 198 × 197 × 196 × 195 × 194 × 193 × 192 × 191 × 190 × 189 × 188 × 187 × 186 × 185 × 184 × 183 × 182 × 181 × 180 × 179 × 178 × 177 × 176 × 175 × 174 × 173 × 172 × 171 × 170 × 169 × 168 × 167 × 166 × 165 × 164 × 163 × 162 × 161 × 160 × 159 × 158 × 157 × 156 × 155 × 154 × 153 × 152 × 151 × 150 × 149 × 148 × 147 × 146 × 145 × 144 × 143 × 142 × 141 × 140 × 139 × 138 × 137 × 136 × 135 × 134 × 133 × 132 × 131 × 130 × 129 × 128 × 127 × 126 × 125 × 124 × 123 × 122 × 121 × 120 × 119 × 118 × 117 × 116 × 115 × 114 × 113 × 112 × 111 × 110 × 109 × 108 × 107 × 106 × 105 × 104 × 103 × 102 × 101 × 100 × 99 × 98 × 97 × 96 × 95 × 94 × 93 × 92 × 91 × 90 × 89 × 88 × 87 × 86 × 85 × 84 × 83 × 82 × 81 × 80 × 79 × 78 × 77 × 76 × 75 × 74 × 73 × 72 × 71 × 70 × 69 × 68 × 67 × 66 × 65 × 64 × 63 × 62 × 61 × 60 × 59 × 58 × 57 × 56 × 55 × 54 × 53 × 52 × 51 × 50 × 49 × 48 × 47 × 46 × 45 × 44 × 43 × 42 × 41 × 40 × 39 × 38 × 37 × 36 × 35 × 34 × 33 × 32 × 31 × 30 × 29 × 28 × 27 × 26 × 25 × 24 × 23 × 22 × 21 × 20 × 19 × 18 × 17 × 16 × 15 × 14 × 13 × 12 × 11 × 10 × 9 × 8 × 7 × 6 × 5 × 4 × 3 × 2 × 1 = 39835527935427442653307246390889133574455058929474360918831440169865373173062205245987407819877230158625954248105449553737789484754202879130453683311034798251040647448239996323595729529242460558022987116647853214200309640883549364452499131740748918231314884434143823158375186224673641496062809972380056937780444997576203214305328732152335729333031277824713798129156112852590636201781658170402000138642530440170821847233900697242790032037350027852544137918297862391191896981741518799468846174738258138349655578686063236119130723929973173232037676743659319972210894275877710333185091850615091699690800778651674399080909618893555520041340693021809886928098043362394126080750337167664977655745225761742519841258652832147366990072007520590506718330245094485979644081447888376081078472943701147302371285456158635432103502841496876705880085878159883750361223277928135652117374579120356599205611267455058317952893096761242338655156781065342979004276319051014016381377369519365969606362756724961345364788510720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
## 
## Final division: 1220136825991110068701238785423046926253574342803192842192413588385845373153881997605496447502203281863013616477148203584163378722078177200480785205159329285477907571939330603772960859086270429174547882424912726344305670173270769461062802310452644218878789465754777149863494367781037644274033827365397471386477878495438489595537537990423241061271326984327745715546309977202781014561081188373709531016356324432987029563896628911658974769572087926928871281780070265174507768410719624390394322536422605234945850129918571501248706961568141625359056693423813008856249246891564126775654481886506593847951775360894005745238940335798476363944905313062323749066445048824665075946735862074637925184200459369692981022263971952597190945217823331756934581508552332820762820023402626907898342451712006207714640979456116127629145951237229913340169552363850942885592018727433795173014586357570828355780158735432768888680120399882384702151467605445407663535984174430480128938313896881639487469658817504506926365338175055478128640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ÷ (120 × 39835527935427442653307246390889133574455058929474360918831440169865373173062205245987407819877230158625954248105449553737789484754202879130453683311034798251040647448239996323595729529242460558022987116647853214200309640883549364452499131740748918231314884434143823158375186224673641496062809972380056937780444997576203214305328732152335729333031277824713798129156112852590636201781658170402000138642530440170821847233900697242790032037350027852544137918297862391191896981741518799468846174738258138349655578686063236119130723929973173232037676743659319972210894275877710333185091850615091699690800778651674399080909618893555520041340693021809886928098043362394126080750337167664977655745225761742519841258652832147366990072007520590506718330245094485979644081447888376081078472943701147302371285456158635432103502841496876705880085878159883750361223277928135652117374579120356599205611267455058317952893096761242338655156781065342979004276319051014016381377369519365969606362756724961345364788510720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) = 255244687600
print(f"Answer (unordered tie selections): {res2}")
## Answer (unordered tie selections): 255244687600
import math

def comb(n, k):
    return math.factorial(n) // (math.factorial(k) * math.factorial(n - k))

# 評估範例
card_groups = comb(5, 3)
tie_choices = comb(500, 5)

print(f"C(5,3) (card groups) = {card_groups}")
## C(5,3) (card groups) = 10
print(f"C(500,5) (tie selections) = {tie_choices}")
## C(500,5) (tie selections) = 255244687600

3 允許重複的排列與組合 (Permutations and Combinations with Repetition)

在數學上,這個表達式代表二項式係數: \[ \binom{500}{5} \]

這些計算也可以使用 R 的內建指令來求二項式係數:

## binomial(500,5) = 255244687600

到目前為止,我們涵蓋了不可重複選擇的計數問題。當允許重複選擇項目時,我們對允許重複的排列和組合使用不同的公式。

3.1 1) 允許重複的排列(重複排列):符號 \(\boldsymbol{{}_n \Pi_k}\)

\({}_n \Pi_k\) 表示從 \(n\) 種不同的類型中有順序地選擇 \(k\) 個項目,其中項目可以被重複使用(允許重複)。 \[ \boldsymbol{{}_n \Pi_k = n^k} \]

3.2 2) 允許重複的組合(重複組合):符號 \(\boldsymbol{{}_n H_k}\)

\({}_n H_k\) 表示從 \(n\) 種不同的類型中無序選擇 \(k\) 個項目,其中項目可以被重複使用(允許重複)。 該公式可以轉換為標準的二項式係數: \[ \boldsymbol{{}_n H_k = \binom{n+k-1}{k}} \]

3.3 範例 3

\(\{1,2,3,4,5\}\) 中選擇三個數字,將它們按順序排列形成三位的自然數(允許重複)。 求有多少個這樣的三位數是 \(5\) 的倍數。

3.3.1 逐步解題推理:

如果一個自然數的個位數是 \(0\)\(5\),它就是 \(5\) 的倍數。我們可用的數字只有 \(1,2,3,4,5\),因此個位數必須固定為 \(5\)

  • 位置 3(個位):只有 1 個有效選擇(\(5\)

  • 位置 1(百位)和 2(十位):我們從 \(\{1,2,3,4,5\}\) 中選擇 2 個數字,且允許重複(\(n=5,\ k=2\)

對於前兩位數字來說,這是一個允許重複的排列問題:\({}_n \Pi_k = n^k\)

\[\begin{align*} n &= 5,\quad k=2 \\ {}_5 \Pi_2 &= 5^2 \\ 5^2 &= 5 \times 5 = \boldsymbol{25} \end{align*}\] 符合條件的 5 的倍數三位數共有:\(\boldsymbol{25}\)

3.4 範例 4

四個人對三位候選人 A、B、C 進行不記名投票。求總共有多少種不同的投票結果分佈。

3.4.1 逐步解題推理:

投票是不記名的,因此只有每位候選人獲得的票數才重要(投票者的順序不重要)。這是一個允許重複的組合情況:

  • \(n = 3\) 位不同的候選人 (A,B,C)

  • \(k = 4\) 張總票數可供分配

公式:\({}_n H_k = \binom{n+k-1}{k}\)

\[\begin{align*} {}_3 H_4 &= \binom{3+4-1}{4} = \binom{6}{4} \end{align*}\] 二項式係數化簡:\(\dbinom{6}{4} = \dbinom{6}{2}\) \[\begin{align*} \binom{6}{2} &= \frac{6!}{2!\,(6-2)!} = \frac{6!}{2!\,4!} \\ 6! &= 6 \times 5 \times 4! \\ \binom{6}{2} &= \frac{6 \times 5 \times 4!}{(2\times1) \times 4!} = \frac{30}{2} = \boldsymbol{15} \end{align*}\] 總共獨特的匿名投票分佈:\(\boldsymbol{15}\)

import math

def factorial(x):
    """計算階乘並印出展開步驟"""
    if x == 0 or x == 1:
        print(f"{x}! = 1")
        return 1
    product = 1
    terms = []
    for val in range(x, 0, -1):
        terms.append(str(val))
        product *= val
    exp_str = " × ".join(terms)
    print(f"{x}! = {exp_str} = {product}")
    return product

def perm_repeat(n, k):
    """重複排列: n^k"""
    print(f"\nPermutation with repetition _{n}Π_{k} = {n}^{k}")
    res = n ** k
    print(f"{n} × {n} × ... ({k} times) = {res}")
    return res

def comb_repeat(n, k):
    """重複組合: binomial(n+k-1, k)"""
    upper = n + k - 1
    print(f"\nCombination with repetition _{n}H_{k} = binom({upper}, {k})")
    numer = factorial(upper)
    denom = factorial(k) * factorial(upper - k)
    res = numer // denom
    print(f"binom({upper},{k}) = {numer} ÷ ({factorial(k)} × {factorial(upper - k)}) = {res}")
    return res

# 1. SageMath 二項式參考測試 (C(500,5))
print("=== SageMath binomial(500,5) Equivalent ===")
## === SageMath binomial(500,5) Equivalent ===
c500_5 = math.factorial(500) // (math.factorial(5)*math.factorial(495))
print(f"C(500,5) = {c500_5}\n")
## C(500,5) = 255244687600
# 範例 3: 5 的倍數三位數,數字 {1,2,3,4,5},允許重複
print("===== Example 3: Three-digit multiples of 5 =====")
## ===== Example 3: Three-digit multiples of 5 =====
ex3 = perm_repeat(n=5, k=2)
## 
## Permutation with repetition _5Π_2 = 5^2
## 5 × 5 × ... (2 times) = 25
print(f"Total valid numbers = {ex3}\n")
## Total valid numbers = 25
# 範例 4: 4 張票給 3 個候選人 (匿名)
print("===== Example 4: Anonymous vote distributions =====")
## ===== Example 4: Anonymous vote distributions =====
ex4 = comb_repeat(n=3, k=4)
## 
## Combination with repetition _3H_4 = binom(6, 4)
## 6! = 6 × 5 × 4 × 3 × 2 × 1 = 720
## 4! = 4 × 3 × 2 × 1 = 24
## 2! = 2 × 1 = 2
## 4! = 4 × 3 × 2 × 1 = 24
## 2! = 2 × 1 = 2
## binom(6,4) = 720 ÷ (24 × 2) = 15
print(f"Total unique vote outcomes = {ex4}")
## Total unique vote outcomes = 15
import math

# 重複排列: n^k
def perm_rep(n, k):
    return n ** k

# 重複組合: C(n+k-1, k)
def comb_rep(n, k):
    return math.comb(n + k - 1, k)

# 測試所有情況
print(f"Sage binomial(500,5) = {math.comb(500,5)}")
## Sage binomial(500,5) = 255244687600
print(f"Example3 (3-digit multiples of 5): {perm_rep(5,2)}")
## Example3 (3-digit multiples of 5): 25
print(f"Example4 (4 votes,3 candidates): {comb_rep(3,4)}")
## Example4 (4 votes,3 candidates): 15

4 概率 (Probability)

特定事件發生的概率取值在區間 \([0,1]\) 內。例如,擲一枚公平的硬幣,出現正面的概率為 \(\frac12\)

當拋擲一枚硬幣時,只存在兩種結果:正面或反面。總共有 \(2\) 種可能的結果,而符合正面的結果恰好有 \(1\) 種。

  • 概率值為 \(0\) 表示事件不可能發生(絕對不會發生)。

  • 概率值為 \(1\) 表示事件必然發生(一定會發生)。

要在數學上計算概率,我們首先要定義所有可能結果的完整集合。

  • 拋硬幣的樣本空間:\(S=\{\text{正面},\text{反面}\}\)

  • 標準六面骰子的樣本空間:\(S=\{1,2,3,4,5,6\}\)

這個所有可能結果的完整集合被稱為樣本空間 (sample space),記作 \(S\)

4.1 經典概率定義 (Formal Classical Probability Definition)

假設:

  • \(n(S) =\) 樣本空間 \(S\) 中不同可能結果的總數

  • \(n(A) =\) 特定事件 \(A\) 的有利(符合條件)結果的數量

事件 \(A\) 的經典概率,記為 \(P(A)\),定義為: \[ P(A) = \frac{\text{事件 }A\text{ 的有利結果數量}}{\text{所有可能結果的總數}} = \boldsymbol{\frac{n(A)}{n(S)}} \]

4.2 幾何概率定義 (Geometric Probability Definition)

對於幾何問題,其中 \(S\) 代表總區域/面積,且 \(A\subset S\)(事件區域完全位於樣本空間區域內): \[ P(A) = \boldsymbol{\frac{\text{區域 }A\text{ 的面積}}{\text{區域 }S\text{ 的面積}}} \]

4.3 統計概率與大數定律 (Statistical Probability & Law of Large Numbers)

在實際的實驗試驗中:

假設一個相同的試驗總共重複了 \(n\) 次,並觀察到事件 \(A\) 發生了 \(k\) 次。 事件 \(A\)相對頻率 (relative frequency)(統計概率)為: \[ \frac{k}{n} \]

隨著試驗次數 \(n\) 無限增大,相對頻率會收斂到一個固定的常數值 \(\mathcal{P}\),稱為數學概率 \(P(A)\)

這種收斂性質就是大數定律 (Law of Large Numbers),可以用極限正式表達: \[ \boldsymbol{\lim_{n\to\infty} \frac{k}{n} = P(A)} \]

4.4 基本概率公理與性質 (Fundamental Probability Axioms & Properties)

\(A\) 為樣本空間 \(S\) 內的任意事件:

  • 有界範圍:對於任何有效的事件 \(A\subseteq S\)\(\boldsymbol{0 \le P(A) \le 1}\)

  • 完整樣本空間的必然性:\(\boldsymbol{P(S) = 1}\)

  • 不可能的空事件:\(\boldsymbol{P(\emptyset) = 0}\)\(\emptyset\) = 空集,沒有結果)

  • 互斥事件的可加性:如果 \(A\)\(B\) 不能同時發生(不相交,\(A\cap B=\emptyset\)): \[ \boldsymbol{P(A\cup B) = P(A) + P(B)} \]

  • 補集法則:設 \(A^c\)(也寫作 \(\overline{A}\))表示補集事件(所有 \(A\) 發生結果的集合): \[ \boldsymbol{P(A^c) = 1 - P(A)} \]

4.4.1 逐步計算範例(拋硬幣出現正面)

\[\begin{align*} S &= \{\text{正面},\text{反面}\} \implies n(S)=2 \\ A &= \{\text{正面}\} \implies n(A)=1 \\ P(\text{正面}) &= \frac{n(A)}{n(S)} = \frac{1}{2} = \boldsymbol{0.5} \end{align*}\]

4.4.2 逐步計算範例(擲骰子,事件 = 擲出 3)

\[\begin{align*} S &= \{1,2,3,4,5,6\} \implies n(S)=6 \\ A &= \{3\} \implies n(A)=1 \\ P(\text{擲出 }3) &= \frac{1}{6} \approx \boldsymbol{0.1667} \end{align*}\]

def classical_probability(favorable, total):
    """
    Classical probability P(A) = n(A)/n(S)
    favorable: n(A), total: n(S)
    """
    print(f"\nClassical Probability Calculation:")
    print(f"n(A) (favorable outcomes) = {favorable}")
    print(f"n(S) (total sample space outcomes) = {total}")
    prob = favorable / total
    print(f"P(A) = {favorable} / {total} = {prob:.4f}")
    return prob

def complement_prob(p_a):
    """Complement rule P(A^c) = 1 - P(A)"""
    p_ac = 1 - p_a
    print(f"\nComplement Event Calculation:")
    print(f"P(A) = {p_a:.4f}, so P(A^c) = 1 - {p_a:.4f} = {p_ac:.4f}")
    return p_ac

def geometric_prob(area_a, area_s):
    """Geometric probability P(A) = Area(A)/Area(S)"""
    prob = area_a / area_s
    print(f"\nGeometric Probability Calculation:")
    print(f"Area(A) = {area_a}, Area(S) = {area_s}")
    print(f"P(A) = {area_a}/{area_s} = {prob:.4f}")
    return prob

# ---------------- 測試案例 1: 拋硬幣出現正面 ----------------
print("===== Test 1: Fair Coin, Event = Heads =====")
## ===== Test 1: Fair Coin, Event = Heads =====
p_head = classical_probability(favorable=1, total=2)
## 
## Classical Probability Calculation:
## n(A) (favorable outcomes) = 1
## n(S) (total sample space outcomes) = 2
## P(A) = 1 / 2 = 0.5000
# 補集: 反面
p_tail = complement_prob(p_head)
## 
## Complement Event Calculation:
## P(A) = 0.5000, so P(A^c) = 1 - 0.5000 = 0.5000
# ---------------- 測試案例 2: 擲出 3 ----------------
print("\n===== Test 2: 6-sided Die, Event = Roll 3 =====")
## 
## ===== Test 2: 6-sided Die, Event = Roll 3 =====
p_three = classical_probability(favorable=1, total=6)
## 
## Classical Probability Calculation:
## n(A) (favorable outcomes) = 1
## n(S) (total sample space outcomes) = 6
## P(A) = 1 / 6 = 0.1667
# 補集: 不是擲出 3
p_not_three = complement_prob(p_three)
## 
## Complement Event Calculation:
## P(A) = 0.1667, so P(A^c) = 1 - 0.1667 = 0.8333
# ---------------- 測試案例 3: 幾何概率範例 ----------------
print("\n===== Test 3: Geometric Probability Example =====")
## 
## ===== Test 3: Geometric Probability Example =====
# 假設總正方形面積 = 100,陰影事件面積 = 25
geo_p = geometric_prob(area_a=25, area_s=100)
## 
## Geometric Probability Calculation:
## Area(A) = 25, Area(S) = 100
## P(A) = 25/100 = 0.2500
# 核心概率公式
def prob_classical(nA, nS):
    return nA / nS

def prob_complement(pA):
    return 1 - pA

def prob_geo(areaA, areaS):
    return areaA / areaS

# 執行範例
coin_head = prob_classical(1,2)
die_three = prob_classical(1,6)
geo_sample = prob_geo(25,100)

print(f"P(Coin Heads) = {coin_head}")
## P(Coin Heads) = 0.5
print(f"P(Die roll 3) = {die_three:.4f}")
## P(Die roll 3) = 0.1667
print(f"P(Geometric shaded region) = {geo_sample}")
## P(Geometric shaded region) = 0.25

4.5 範例 5:抽出兩個同色球的概率

問題描述:一個袋子裡裝有 3 個黑球、2 個白球和 1 個紅球(總共有 \(3+2+1=6\) 個球)。隨機同時抽出兩個球。計算選出的這兩個球顏色相同的概率。

4.5.1 步驟 1:計算從 6 個球中無序抽出 2 個球的總方式數

同時抽出兩個球是一種無序選擇,因此我們使用組合 \(\binom{n}{k}={}_n C_k\)。 總樣本空間結果數: \[ n(S) = \binom{6}{2} \] 展開並逐步計算: \[\begin{align*} \binom{6}{2} &= \frac{6!}{2!\,(6-2)!} = \frac{6!}{2!\cdot 4!} \\ 6! &= 6\times5\times4! \\ \binom{6}{2} &= \frac{6\times5\times4!}{(2\times1)\times4!} = \frac{30}{2} = \boldsymbol{15} \end{align*}\]

4.5.2 步驟 2:計算有利結果數(兩個相同顏色的球)

只有黑色和白色至少有兩個球;紅球只有 1 個,因此不可能抽出兩個紅球。

  1. 從 3 個黑球中選出 2 個黑球的方式數:\(\binom{3}{2}\) \[\begin{align*} \binom{3}{2} &= \frac{3!}{2!\cdot1!} = \frac{3\times2!}{2!\times1} = \boldsymbol{3} \end{align*}\]

  2. 從 2 個白球中選出 2 個白球的方式數:\(\binom{2}{2}\) \[\begin{align*} \binom{2}{2} &= \frac{2!}{2!\cdot0!} = \frac{2!}{2!\times1} = \boldsymbol{1} \quad (\text{根據定義 }0!=1) \end{align*}\]

總有利結果數 \(n(A)\) = 黑色對數 + 白色對數: \[ n(A) = \binom{3}{2} + \binom{2}{2} = 3 + 1 = \boldsymbol{4} \]

\[ P(\text{同色}) = \frac{n(A)}{n(S)} = \frac{4}{15} \]

4.5.3 上述數學表達式對應於:

\[ \frac{\binom{3}{2} + \binom{2}{2}}{\binom{6}{2}} \]

4.6 範例 6:使用 Python 程式碼進行拋硬幣模擬

我們使用 R 程式語言模擬重複拋硬幣的過程,以觀察相對頻率(統計概率)。

table(coin) 函數輸出的頻率計數顯示了在所有模擬的拋擲中,正面和反面出現了多少次。隨著試驗次數增加,相對頻率 \(\frac{\text{正面}}{n}\) 收斂於數學概率 \(P(\text{正面})=\frac12\)(大數定律)。

import math

def binom(n, k):
    """二項式係數 C(n,k) = n!/(k!*(n-k)!)"""
    return math.factorial(n) // (math.factorial(k) * math.factorial(n - k))

# 步驟 1: 從 6 個選 2 個的總方式數
total = binom(6, 2)
print(f"Total unordered pairs C(6,2) = {total}")
## Total unordered pairs C(6,2) = 15
# 步驟 2: 符合條件的同色對數
black_pairs = binom(3, 2)
white_pairs = binom(2, 2)
favorable = black_pairs + white_pairs
print(f"Black pairs C(3,2) = {black_pairs}")
## Black pairs C(3,2) = 3
print(f"White pairs C(2,2) = {white_pairs}")
## White pairs C(2,2) = 1
print(f"Total favorable same-color pairs = {favorable}")
## Total favorable same-color pairs = 4
# 步驟 3: 概率
prob = favorable / total
print(f"\nProbability(two same color) = {favorable}/{total} = {prob:.4f}")
## 
## Probability(two same color) = 4/15 = 0.2667
# SageMath 等效單行計算
sage_eq = (binom(3,2)+binom(2,2))/binom(6,2)
print(f"SageMath command result match: {sage_eq:.4f}")
## SageMath command result match: 0.2667
import random
import collections

def flip_coins(num_trials):
    # 模擬拋硬幣: 0=Head(正面), 1=Tail(反面)
    outcomes = random.choices(["head", "tail"], k=num_trials)
    count = collections.Counter(outcomes)
    heads = count.get("head", 0)
    tails = count.get("tail", 0)
    freq_head = heads / num_trials
    print(f"\n--- {num_trials} Coin Flips Simulation ---")
    print(f"Heads count: {heads}, Tails count: {tails}")
    print(f"Relative frequency of Heads = {freq_head:.4f}")
    return outcomes, count

# 對應 R 的 Task1: 10 次拋擲
flip_coins(10)
## 
## --- 10 Coin Flips Simulation ---
## Heads count: 3, Tails count: 7
## Relative frequency of Heads = 0.3000
## (['tail', 'tail', 'tail', 'tail', 'head', 'tail', 'head', 'head', 'tail', 'tail'], Counter({'tail': 7, 'head': 3}))
# 對應 R 的 Task2: 100 次拋擲及表格計數
flip_coins(100)
## 
## --- 100 Coin Flips Simulation ---
## Heads count: 52, Tails count: 48
## Relative frequency of Heads = 0.5200
## (['head', 'tail', 'head', 'tail', 'head', 'tail', 'head', 'head', 'tail', 'tail', 'head', 'head', 'head', 'head', 'head', 'tail', 'tail', 'tail', 'tail', 'head', 'head', 'head', 'head', 'tail', 'tail', 'head', 'head', 'tail', 'head', 'head', 'head', 'tail', 'tail', 'head', 'tail', 'tail', 'head', 'tail', 'tail', 'tail', 'tail', 'head', 'head', 'tail', 'tail', 'tail', 'head', 'tail', 'head', 'head', 'tail', 'head', 'head', 'tail', 'head', 'head', 'tail', 'tail', 'head', 'head', 'tail', 'tail', 'head', 'head', 'tail', 'head', 'head', 'head', 'head', 'tail', 'tail', 'tail', 'head', 'tail', 'head', 'head', 'head', 'tail', 'tail', 'head', 'tail', 'tail', 'head', 'head', 'tail', 'tail', 'head', 'tail', 'tail', 'head', 'tail', 'head', 'head', 'tail', 'head', 'tail', 'head', 'head', 'tail', 'tail'], Counter({'head': 52, 'tail': 48}))

4.7 範例 7:次品的超幾何概率 (Hypergeometric Probability for Defective Products)

問題設定

  • 總產品數:\(1000\)

  • 次品數:\(3\)

  • 正常產品數:\(1000 - 3 = 997\)

我們在不放回的情況下隨機抽取 \(10\) 件產品。計算兩個概率:

  • 抽出的 10 件物品中完全沒有次品的概率。

  • 抽出的物品中至少有 1 件是次品的概率。

4.7.1 步驟 1:從 1000 件物品中選出 10 件的總方式數

這是一個無序的組合選擇: \[ n(S) = \binom{1000}{10} \]

4.7.2 第 (1) 部分:選出的 10 件中,有零件次品

要得到零件次品,我們必須從 \(997\) 件正常產品中選出所有 \(10\) 件,並從 \(3\) 件次品中選出 \(0\) 件。

事件 \(A_0\)(0 件次品)的有利結果數為: \[ n(A_0) = \binom{997}{10} \times \binom{3}{0} \] 根據經典概率公式: \[ P(A_0) = \frac{\dbinom{997}{10}\dbinom{3}{0}}{\dbinom{1000}{10}} \] 請回想,對於任何整數 \(m\ge0\)\(\dbinom{m}{0}=1\),因此 \(\dbinom{3}{0}=1\),化簡後得: \[ P(A_0) = \frac{\dbinom{997}{10}}{\dbinom{1000}{10}} \]

## [1] 0.9702695

4.7.3 逐步數值化簡 \(P(A_0)\)

展開二項式比例,以避免計算巨大的階乘數值: \[ \begin{aligned} \frac{\dbinom{997}{10}}{\dbinom{1000}{10}} &= \frac{\dfrac{997!}{10!\cdot 987!}}{\dfrac{1000!}{10!\cdot 990!}} \\ &= \frac{997! \cdot 990!}{987! \cdot 1000!} \\ &= \frac{990 \times 989 \times 988}{1000 \times 999 \times 998} \end{aligned} \] 計算步驟算術:

\[ 990 \times 989 \times 988 = 967360680,\quad 1000 \times 999 \times 998 = 997002000 \] \[ P(\text{0 件次品}) = \frac{967360680}{997002000} \approx \boldsymbol{0.9702695} \]

4.7.4 第 (2) 部分:至少選出 1 件次品

設事件 \(B\) = 至少有 1 件次品。

\(B\) 的補集恰好是事件 \(A_0\)(零件次品)。根據補集概率法則: \[ P(B) = 1 - P(A_0) \] 用二項式係數寫出的公式: \[ P(\text{至少 1 件次品}) = 1 - \frac{\dbinom{997}{10}\dbinom{3}{0}}{\dbinom{1000}{10}} \]

## [1] 0.02973045

4.7.5 第 (2) 部分的數值計算

\[ P(\text{至少 1 件次品}) = 1 - 0.9702695 = \boldsymbol{0.0297305} \]

import math

def binom(n, k):
    """二項式係數 C(n,k) = n!/(k! (n-k)!)"""
    if k < 0 or k > n:
        return 0
    return math.factorial(n) // (math.factorial(k) * math.factorial(n - k))

# 給定參數
total = 1000
defective_total = 3
normal_total = total - defective_total
sample_size = 10

# 第 1 部分: 零次品的概率
fav_0_def = binom(normal_total, sample_size) * binom(defective_total, 0)
total_ways = binom(total, sample_size)
p0 = fav_0_def / total_ways

print("=== Part 1: Probability of 0 defective products ===")
## === Part 1: Probability of 0 defective products ===
print(f"C(997,10) = {binom(997,10)}")
## C(997,10) = 255578275196030318119016
print(f"C(3,0) = {binom(3,0)}")
## C(3,0) = 1
print(f"C(1000,10) = {binom(1000,10)}")
## C(1000,10) = 263409560461970212832400
print(f"P(0 defective) = (C(997,10)*C(3,0)) / C(1000,10) = {p0:.7f}\n")
## P(0 defective) = (C(997,10)*C(3,0)) / C(1000,10) = 0.9702695
# 第 2 部分: 至少 1 件次品的概率 (補集法則)
p_at_least_1 = 1 - p0
print("=== Part 2: Probability of at least 1 defective product ===")
## === Part 2: Probability of at least 1 defective product ===
print(f"P(at least 1 defective) = 1 - P(0 defective) = {p_at_least_1:.7f}")
## P(at least 1 defective) = 1 - P(0 defective) = 0.0297305
# 單行 Sage/R 等效計算
sage_line = (binom(997,10)*binom(3,0))/binom(1000,10)
print(f"\nSage one-line calculation match value: {sage_line:.7f}")
## 
## Sage one-line calculation match value: 0.9702695

5 條件概率 (Conditional Probability)

條件概率是數據分析中的一個基礎概念。它表示在已知事件 \(A\) 已經發生的先決條件下,事件 \(B\) 發生的概率。此條件概率記作 \(\boldsymbol{P(B \mid A)}\)

5.1 正式定義

\[ \boldsymbol{P(B \mid A) = \frac{P(A \cap B)}{P(A)} = \frac{P(B \cap A)}{P(A)}},\quad \text{僅在 } P(A) > 0 \text{ 時有效} \] 圖中顯示的符號 \(P_A(B)\)\(P(B\mid A)\) 的等價簡寫。

5.2 由定義推導出的乘法法則 (Product Rule)

重組條件概率公式可得出聯合概率的乘法法則: \[ \boldsymbol{P(A \cap B) = P(A)\,P(B \mid A) = P(B)\,P(A \mid B) = P(B \cap A)} \]

5.3 \(n\) 個事件 \(A_1,A_2,\dots,A_n\) 的廣義乘法法則

\[ \begin{aligned} &P(A_1)\,P(A_2 \mid A_1)\,P(A_3 \mid A_1 \cap A_2)\cdots P(A_n \mid A_1 \cap A_2 \cap \dots \cap A_{n-1}) \\ =\ &P(A_1)\cdot \frac{P(A_1\cap A_2)}{P(A_1)} \cdot \frac{P(A_1\cap A_2\cap A_3)}{P(A_1\cap A_2)} \cdots \frac{P(A_1\cap A_2\cap\dots\cap A_n)}{P(A_1\cap A_2\cap\dots\cap A_{n-1})} \\ =\ &\boldsymbol{P(A_1 \cap A_2 \cap \dots \cap A_n)} \end{aligned} \]

5.4 事件 \(A\) 的補集分割恆等式 (Complement Partition Identity)

對於任何事件 \(A\),不相交的分割成立: \[ A = (A\cap B) \cup (A\cap B^c),\quad (A\cap B)\cap(A\cap B^c)=\emptyset \] 根據不相交集合概率的可加性: \[ P(A) = P(A\cap B) + P(A\cap B^c) \] 重新排列後: \[ \boldsymbol{P(A\cap B) = P(A) - P(A\cap B^c)} \]

5.5 範例 8

給定數值\[ P(A) = \frac{21}{25},\quad P(A\cap B^c) = \frac15 \]

目標:計算 \(P(B \mid A)\)

5.6 步驟 1:將分割恆等式代入條件公式

\[ P(B\mid A) = \frac{P(A\cap B)}{P(A)} = \frac{P(A) - P(A\cap B^c)}{P(A)} \]

5.7 步驟 2:逐步代入數值分數

首先將 \(\frac15\) 轉換為分母 \(25\),以便進行減法: \[ \frac15 = \frac{1\times 5}{5\times 5} = \frac{5}{25} \] 將數值代入分子: \[ P(A)-P(A\cap B^c) = \frac{21}{25} - \frac{5}{25} = \frac{21-5}{25} = \frac{16}{25} \]

5.8 步驟 3:分子除以 \(P(A)\)

\[ P(B\mid A) = \frac{\;\dfrac{16}{25}\;}{\dfrac{21}{25}} \] 共同的分母 \(25\) 可以被抵消: \[ P(B\mid A) = \boldsymbol{\frac{16}{21}} \]

# 輸入給定的概率
P_A = 21 / 25
P_A_intersect_Bcomp = 1 / 5

# 步驟 1: 使用分割恆等式計算 P(A ∩ B)
P_A_intersect_B = P_A - P_A_intersect_Bcomp
print(f"Step 1: P(A ∩ B) = P(A) - P(A ∩ B^c) = {P_A:.4f} - {P_A_intersect_Bcomp:.4f} = {P_A_intersect_B:.4f}")
## Step 1: P(A ∩ B) = P(A) - P(A ∩ B^c) = 0.8400 - 0.2000 = 0.6400
# 步驟 2: 條件概率公式 P(B|A) = P(A∩B)/P(A)
P_B_given_A = P_A_intersect_B / P_A
print(f"Step 2: P(B|A) = P(A∩B) / P(A) = {P_A_intersect_B:.4f} / {P_A:.4f} = {P_B_given_A:.4f}")
## Step 2: P(B|A) = P(A∩B) / P(A) = 0.6400 / 0.8400 = 0.7619
# 精確的分數形式輸出
from fractions import Fraction
frac_PA = Fraction(21,25)
frac_PA_Bc = Fraction(1,5)
frac_PA_B = frac_PA - frac_PA_Bc
frac_result = frac_PA_B / frac_PA

print(f"\nExact fractional answer: P(B|A) = {frac_result}")
## 
## Exact fractional answer: P(B|A) = 16/21

6 貝葉斯定理 (Bayes’ Theorem)

貝葉斯定理透過結合相關條件先驗知識,來計算事件發生的概率。

這個工具對於不確定情況下的數學決策至關重要,並廣泛應用於評估資訊等無形資產的價值。

6.1 關鍵術語定義

  • 先驗概率 (Prior Probability)\(P(A)\) — 在觀察到新數據或證據之前所計算出的事件 \(A\) 的概率。

  • 後驗概率 (Posterior Probability)\(P(A\mid B)\) — 在觀察到新證據/事件 \(B\) 發生後,經過修正和更新的事件 \(A\) 的概率。 在 \(P(A\mid B)\) 中,事件 \(B\) 是觀察到的條件,而 \(P(A\mid B)\) 則是我們在看到 \(B\) 之後對 \(A\) 的信念更新。

貝葉斯定理將已知的先驗概率與觀察到事件的條件似然 (conditional likelihoods) 結合,推導出後驗概率。

6.2 樣本空間的分割與全概率法則 (Law of Total Probability)

假設樣本空間 \(S\) 被分割為不相交的事件 \(A_1,A_2,\dots,A_n\)\[ A_i \cap A_j = \emptyset \quad (i\neq j), \qquad S = A_1 \cup A_2 \cup \dots \cup A_n \] 對於任何任意事件 \(B \subseteq S\)\[ B = S \cap B = \big(A_1\cup A_2\cup\dots\cup A_n\big)\cap B = (A_1\cap B)\cup(A_2\cap B)\cup\dots\cup(A_n\cap B) \] 所有的集合 \(A_i\cap B\) 都是互斥的,所以根據概率的有限可加性: \[ P(B) = P(A_1\cap B)+P(A_2\cap B)+\dots+P(A_n\cap B) \] 應用概率的乘法法則 \(P(A_i\cap B)=P(A_i)\,P(B\mid A_i)\) 得到全概率法則\[ \boldsymbol{P(B) = \sum_{i=1}^n P(A_i)\,P(B\mid A_i)} = P(A_1)P(B\mid A_1)+P(A_2)P(B\mid A_2)+\dots+P(A_n)P(B\mid A_n) \]

6.3 貝葉斯定理公式

由條件概率定義可知: \[ P(A_j \mid B) = \frac{P(A_j \cap B)}{P(B)} \] 代入乘法法則 \(P(A_j\cap B)=P(A_j)P(B\mid A_j)\) 並用全概率取代 \(P(B)\)\[ \boldsymbol{ P(A_j \mid B) = \frac{P(A_j)\,P(B\mid A_j)} {\displaystyle\sum_{i=1}^n P(A_i)\,P(B\mid A_i)} } \]

  • \(P(A_j)\):分割事件 \(A_j\) 的先驗概率

  • \(P(A_j\mid B)\):在觀察到事件 \(B\)\(A_j\) 的後驗概率

6.4 範例 9

問題設定

三個工廠的機器 \(A,B,C\) 分別生產了總產量的 \(50\%,\;30\%,\;20\%\)

次品率為:\(P(\text{次品}\mid A)=0.04,\ P(\text{次品}\mid B)=0.03,\ P(\text{次品}\mid C)=0.02\)

  1. 求隨機選出一件產品為次品的總概率(\(P(X)\),其中 \(X=\) 次品)。

  2. 求一件次品是由機器 \(C\) 生產的後驗概率(\(P(C\mid X)\))。

6.4.1 步驟 1:定義先驗概率

\[ P(A)=0.5,\quad P(B)=0.3,\quad P(C)=0.2 \] 條件次品似然: \[ P(X\mid A)=0.04,\quad P(X\mid B)=0.03,\quad P(X\mid C)=0.02 \]

6.4.2 步驟 2:利用全概率法則求 \(P(X)\)

\[ \begin{aligned} P(X) &= P(A)P(X\mid A)+P(B)P(X\mid B)+P(C)P(X\mid C) \\ &= (0.5 \times 0.04) + (0.3 \times 0.03) + (0.2 \times 0.02) \\ &= 0.02 + 0.009 + 0.004 \\ &= \boldsymbol{0.033} \end{aligned} \]

6.4.3 步驟 3:利用貝葉斯定理求後驗概率 \(P(C\mid X)\)

\[ \begin{aligned} P(C\mid X) &= \frac{P(C)\,P(X\mid C)}{P(A)P(X\mid A)+P(B)P(X\mid B)+P(C)P(X\mid C)} \\ &= \frac{0.2 \times 0.02}{0.033} \\ &= \frac{0.004}{0.033} = \boldsymbol{\frac{4}{33}} \approx 0.1212 \end{aligned} \]

# 使用精確的分數輸入以避免 float → Fraction 轉換誤差
from fractions import Fraction

# 1. 以精確分數表示先驗概率
P_A = Fraction(50, 100)   # 0.5
P_B = Fraction(30, 100)   # 0.3
P_C = Fraction(20, 100)   # 0.2

# 2. 以精確分數表示條件次品率
P_X_given_A = Fraction(4, 100)   # 0.04
P_X_given_B = Fraction(3, 100)   # 0.03
P_X_given_C = Fraction(2, 100)   # 0.02

# 步驟 1: 利用全概率法則求 P(X)
term_A = P_A * P_X_given_A
term_B = P_B * P_X_given_B
term_C = P_C * P_X_given_C
P_X = term_A + term_B + term_C

print("=== Step 1: Total Probability of Defective Product P(X) ===")
## === Step 1: Total Probability of Defective Product P(X) ===
print(f"P(A)·P(X|A) = {float(P_A)} × {float(P_X_given_A)} = {float(term_A)}")
## P(A)·P(X|A) = 0.5 × 0.04 = 0.02
print(f"P(B)·P(X|B) = {float(P_B)} × {float(P_X_given_B)} = {float(term_B)}")
## P(B)·P(X|B) = 0.3 × 0.03 = 0.009
print(f"P(C)·P(X|C) = {float(P_C)} × {float(P_X_given_C)} = {float(term_C)}")
## P(C)·P(X|C) = 0.2 × 0.02 = 0.004
print(f"P(X) = {float(term_A)} + {float(term_B)} + {float(term_C)} = {float(P_X):.4f}\n")
## P(X) = 0.02 + 0.009 + 0.004 = 0.0330
# 步驟 2: 貝葉斯定理求後驗概率 P(C|X)
P_C_given_X = term_C / P_X
frac_result = P_C_given_X  # 已經是精確的 Fraction 對象

print("=== Step 2: Bayes' Theorem P(C|X) ===")
## === Step 2: Bayes' Theorem P(C|X) ===
print(f"P(C|X) = [P(C)·P(X|C)] / P(X) = {float(term_C)} / {float(P_X):.4f} = {float(P_C_given_X):.4f}")
## P(C|X) = [P(C)·P(X|C)] / P(X) = 0.004 / 0.0330 = 0.1212
print(f"Exact fractional value = {frac_result}")
## Exact fractional value = 4/33

7 隨機變量 (Random Variables)

考慮拋擲兩枚公平硬幣的實驗。所有不同結果的樣本空間是: \[ S = \{\,(\text{正面},\text{正面}),\; (\text{正面},\text{反面}),\; (\text{反面},\text{正面}),\; (\text{反面},\text{反面})\,\} \] 對於公平的硬幣拋擲,這個樣本空間中的每一個結果都是等可能的,因此每一個單一結果發生的概率都等於 \(\boldsymbol{\dfrac14}\)

定義 \(X\)兩次硬幣拋擲中觀察到的反面數量。隨機變量 \(X\) 將每一個樣本結果映射為一個實數數值:

  • 結果 \((\text{正面},\text{正面}) \mapsto X = 0\) 個反面

  • 結果 \((\text{正面},\text{反面}),\; (\text{反面},\text{正面}) \mapsto X = 1\) 個反面

  • 結果 \((\text{反面},\text{反面}) \mapsto X = 2\) 個反面

這個映射函數 \(X\) 被定義為一個隨機變量

7.1 隨機變量的概念定義

隨機變量與電腦程式設計中的變數相似,差別在於它的實現值是由概率性機率決定,而非固定賦值。

正式來說,隨機變量是一個函數,它將樣本空間 \(S\) 中的每一個結果(樣本點)映射到實數線 \(\mathbb{R}\) 上的一個實數。

使用隨機變量可以將定性的概率事件轉換為定量的數值,這簡化了隨機實驗的計算、比較和統計分析。

符號慣例:

  • 大寫字母(例如 \(X,Y,Z\)):表示隨機變量函數本身

  • 小寫字母(例如 \(x,y,z\)):表示隨機變量可能取到的特定數值

7.1.1 逐步計算 \(X\)(兩次拋擲硬幣中的反面數量)的概率質量

總等可能樣本結果:\(n(S)=4\),每一個的概率為 \(\frac14\)

7.1.2 驗證總概率和為 1

所有互斥的 \(X\) 可能數值涵蓋了完整的樣本空間: \[ P(X=0)+P(X=1)+P(X=2) = \frac14 + \frac12 + \frac14 = \frac{1+2+1}{4} = \frac44 = \boldsymbol{1} \]

# 兩次拋硬幣的樣本空間
sample_space = [("H","H"), ("H","T"), ("T","H"), ("T","T")]
total_outcomes = len(sample_space)

# 定義隨機變量 X: 計算每個結果中的反面數量 (T)
def count_tails(outcome):
    return outcome.count("T")

# 計算每個可能的 X 值 (0,1,2) 的概率質量
pmf = {0:0, 1:0, 2:0}
for outcome in sample_space:
    x_val = count_tails(outcome)
    pmf[x_val] += 1

# 將計數轉換為概率
for x in pmf:
    pmf[x] = pmf[x] / total_outcomes

# 印出逐步明細
print("=== Random Variable X = Number of Tails in 2 Coin Flips ===")
## === Random Variable X = Number of Tails in 2 Coin Flips ===
print(f"Total sample outcomes = {total_outcomes}\n")
## Total sample outcomes = 4
for x in sorted(pmf.keys()):
    count = pmf[x] * total_outcomes
    prob = pmf[x]
    print(f"X = {x}: {count} favorable outcomes, P(X={x}) = {count}/{total_outcomes} = {prob:.2f}")
## X = 0: 1.0 favorable outcomes, P(X=0) = 1.0/4 = 0.25
## X = 1: 2.0 favorable outcomes, P(X=1) = 2.0/4 = 0.50
## X = 2: 1.0 favorable outcomes, P(X=2) = 1.0/4 = 0.25
# 驗證總概率和為 1
total_prob = sum(pmf.values())
print(f"\nTotal sum of all probabilities = {total_prob}")
## 
## Total sum of all probabilities = 1.0
# 2. 蒙地卡羅模擬 (針對隨機變量分佈進行經驗測試)
import random
def flip_two_coins():
    coin1 = random.choice(["H","T"])
    coin2 = random.choice(["H","T"])
    return (coin1, coin2)

simulation_trials = 10000
sim_counts = {0:0,1:0,2:0}
for _ in range(simulation_trials):
    res = flip_two_coins()
    sim_x = count_tails(res)
    sim_counts[sim_x] += 1

print(f"\n=== Monte Carlo Simulation ({simulation_trials} trials) ===")
## 
## === Monte Carlo Simulation (10000 trials) ===
for x in sorted(sim_counts.keys()):
    sim_prob = sim_counts[x] / simulation_trials
    print(f"Simulated P(X={x}) ≈ {sim_prob:.4f}")
## Simulated P(X=0) ≈ 0.2535
## Simulated P(X=1) ≈ 0.5031
## Simulated P(X=2) ≈ 0.2434

8 離散概率分佈 (Discrete Probability Distributions)

一個離散隨機變量 \(X\) 是一個只能取可數的相異實數值集合 \(x_1,\,x_2,\,\dots,\,x_n\) 的隨機變量。

一個離散概率分佈完整地說明了離散隨機變量 \(X\) 針對每一個可能數值 \(x_i\) 發生的概率 \(P(X=x_i)\)

8.1 離散分佈的表格形式

\[ \begin{array}{l|cccc|c} X & x_1 & x_2 & \dots & x_n & \textrm{總和} \\ \hline \textrm{概率} & P(X=x_1) & P(X=x_2) & \dots & P(X=x_n) & 1 \end{array} \]

8.2 說明範例:拋擲兩次硬幣(計算反面數 \(X\)

實驗:同時拋擲兩枚公平的硬幣。\(X\) = 觀察到的反面數量。

樣本空間:\(S=\{(H,H),(H,T),(T,H),(T,T)\}\),每個結果發生的概率均等,為 \(\tfrac14\)

逐步映射與概率計算:

8.3 概率質量函數 (PMF) 定義

將概率值 \(P(X=x_i)\) 賦予 \(X\) 的每一個可能離散值 \(x_i\) 的函數 \(f(x)\),被稱為 \(X\)概率質量函數 (probability mass function, pmf)\[ f(x) = \begin{cases} P(X=x_i) & \text{對於 } x = x_1,\,x_2,\,\dots,\,x_n \\ 0 & \text{對於所有其他實數 } x \end{cases} \]

8.3.1 PMF 的三個基本性質

8.3.2 兩次拋硬幣範例 PMF 的驗證

PMF 數值:\(f(0)=\tfrac14,\ f(1)=\tfrac12,\ f(2)=\tfrac14\)

  1. 邊界檢查:\(0<\tfrac14<1,\ 0<\tfrac12<1,\ 0<\tfrac14<1\)(滿足性質 1)

  2. 總和: \[ f(0)+f(1)+f(2) = \frac14+\frac12+\frac14 = \frac{1+2+1}{4} = \frac44 = \boldsymbol{1} \]

  3. 區間計算範例:\(P(0\le X \le 1)\) \[ P(0\le X \le 1) = f(0)+f(1) = \frac14+\frac12 = \frac34 \]

# 離散隨機變量 X: 兩次拋硬幣的反面數量
# 定義可能的 x 值及其 pmf f(x)
x_values = [0, 1, 2]
pmf_vals = [1/4, 1/2, 1/4]

# 儲存為字典以方便查找
pmf = dict(zip(x_values, pmf_vals))

print("=== Discrete PMF for X = Number of Tails (2 coin tosses) ===")
## === Discrete PMF for X = Number of Tails (2 coin tosses) ===
for x, fx in pmf.items():
    print(f"f({x}) = P(X={x}) = {fx:.2f}")
## f(0) = P(X=0) = 0.25
## f(1) = P(X=1) = 0.50
## f(2) = P(X=2) = 0.25
# 性質 1: 檢查對所有 x 是否滿足 0 ≤ f(x) ≤ 1
print("\n--- Property 1 Check (0 ≤ f(x) ≤ 1) ---")
## 
## --- Property 1 Check (0 ≤ f(x) ≤ 1) ---
prop1_ok = True
for x, fx in pmf.items():
    if not (0 <= fx <= 1):
        prop1_ok = False
        print(f"ERROR: f({x}) = {fx} out of bounds")
if prop1_ok:
    print("All pmf values satisfy 0 ≤ f(x) ≤ 1")
## All pmf values satisfy 0 ≤ f(x) ≤ 1
# 性質 2: 總和 f(x) = 1
total_mass = sum(pmf_vals)
print(f"\n--- Property 2 Check (Total sum = 1) ---")
## 
## --- Property 2 Check (Total sum = 1) ---
print(f"Sum f(x) = {total_mass}")
## Sum f(x) = 1.0
# 性質 3: 計算區間概率 P(a ≤ X ≤ b)
def prob_interval(a, b, pmf_dict):
    total = 0.0
    for x, fx in pmf_dict.items():
        if a <= x <= b:
            total += fx
    return total

p_0to1 = prob_interval(0, 1, pmf)
print(f"\n--- Property3 Example: P(0 ≤ X ≤ 1) = {p_0to1:.2f}")
## 
## --- Property3 Example: P(0 ≤ X ≤ 1) = 0.75
# 第 2 部分: 蒙地卡羅模擬以逼近 PMF
import random
def flip_two():
    c1 = random.choice(["H","T"])
    c2 = random.choice(["H","T"])
    return (c1,c2)

def count_tails(outcome):
    return outcome.count("T")

trials = 20000
sim_counts = {0:0,1:0,2:0}
for _ in range(trials):
    res = flip_two()
    x_sim = count_tails(res)
    sim_counts[x_sim] +=1

print(f"\n=== Monte Carlo Simulation ({trials} trials) ===")
## 
## === Monte Carlo Simulation (20000 trials) ===
for x in sorted(sim_counts.keys()):
    sim_prob = sim_counts[x] / trials
    print(f"Simulated f({x}) ≈ {sim_prob:.4f}, Theoretical f({x}) = {pmf[x]:.2f}")
## Simulated f(0) ≈ 0.2487, Theoretical f(0) = 0.25
## Simulated f(1) ≈ 0.5006, Theoretical f(1) = 0.50
## Simulated f(2) ≈ 0.2507, Theoretical f(2) = 0.25

9 連續概率分佈 (Continuous Probability Distributions)

一個連續隨機變量 \(X\) 是一個可以取不可數的無限多個實數值集合的隨機變量。

對於任何連續隨機變量,\(X\) 等於單一個確切點數值 \(x\) 的概率永遠為零: \[ \boldsymbol{P(X = x) = 0} \] 因為單點的概率為零,離散的概率質量函數 (pmf) 無法用來描述連續分佈。取而代之的是,我們引入概率密度函數 (probability density function, pdf),記作 \(f(x)\),來對連續概率行為建立模型。

pdf \(f(x)\) 是離散 pmf 的連續對應物。如果一個函數 \(f(x)\) 滿足三個核心性質,那麼它就有資格成為連續隨機變量 \(X\) 的有效概率密度函數:

9.1 區間概率的圖形詮釋

概率 \(P(a\le X\le b)\) 在幾何上對應於 pdf 曲線 \(y=f(x)\) 與垂直線 \(x=a\)\(x=b\) 之間的面積。

9.2 備註:PDF 中「密度 (Density)」的語源

我們將概率解釋為質量,將區間長度解釋為一維體積:

  • 比例:\(\dfrac{\text{概率}}{\text{區間長度}} = \dfrac{\text{質量}}{\text{體積}}\)

  • 比例 \(\frac{\text{質量}}{\text{體積}}\) 也就是物理密度的標準定義。

  • 重新排列關係: \[ \left(\frac{\text{概率}}{\text{區間長度}}\right) \times (\text{區間長度}) = \text{概率} \] 將密度(單位長度的概率)乘以區間長度就能產生該區段的總概率。這種關係這就是概率密度函數這個名稱的由來。

9.3 步驟驗證範例(均勻連續分佈測試)

採用 \([0,2]\) 上的均勻 pdf: \[ f(x) = \begin{cases} \frac12 & 0 \le x \le 2 \\ 0 & \text{其他情況} \end{cases} \]

  1. 性質 1 檢查:對所有實數 \(x\) 皆有 \(f(x)\ge0\)(在支撐集上為 \(\tfrac12>0\),外部為 \(0\)

  2. 性質 2 總積分: \[ \int_{-\infty}^{\infty}f(x)dx = \int_0^2 \frac12 dx = \frac12 \big[x\big]_0^2 = \frac12(2-0) = \boldsymbol{1} \]

  3. 區間概率範例:\(P(0.5 \le X \le 1.5)\) \[ P(0.5\le X\le1.5) = \int_{0.5}^{1.5}\frac12 dx = \frac12(1.5-0.5) = \boldsymbol{0.5} \] 同時確認 \(P(X=1)=0\)(單點積分 \(\displaystyle \int_1^1 \tfrac12 dx =0\)

import sympy as sp
import scipy.integrate as spi
import numpy as np

# 符號變數
x = sp.Symbol('x', real=True)

# 定義均勻 pdf f(x) = 1/2 若 0<=x<=2,否則為 0
def f_sym(x_val):
    if 0 <= x_val <= 2:
        return sp.Rational(1,2)
    else:
        return 0

# 轉換為分段的 sympy 表達式
f = sp.Piecewise((sp.Rational(1,2), (x >= 0) & (x <= 2)), (0, True))

print("=== Step 1: Verify PDF Property 1 (f(x) ≥ 0 for all real x) ===")
## === Step 1: Verify PDF Property 1 (f(x) ≥ 0 for all real x) ===
# 測試支撐集內部與外部的樣本點
test_points = [-1, 0, 1, 2, 3]
for xi in test_points:
    fx_val = float(f.subs(x, xi))
    print(f"f({xi}) = {fx_val}, non-negative? {fx_val >= 0}")
## f(-1) = 0.0, non-negative? True
## f(0) = 0.5, non-negative? True
## f(1) = 0.5, non-negative? True
## f(2) = 0.5, non-negative? True
## f(3) = 0.0, non-negative? True
# FIX 1: 移除所有的 Unicode ∞,僅使用純 ASCII "inf" 文字
print("\n=== Step 2: Verify PDF Property 2 (Integral from -inf to inf = 1) ===")
## 
## === Step 2: Verify PDF Property 2 (Integral from -inf to inf = 1) ===
total_integral = sp.integrate(f, (x, -sp.oo, sp.oo))
print(f"Integral from -inf to inf of f(x) dx = {total_integral}")
## Integral from -inf to inf of f(x) dx = 1
print("\n=== Step3: Verify Interval Probability P(0.5 ≤ X ≤1.5) ===")
## 
## === Step3: Verify Interval Probability P(0.5 ≤ X ≤1.5) ===
interval_int = sp.integrate(f, (x, 0.5, 1.5))
print(f"P(0.5 ≤ X ≤1.5) = Integral from 0.5 to 1.5 of f(x) dx = {float(interval_int)}")
## P(0.5 ≤ X ≤1.5) = Integral from 0.5 to 1.5 of f(x) dx = 0.5
# 驗證單點概率 P(X=1)=0
point_int = sp.integrate(f, (x, 1, 1))
print(f"\nSingle point integral P(X=1) = Integral from 1 to 1 of f(x) dx = {point_int}")
## 
## Single point integral P(X=1) = Integral from 1 to 1 of f(x) dx = 0
# 2. 一般連續 PDF 的數值積分
def pdf_uniform(x_num):
    return 0.5 if (0 <= x_num <=2) else 0

num_total, err_total = spi.quad(pdf_uniform, -np.inf, np.inf)
num_interval, err_int = spi.quad(pdf_uniform, 0.5, 1.5)

print("\n=== Numerical Integration Confirmation ===")
## 
## === Numerical Integration Confirmation ===
print(f"Numerical total integral = {num_total:.4f}")
## Numerical total integral = 1.0000
print(f"Numerical P(0.5 ≤ X ≤1.5) = {num_interval:.4f}")
## Numerical P(0.5 ≤ X ≤1.5) = 0.5000
# 3. 繪製 PDF 曲線及陰影區間面積
import matplotlib.pyplot as plt

xs = np.linspace(-0.5, 2.5, 1000)
ys = np.array([pdf_uniform(t) for t in xs])

plt.figure(figsize=(8,4))
## <Figure size 800x400 with 0 Axes>
# FIX 2: 將 LaTeX \frac 替換為純 ASCII 文字標籤以避免解析錯誤
plt.plot(xs, ys, color='darkblue', linewidth=2, label='f(x)=1/2, 0 ≤ x ≤ 2')
## [<matplotlib.lines.Line2D object at 0x000002BFEF8B5430>]
# 陰影 0.5 至 1.5
x_fill = np.linspace(0.5,1.5,500)
y_fill = np.array([pdf_uniform(t) for t in x_fill])
plt.fill_between(x_fill, y_fill, color='cyan', alpha=0.4, label='P(0.5 ≤ X ≤ 1.5)')
## <matplotlib.collections.FillBetweenPolyCollection object at 0x000002BFEF8AED50>
plt.axvline(x=0.5, linestyle='--', color='gray')
## <matplotlib.lines.Line2D object at 0x000002BFEF8B7500>
plt.axvline(x=1.5, linestyle='--', color='gray')
## <matplotlib.lines.Line2D object at 0x000002BFADBD9CA0>
plt.xlabel('x')
## Text(0.5, 0, 'x')
plt.ylabel('f(x)')
## Text(0, 0.5, 'f(x)')
plt.legend()
## <matplotlib.legend.Legend object at 0x000002BFEF8B6C60>
plt.grid(alpha=0.3)
plt.title('Uniform Continuous Probability Density Function')
## Text(0.5, 1.0, 'Uniform Continuous Probability Density Function')
plt.show()