香港中文大學數學系
2026年6月27日
兩種核心的計數技巧是排列和組合。排列 (permutation) 計算的是順序重要時的不同排列方式的數量。
我們有五張不同的卡片,分別標示為 \(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、3:
根據計數的乘法原理,將每個位置的選擇數量相乘: \[ \text{總有序結果數量} = 5 \times 4 \times 3 = \boldsymbol{60} \]
從 \(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\) 階乘」)。
將分子和分母同時乘以尾部乘積 \((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} \]
\[\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
##
## 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
組合 (combination) 計算的是順序不重要時選擇項目的方式數量。
直接計算: \[ \frac{5 \times 4 \times 3}{3!} = 10 \]
假設選出的數值為 \(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!\)。
分子 \(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!} \]
\[\begin{align*} 3! &= 3\times2\times1 = 6 \\ 5\times4\times3 &= 60 \\ \frac{60}{6} &= \boldsymbol{10} \end{align*}\]
當從 \(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 \]
問題:找出從總共 500 條領帶中無序挑選 5 條領帶的方式數量。 根據組合公式,\(n=500,\;k=5\): \[ \binom{500}{5} = \frac{500!}{5!\cdot (500-5)!} = \frac{500!}{5!\cdot 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} \]
分子乘積: \[ 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 =====
##
## === 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
## Answer (unordered card groups): 10
## ===== Test 2: Pick 5 unordered ties from 500 =====
##
## === 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
## 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
## C(500,5) (tie selections) = 255244687600
在數學上,這個表達式代表二項式係數: \[ \binom{500}{5} \]
這些計算也可以使用 R 的內建指令來求二項式係數:
## binomial(500,5) = 255244687600
到目前為止,我們涵蓋了不可重複選擇的計數問題。當允許重複選擇項目時,我們對允許重複的排列和組合使用不同的公式。
\({}_n \Pi_k\) 表示從 \(n\) 種不同的類型中有順序地選擇 \(k\) 個項目,其中項目可以被重複使用(允許重複)。 \[ \boldsymbol{{}_n \Pi_k = n^k} \]
\({}_n H_k\) 表示從 \(n\) 種不同的類型中無序選擇 \(k\) 個項目,其中項目可以被重複使用(允許重複)。 該公式可以轉換為標準的二項式係數: \[ \boldsymbol{{}_n H_k = \binom{n+k-1}{k}} \]
從 \(\{1,2,3,4,5\}\) 中選擇三個數字,將它們按順序排列形成三位的自然數(允許重複)。 求有多少個這樣的三位數是 \(5\) 的倍數。
如果一個自然數的個位數是 \(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}\)
四個人對三位候選人 A、B、C 進行不記名投票。求總共有多少種不同的投票結果分佈。
投票是不記名的,因此只有每位候選人獲得的票數才重要(投票者的順序不重要)。這是一個允許重複的組合情況:
\(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
## ===== Example 3: Three-digit multiples of 5 =====
##
## Permutation with repetition _5Π_2 = 5^2
## 5 × 5 × ... (2 times) = 25
## Total valid numbers = 25
## ===== Example 4: Anonymous vote distributions =====
##
## 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
## 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
## Example3 (3-digit multiples of 5): 25
## Example4 (4 votes,3 candidates): 15
特定事件發生的概率取值在區間 \([0,1]\) 內。例如,擲一枚公平的硬幣,出現正面的概率為 \(\frac12\)。
當拋擲一枚硬幣時,只存在兩種結果:正面或反面。總共有 \(2\) 種可能的結果,而符合正面的結果恰好有 \(1\) 種。
概率值為 \(0\) 表示事件不可能發生(絕對不會發生)。
概率值為 \(1\) 表示事件必然發生(一定會發生)。
要在數學上計算概率,我們首先要定義所有可能結果的完整集合。
拋硬幣的樣本空間:\(S=\{\text{正面},\text{反面}\}\)
標準六面骰子的樣本空間:\(S=\{1,2,3,4,5,6\}\)
這個所有可能結果的完整集合被稱為樣本空間 (sample space),記作 \(S\)。
假設:
\(n(S) =\) 樣本空間 \(S\) 中不同可能結果的總數
\(n(A) =\) 特定事件 \(A\) 的有利(符合條件)結果的數量
事件 \(A\) 的經典概率,記為 \(P(A)\),定義為: \[ P(A) = \frac{\text{事件 }A\text{ 的有利結果數量}}{\text{所有可能結果的總數}} = \boldsymbol{\frac{n(A)}{n(S)}} \]
對於幾何問題,其中 \(S\) 代表總區域/面積,且 \(A\subset S\)(事件區域完全位於樣本空間區域內): \[ P(A) = \boldsymbol{\frac{\text{區域 }A\text{ 的面積}}{\text{區域 }S\text{ 的面積}}} \]
在實際的實驗試驗中:
假設一個相同的試驗總共重複了 \(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)} \]
設 \(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)} \]
\[\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*}\]
\[\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 =====
##
## Classical Probability Calculation:
## n(A) (favorable outcomes) = 1
## n(S) (total sample space outcomes) = 2
## P(A) = 1 / 2 = 0.5000
##
## 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 =====
##
## Classical Probability Calculation:
## n(A) (favorable outcomes) = 1
## n(S) (total sample space outcomes) = 6
## P(A) = 1 / 6 = 0.1667
##
## 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 =====
##
## 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
## P(Die roll 3) = 0.1667
## P(Geometric shaded region) = 0.25
問題描述:一個袋子裡裝有 3 個黑球、2 個白球和 1 個紅球(總共有 \(3+2+1=6\) 個球)。隨機同時抽出兩個球。計算選出的這兩個球顏色相同的概率。
同時抽出兩個球是一種無序選擇,因此我們使用組合 \(\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*}\]
只有黑色和白色至少有兩個球;紅球只有 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 個白球的方式數:\(\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} \]
\[ \frac{\binom{3}{2} + \binom{2}{2}}{\binom{6}{2}} \]
我們使用 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
## White pairs C(2,2) = 1
## 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}))
##
## --- 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}))
問題設定:
總產品數:\(1000\)
次品數:\(3\)
正常產品數:\(1000 - 3 = 997\)
我們在不放回的情況下隨機抽取 \(10\) 件產品。計算兩個概率:
抽出的 10 件物品中完全沒有次品的概率。
抽出的物品中至少有 1 件是次品的概率。
這是一個無序的組合選擇: \[ n(S) = \binom{1000}{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
展開二項式比例,以避免計算巨大的階乘數值: \[ \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} \]
設事件 \(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
\[ 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 ===
## C(997,10) = 255578275196030318119016
## C(3,0) = 1
## C(1000,10) = 263409560461970212832400
## 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 ===
## 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
條件概率是數據分析中的一個基礎概念。它表示在已知事件 \(A\) 已經發生的先決條件下,事件 \(B\) 發生的概率。此條件概率記作 \(\boldsymbol{P(B \mid A)}\)。
\[ \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)\) 的等價簡寫。
重組條件概率公式可得出聯合概率的乘法法則: \[ \boldsymbol{P(A \cap B) = P(A)\,P(B \mid A) = P(B)\,P(A \mid B) = P(B \cap A)} \]
\[ \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} \]
對於任何事件 \(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)} \]
給定數值: \[ P(A) = \frac{21}{25},\quad P(A\cap B^c) = \frac15 \]
目標:計算 \(P(B \mid A)\)
\[ P(B\mid A) = \frac{P(A\cap B)}{P(A)} = \frac{P(A) - P(A\cap B^c)}{P(A)} \]
首先將 \(\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} \]
\[ 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
貝葉斯定理透過結合相關條件先驗知識,來計算事件發生的概率。
這個工具對於不確定情況下的數學決策至關重要,並廣泛應用於評估資訊等無形資產的價值。
先驗概率 (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) 結合,推導出後驗概率。
假設樣本空間 \(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) \]
由條件概率定義可知: \[ 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\) 的後驗概率
問題設定:
三個工廠的機器 \(A,B,C\) 分別生產了總產量的 \(50\%,\;30\%,\;20\%\)。
次品率為:\(P(\text{次品}\mid A)=0.04,\ P(\text{次品}\mid B)=0.03,\ P(\text{次品}\mid C)=0.02\)。
求隨機選出一件產品為次品的總概率(\(P(X)\),其中 \(X=\) 次品)。
求一件次品是由機器 \(C\) 生產的後驗概率(\(P(C\mid X)\))。
\[ 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 \]
\[ \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} \]
\[ \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) ===
## P(A)·P(X|A) = 0.5 × 0.04 = 0.02
## P(B)·P(X|B) = 0.3 × 0.03 = 0.009
## P(C)·P(X|C) = 0.2 × 0.02 = 0.004
## 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
## Exact fractional value = 4/33
考慮拋擲兩枚公平硬幣的實驗。所有不同結果的樣本空間是: \[ 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\) 被定義為一個隨機變量。
隨機變量與電腦程式設計中的變數相似,差別在於它的實現值是由概率性機率決定,而非固定賦值。
正式來說,隨機變量是一個函數,它將樣本空間 \(S\) 中的每一個結果(樣本點)映射到實數線 \(\mathbb{R}\) 上的一個實數。
使用隨機變量可以將定性的概率事件轉換為定量的數值,這簡化了隨機實驗的計算、比較和統計分析。
符號慣例:
大寫字母(例如 \(X,Y,Z\)):表示隨機變量函數本身
小寫字母(例如 \(x,y,z\)):表示隨機變量可能取到的特定數值
所有互斥的 \(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 ===
## 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
一個離散隨機變量 \(X\) 是一個只能取可數的相異實數值集合 \(x_1,\,x_2,\,\dots,\,x_n\) 的隨機變量。
一個離散概率分佈完整地說明了離散隨機變量 \(X\) 針對每一個可能數值 \(x_i\) 發生的概率 \(P(X=x_i)\)。
\[ \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} \]
實驗:同時拋擲兩枚公平的硬幣。\(X\) = 觀察到的反面數量。
樣本空間:\(S=\{(H,H),(H,T),(T,H),(T,T)\}\),每個結果發生的概率均等,為 \(\tfrac14\)。
逐步映射與概率計算:將概率值 \(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} \]
PMF 數值:\(f(0)=\tfrac14,\ f(1)=\tfrac12,\ f(2)=\tfrac14\)
邊界檢查:\(0<\tfrac14<1,\ 0<\tfrac12<1,\ 0<\tfrac14<1\)(滿足性質 1)
總和: \[ f(0)+f(1)+f(2) = \frac14+\frac12+\frac14 = \frac{1+2+1}{4} = \frac44 = \boldsymbol{1} \]
區間計算範例:\(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) ===
## f(0) = P(X=0) = 0.25
## f(1) = P(X=1) = 0.50
## f(2) = P(X=2) = 0.25
##
## --- 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
##
## --- Property 2 Check (Total sum = 1) ---
## 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
一個連續隨機變量 \(X\) 是一個可以取不可數的無限多個實數值集合的隨機變量。
對於任何連續隨機變量,\(X\) 等於單一個確切點數值 \(x\) 的概率永遠為零: \[ \boldsymbol{P(X = x) = 0} \] 因為單點的概率為零,離散的概率質量函數 (pmf) 無法用來描述連續分佈。取而代之的是,我們引入概率密度函數 (probability density function, pdf),記作 \(f(x)\),來對連續概率行為建立模型。
pdf \(f(x)\) 是離散 pmf 的連續對應物。如果一個函數 \(f(x)\) 滿足三個核心性質,那麼它就有資格成為連續隨機變量 \(X\) 的有效概率密度函數:
我們將概率解釋為質量,將區間長度解釋為一維體積:
比例:\(\dfrac{\text{概率}}{\text{區間長度}} = \dfrac{\text{質量}}{\text{體積}}\)
比例 \(\frac{\text{質量}}{\text{體積}}\) 也就是物理密度的標準定義。
重新排列關係: \[ \left(\frac{\text{概率}}{\text{區間長度}}\right) \times (\text{區間長度}) = \text{概率} \] 將密度(單位長度的概率)乘以區間長度就能產生該區段的總概率。這種關係這就是概率密度函數這個名稱的由來。
採用 \([0,2]\) 上的均勻 pdf: \[ f(x) = \begin{cases} \frac12 & 0 \le x \le 2 \\ 0 & \text{其他情況} \end{cases} \]
性質 1 檢查:對所有實數 \(x\) 皆有 \(f(x)\ge0\)(在支撐集上為 \(\tfrac12>0\),外部為 \(0\))
性質 2 總積分: \[ \int_{-\infty}^{\infty}f(x)dx = \int_0^2 \frac12 dx = \frac12 \big[x\big]_0^2 = \frac12(2-0) = \boldsymbol{1} \]
區間概率範例:\(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
##
## === 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 ===
## Numerical total integral = 1.0000
## 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>
## <matplotlib.lines.Line2D object at 0x000002BFEF8B7500>
## <matplotlib.lines.Line2D object at 0x000002BFADBD9CA0>
## Text(0.5, 0, 'x')
## Text(0, 0.5, 'f(x)')
## <matplotlib.legend.Legend object at 0x000002BFEF8B6C60>
## Text(0.5, 1.0, 'Uniform Continuous Probability Density Function')