用 Python 模擬囚徒困境:從海洋生態合作到遊戲理論哲學 (上)

更新於 發佈於 閱讀時間約 28 分鐘

前言:當演算法遇見海洋智慧

在臺灣周圍的海域中,珊瑚與藻類進行著一場古老的合作遊戲。牠們面臨著一個經典的選擇:是要無私地分享資源,還是自私地獨占養分?這個看似簡單的生態互動,實際上蘊含著深刻的遊戲理論智慧——囚徒困境(Prisoner's Dilemma)。

今天,我們將用 Python 來模擬這個經典的哲學問題,從海洋生態的角度重新審視合作與競爭的本質,並探討其背後的哲學意涵。



第一章:囚徒困境的核心邏輯

1.1 經典囚徒困境

囚徒困境是博弈論中的經典案例。兩名囚犯被分別審訊,他們可以選擇「合作」(保持沉默)或「背叛」(指證對方)。每個人的最佳策略取決於對方的選擇,但理性的個體決策往往導致雙輸的結果。

讓我們用 Python 來建立基本的囚徒困境模型:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from collections import defaultdict
import random

class PrisonersDilemma:
"""囚徒困境遊戲類別"""

def __init__(self):
# 收益矩陣:(玩家1收益, 玩家2收益)
# 策略:0=合作(C), 1=背叛(D)
self.payoff_matrix = {
(0, 0): (3, 3), # 雙方合作:中等收益
(0, 1): (0, 5), # 自己合作,對方背叛:自己受損
(1, 0): (5, 0), # 自己背叛,對方合作:自己得利
(1, 1): (1, 1) # 雙方背叛:雙輸
}

def play_round(self, strategy1, strategy2):
"""進行一輪遊戲"""
return self.payoff_matrix[(strategy1, strategy2)]

def get_payoff_description(self, s1, s2):
"""取得策略組合的描述"""
strategies = {0: "合作", 1: "背叛"}
return f"玩家1: {strategies[s1]}, 玩家2: {strategies[s2]}"

# 示例:基本遊戲
game = PrisonersDilemma()
print("囚徒困境收益矩陣:")
print("=" * 40)
for (s1, s2), (p1, p2) in game.payoff_matrix.items():
desc = game.get_payoff_description(s1, s2)
print(f"{desc} -> 收益: ({p1}, {p2})")

1.2 海洋生態中的囚徒困境

在海洋生態系統中,我們可以觀察到許多類似囚徒困境的現象:

清潔魚與宿主魚的互動

  • 合作:清潔魚專心清除寄生蟲,宿主魚保持靜止
  • 背叛:清潔魚咬食宿主的健康組織,或宿主魚突然游走

珊瑚與共生藻的關係

  • 合作:珊瑚提供庇護,共生藻進行光合作用分享養分
  • 背叛:任一方過度消耗資源而不給予回報



第二章:Python 實作海洋生態囚徒困境

2.1 海洋生物策略模擬

讓我們創建一個模擬海洋生物互動的進階模型:

class MarineCreature:
"""海洋生物基類"""

def __init__(self, name, strategy_type="random"):
self.name = name
self.strategy_type = strategy_type
self.total_payoff = 0
self.interaction_history = []
self.reputation = 0.5 # 信譽值:0-1之間

def choose_strategy(self, opponent_history, current_round):
"""根據策略類型選擇行動"""
if self.strategy_type == "always_cooperate":
return 0 # 總是合作
elif self.strategy_type == "always_defect":
return 1 # 總是背叛
elif self.strategy_type == "tit_for_tat":
# 以牙還牙:第一輪合作,之後模仿對手上一輪行為
if current_round == 0 or len(opponent_history) == 0:
return 0
return opponent_history[-1]
elif self.strategy_type == "tit_for_two_tats":
# 雙重以牙還牙:對手連續背叛兩次才報復
if len(opponent_history) < 2:
return 0
if opponent_history[-1] == 1 and opponent_history[-2] == 1:
return 1
return 0
elif self.strategy_type == "generous_tit_for_tat":
# 寬容的以牙還牙:有機率原諒對手的背叛
if current_round == 0 or len(opponent_history) == 0:
return 0
if opponent_history[-1] == 1:
return 1 if random.random() > 0.1 else 0 # 90%機率報復
return 0
else: # random
return random.choice([0, 1])

def update_reputation(self, own_action, opponent_action):
"""更新信譽值"""
if own_action == 0: # 合作
self.reputation = min(1.0, self.reputation + 0.01)
else: # 背叛
self.reputation = max(0.0, self.reputation - 0.02)

class MarineEcosystemSimulation:
"""海洋生態系統模擬"""

def __init__(self):
self.game = PrisonersDilemma()
self.creatures = []
self.simulation_history = []

def add_creature(self, creature):
"""添加海洋生物"""
self.creatures.append(creature)

def simulate_interaction(self, creature1, creature2, rounds=100):
"""模擬兩個生物之間的互動"""
history1, history2 = [], []
payoffs1, payoffs2 = [], []

for round_num in range(rounds):
# 選擇策略
action1 = creature1.choose_strategy(history2, round_num)
action2 = creature2.choose_strategy(history1, round_num)

# 計算收益
payoff1, payoff2 = self.game.play_round(action1, action2)

# 更新記錄
history1.append(action1)
history2.append(action2)
payoffs1.append(payoff1)
payoffs2.append(payoff2)

# 更新總收益和信譽
creature1.total_payoff += payoff1
creature2.total_payoff += payoff2
creature1.update_reputation(action1, action2)
creature2.update_reputation(action2, action1)

# 儲存互動歷史
interaction_record = {
'creature1': creature1.name,
'creature2': creature2.name,
'strategy1': creature1.strategy_type,
'strategy2': creature2.strategy_type,
'history1': history1,
'history2': history2,
'payoffs1': payoffs1,
'payoffs2': payoffs2,
'cooperation_rate1': history1.count(0) / len(history1),
'cooperation_rate2': history2.count(0) / len(history2),
'total_payoff1': sum(payoffs1),
'total_payoff2': sum(payoffs2),
'final_reputation1': creature1.reputation,
'final_reputation2': creature2.reputation
}

self.simulation_history.append(interaction_record)
return interaction_record

# 創建海洋生態系統模擬
ecosystem = MarineEcosystemSimulation()

# 創建不同策略的海洋生物
creatures = [
MarineCreature("善良珊瑚", "always_cooperate"),
MarineCreature("自私海葵", "always_defect"),
MarineCreature("聰明清潔魚", "tit_for_tat"),
MarineCreature("寬容海龜", "generous_tit_for_tat"),
MarineCreature("謹慎小丑魚", "tit_for_two_tats"),
MarineCreature("隨機水母", "random")
]

for creature in creatures:
ecosystem.add_creature(creature)

print("海洋生態系統中的生物:")
for creature in creatures:
print(f"- {creature.name} ({creature.strategy_type})")



2.2 大規模生態競賽模擬

def run_ecosystem_tournament(ecosystem, rounds_per_match=100):
"""執行生態系統錦標賽"""
print(f"\n開始海洋生態錦標賽(每場對戰 {rounds_per_match} 輪)...")
print("=" * 60)

# 重置所有生物的總收益
for creature in ecosystem.creatures:
creature.total_payoff = 0
creature.reputation = 0.5

# 每對生物都進行對戰
match_count = 0
for i in range(len(ecosystem.creatures)):
for j in range(i + 1, len(ecosystem.creatures)):
creature1 = ecosystem.creatures[i]
creature2 = ecosystem.creatures[j]

print(f"對戰 {match_count + 1}: {creature1.name} vs {creature2.name}")

interaction = ecosystem.simulate_interaction(
creature1, creature2, rounds_per_match
)

print(f" 合作率: {creature1.name} {interaction['cooperation_rate1']:.2%}, "
f"{creature2.name} {interaction['cooperation_rate2']:.2%}")
print(f" 總收益: {creature1.name} {interaction['total_payoff1']}, "
f"{creature2.name} {interaction['total_payoff2']}")
print(f" 最終信譽: {creature1.name} {interaction['final_reputation1']:.3f}, "
f"{creature2.name} {interaction['final_reputation2']:.3f}")
print()

match_count += 1

return ecosystem.simulation_history

# 執行錦標賽
tournament_results = run_ecosystem_tournament(ecosystem, 200)

# 分析結果
print("錦標賽最終排名:")
print("=" * 40)
sorted_creatures = sorted(ecosystem.creatures,
key=lambda x: x.total_payoff, reverse=True)

for rank, creature in enumerate(sorted_creatures, 1):
avg_payoff = creature.total_payoff / (len(ecosystem.creatures) - 1)
print(f"{rank}. {creature.name:12} | "
f"總收益: {creature.total_payoff:4d} | "
f"平均: {avg_payoff:6.1f} | "
f"信譽: {creature.reputation:.3f} | "
f"策略: {creature.strategy_type}")



第三章:資料視覺化與分析

3.1 合作率與收益的視覺化分析

import matplotlib.pyplot as plt
import seaborn as sns

# 設定中文字體
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'Microsoft JhengHei']
plt.rcParams['axes.unicode_minus'] = False

def analyze_tournament_results(ecosystem, tournament_results):
"""分析錦標賽結果"""

# 創建分析資料
analysis_data = []
for creature in ecosystem.creatures:
creature_matches = [r for r in tournament_results
if r['creature1'] == creature.name or r['creature2'] == creature.name]

cooperation_rates = []
payoffs = []

for match in creature_matches:
if match['creature1'] == creature.name:
cooperation_rates.append(match['cooperation_rate1'])
payoffs.extend(match['payoffs1'])
else:
cooperation_rates.append(match['cooperation_rate2'])
payoffs.extend(match['payoffs2'])

analysis_data.append({
'name': creature.name,
'strategy': creature.strategy_type,
'avg_cooperation_rate': np.mean(cooperation_rates),
'total_payoff': creature.total_payoff,
'avg_payoff_per_match': creature.total_payoff / len(creature_matches),
'reputation': creature.reputation,
'payoff_variance': np.var(payoffs)
})

df = pd.DataFrame(analysis_data)

# 創建視覺化圖表
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
fig.suptitle('海洋生態囚徒困境錦標賽分析', fontsize=16, fontweight='bold')

# 1. 合作率 vs 總收益
ax1 = axes[0, 0]
scatter = ax1.scatter(df['avg_cooperation_rate'], df['total_payoff'],
c=df['reputation'], s=100, alpha=0.7, cmap='viridis')
ax1.set_xlabel('平均合作率')
ax1.set_ylabel('總收益')
ax1.set_title('合作率與收益關係')
plt.colorbar(scatter, ax=ax1, label='最終信譽')

# 添加生物名稱標籤
for i, row in df.iterrows():
ax1.annotate(row['name'], (row['avg_cooperation_rate'], row['total_payoff']),
xytext=(5, 5), textcoords='offset points', fontsize=8)

# 2. 策略比較柱狀圖
ax2 = axes[0, 1]
strategy_colors = plt.cm.Set3(np.linspace(0, 1, len(df)))
bars = ax2.bar(range(len(df)), df['total_payoff'], color=strategy_colors)
ax2.set_xlabel('海洋生物')
ax2.set_ylabel('總收益')
ax2.set_title('各生物收益比較')
ax2.set_xticks(range(len(df)))
ax2.set_xticklabels([f"{row['name']}\n({row['strategy']})"
for _, row in df.iterrows()], rotation=45, ha='right')

# 3. 信譽分佈
ax3 = axes[1, 0]
ax3.hist(df['reputation'], bins=10, alpha=0.7, color='skyblue', edgecolor='black')
ax3.set_xlabel('最終信譽值')
ax3.set_ylabel('頻次')
ax3.set_title('信譽值分佈')
ax3.axvline(df['reputation'].mean(), color='red', linestyle='--',
label=f'平均信譽: {df["reputation"].mean():.3f}')
ax3.legend()

# 4. 收益變異性
ax4 = axes[1, 1]
ax4.scatter(df['avg_cooperation_rate'], df['payoff_variance'],
c=df['total_payoff'], s=100, alpha=0.7, cmap='plasma')
ax4.set_xlabel('平均合作率')
ax4.set_ylabel('收益變異性')
ax4.set_title('合作率與收益穩定性')

plt.tight_layout()
plt.show()

return df

# 執行分析
results_df = analyze_tournament_results(ecosystem, tournament_results)

# 顯示詳細統計
print("\n詳細統計分析:")
print("=" * 50)
print(results_df.round(3))


本章節我們先建立了python的整體觀念,以及相關的數據統計分析,下篇章節,我們再繼續針對哲學層面進行更深入的探討。



留言
avatar-img
留言分享你的想法!
avatar-img
Code & Cogito
0會員
5內容數
用程式思考哲學,用科學驗證真理,用哲學指導技術
Code & Cogito的其他內容
2025/08/06
探討大數據時代個人隱私與尊嚴的哲學議題,從古典哲學到現代思潮,分析隱私的本質、效率與隱私的權衡、知情同意的困境、不同哲學觀點,以及演算法偏見、代際正義、全球化與文化多樣性等當代挑戰,並提出可能的解決方案,包括重新定義隱私、結合技術與倫理、探索新的治理模式,最終呼籲在技術進步與人性尊嚴間取得平衡。
Thumbnail
2025/08/06
探討大數據時代個人隱私與尊嚴的哲學議題,從古典哲學到現代思潮,分析隱私的本質、效率與隱私的權衡、知情同意的困境、不同哲學觀點,以及演算法偏見、代際正義、全球化與文化多樣性等當代挑戰,並提出可能的解決方案,包括重新定義隱私、結合技術與倫理、探索新的治理模式,最終呼籲在技術進步與人性尊嚴間取得平衡。
Thumbnail
2025/08/04
程式設計師的思維模式如何幫助我們理解哲學?本文從程式設計的角度,探討真理、自由意志、意識、道德、時間、身份、知識的界限、存在的意義、因果關係和完美社會等哲學議題,並提出獨特的見解。
Thumbnail
2025/08/04
程式設計師的思維模式如何幫助我們理解哲學?本文從程式設計的角度,探討真理、自由意志、意識、道德、時間、身份、知識的界限、存在的意義、因果關係和完美社會等哲學議題,並提出獨特的見解。
Thumbnail
2025/08/04
在這個數位時代,程式設計師被視為現代社會的建築師,他們用代碼構建著我們的數位世界。然而,許多人可能會疑惑:為什麼學習寫程式的人還需要研讀哲學這門看似抽象的學科?事實上,哲學與程式設計之間存在著深刻的連結,學習哲學不僅能提升程式設計師的技術能力,更能培養他們成為更優秀的思考者和決策者。 培養批判
Thumbnail
2025/08/04
在這個數位時代,程式設計師被視為現代社會的建築師,他們用代碼構建著我們的數位世界。然而,許多人可能會疑惑:為什麼學習寫程式的人還需要研讀哲學這門看似抽象的學科?事實上,哲學與程式設計之間存在著深刻的連結,學習哲學不僅能提升程式設計師的技術能力,更能培養他們成為更優秀的思考者和決策者。 培養批判
Thumbnail
看更多
你可能也想看
Thumbnail
🐟乍看到這書名,我以為是奇幻故事, 怎麼會有魚用「巧克力飛船」來命名, 但,真的有,不只「巧克力飛船魚」, 這本書裡有五種真實存在的魚。 這麼說吧, 《泅泳夜空的巧克力飛船魚》是一部由五個獨立、 但互相關聯的短篇故事組成的小說, 作者以五種不同魚類的習性和特色為比擬, 將這些魚
Thumbnail
🐟乍看到這書名,我以為是奇幻故事, 怎麼會有魚用「巧克力飛船」來命名, 但,真的有,不只「巧克力飛船魚」, 這本書裡有五種真實存在的魚。 這麼說吧, 《泅泳夜空的巧克力飛船魚》是一部由五個獨立、 但互相關聯的短篇故事組成的小說, 作者以五種不同魚類的習性和特色為比擬, 將這些魚
Thumbnail
水母是潛水者的常見問題,被水母螫傷後該怎麼辦?本文介紹了水母的特性和對人體的影響,以及被螫傷後的處理方法。同時還提供了預防水母螫傷的建議。
Thumbnail
水母是潛水者的常見問題,被水母螫傷後該怎麼辦?本文介紹了水母的特性和對人體的影響,以及被螫傷後的處理方法。同時還提供了預防水母螫傷的建議。
Thumbnail
當你放棄了魚,你可以去到更自由美好的世界,不是因為你付出了努力,而是因為它們就跟毀滅和失去一樣,是天理循環的一部分,就像生是死的反面,成長與腐爛互相輪替。
Thumbnail
當你放棄了魚,你可以去到更自由美好的世界,不是因為你付出了努力,而是因為它們就跟毀滅和失去一樣,是天理循環的一部分,就像生是死的反面,成長與腐爛互相輪替。
Thumbnail
我們都曾經看過這樣的報導,漁夫將鯊魚的背鰭割下,將沒有商業價值的鯊魚身體丟回海裡。但我們可能沒有見過這樣的場景,雇主命令漁工將夥伴的遺體丟入海中。這是《開動之前》紀錄片中最真實的影像,發生在印尼漁工上的悲歌。只要是漁工或是鯊魚失去利用價值,他們全都是雇主可以隨意丟棄的「物品」。
Thumbnail
我們都曾經看過這樣的報導,漁夫將鯊魚的背鰭割下,將沒有商業價值的鯊魚身體丟回海裡。但我們可能沒有見過這樣的場景,雇主命令漁工將夥伴的遺體丟入海中。這是《開動之前》紀錄片中最真實的影像,發生在印尼漁工上的悲歌。只要是漁工或是鯊魚失去利用價值,他們全都是雇主可以隨意丟棄的「物品」。
Thumbnail
《泅泳夜空的巧克力飛船魚》以五個短篇故事中描寫人們渴望自由、卻又受困於現實無法逃脫的生活,作者把五種魚類的習性和特色融入故事,把人們生活的日常比喻成一個個水族箱,傳遞出在友情、愛情、親情、關係、生死裡等等的不容易,為了活下去,要多麽努力才能擁有在世界泅泳的勇氣。
Thumbnail
《泅泳夜空的巧克力飛船魚》以五個短篇故事中描寫人們渴望自由、卻又受困於現實無法逃脫的生活,作者把五種魚類的習性和特色融入故事,把人們生活的日常比喻成一個個水族箱,傳遞出在友情、愛情、親情、關係、生死裡等等的不容易,為了活下去,要多麽努力才能擁有在世界泅泳的勇氣。
Thumbnail
  我是一隻在深海的美人魚,我有愛我的父王跟一堆哥哥姊姊們,我喜歡泡泡,我擅長用刀子,但是我不喜歡殺魚來吃,我吃素,我喜歡吃藻類,但是我已經忘記我愛吃藻類可能跟牡蠣那世有關,我覺得魚很可愛,就像我是美人魚一樣,我喜歡手機珍珠貝殼,牡蠣們是我的朋友,在海裡的時間比較慢,牡蠣控制著整個海洋的時間,陸地上
Thumbnail
  我是一隻在深海的美人魚,我有愛我的父王跟一堆哥哥姊姊們,我喜歡泡泡,我擅長用刀子,但是我不喜歡殺魚來吃,我吃素,我喜歡吃藻類,但是我已經忘記我愛吃藻類可能跟牡蠣那世有關,我覺得魚很可愛,就像我是美人魚一樣,我喜歡手機珍珠貝殼,牡蠣們是我的朋友,在海裡的時間比較慢,牡蠣控制著整個海洋的時間,陸地上
Thumbnail
神經科學家在實驗室裡觀察到的事:「好奇」這種大腦狀態,既會比「學習」更早出現,也會促進「學習」。簡單來說,當一個人的大腦想要吸收呈現在面前的資訊時,他的主觀感受就是「好奇」。因此,不論情況為何,當你越感到好奇,你的大腦就越準備好記住接下來發生的事。
Thumbnail
神經科學家在實驗室裡觀察到的事:「好奇」這種大腦狀態,既會比「學習」更早出現,也會促進「學習」。簡單來說,當一個人的大腦想要吸收呈現在面前的資訊時,他的主觀感受就是「好奇」。因此,不論情況為何,當你越感到好奇,你的大腦就越準備好記住接下來發生的事。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News