見出し画像

読書めも『徳の起源 他人をおもいやる遺伝子』マット・リドレー (著)

※私の読書メモをまとめてみました。実際に書かれている内容とは異なる部分があります。本に何が書かれているかを知るためには、やっぱり、自分でちゃんと読むことをお勧めします。

著者

 マット・リドレー(Matt Ridley)は、主に進化生物学や経済学、科学哲学に関する著書で知られている、イギリスのジャーナリストです。進化生物学、遺伝学、経済学、歴史など、幅広いテーマに関心を持ち、一般の読者にもわかりやすく書かれた著書を残しています。

 しかし、科学的厳密性が欠けているという批判もあります。一部の研究を過度に強調し、他の要素を意図的に過小評価したり無視している傾向があります。彼の視点は大胆で挑発的であり、過度に楽観的な面があります。

 主な著書に、『赤の女王—性と人間性の進化論』(The Red Queen: Sex and the Evolution of Human Nature, 1993)、『合理的楽観主義者—進歩の科学』(The Rational Optimist: How Prosperity Evolves, 2010)、『進化は万能である』(The Evolution of Everything: How New Ideas Emerge, 2015)などがあり、広く影響を与えました。

 2013年、「リドリー男爵」としてイギリスの貴族院に任命され、科学技術と経済政策に関する議論に積極的に参加しています。

徳は人間に備わっているのか

 人は、基本的に利己的な行動をとるが、集団においては「汝の隣人を愛せよ」という教えを守り、徳を示そうとする。しかし、隣人以外に対しては傷つけ、滅ぼしてきた。

 「自然を敬い、ともに生きてきた」と言われるインディアンは、多数の大型動物の種を絶滅させている。白人がアメリカ大陸にたどり着いた時には獲物となる動物の数は驚くほど少なかった。人間が、これまで自然と調和した生活をおくってきたなどというのは幻想です。

 これまで人間に対して抱いていたイメージを取り払い、欠点も含めて人間という種を見つめなおします。

囚人のジレンマ

 この本で囚人のジレンマについて取り上げられています。このゲームは1950年、アメリカの数学者アルバート・W・タッカー(Albert W. Tucker)が、ジョン・ナッシュ(John Nash)のナッシュ均衡の概念を説明するための例として使用しました。

 囚人のジレンマは、二人のプレーヤーがそれぞれ協力か裏切りかを選択します。もし二人とも協力なら両者は3点づつもらえます。二人とも裏切りなら1点づつもらえます。しかし、片方が裏切り、もう片方が協力なら、協力した方には得点がもらえず、裏切り者には5点がもらえるというゲームです。

 双方が協力を続けるなら、二人の合計点で最も高くなります。しかし、個人の得点を考えれば「裏切り」を選択したほうが相手と同じか、相手以上の得点を手に入れることができます。

 1984年発行された『The Evolution of Cooperation』で、ロバート・アクセルロッド(Robert Axelrod)は、コンピュータを用いて囚人のジレンマゲームを繰り返し行い、その都度相手の行動に応じて戦略を変更する進化的アプローチの研究を進めます。

 1980年代以降は、実験経済学や社会心理学においても広く研究されました。人々がどのように意思決定を行うのか、協力や裏切りがどのような条件で起こるかが研究され、理論的モデルと人間行動のギャップが明らかにされます。

 囚人のジレンマが繰り返し行われるゲームでは、人々が「条件付き協力者」として振舞うことが多いという研究もおこなわれています。これは、相手が協力するなら自分も協力するが、裏切られた場合は次回以降は裏切り返すという戦略です。この戦略が持続的な協力をどのように維持するかが実験的に探究されています。

 2000年代以降は、ネットワーク理論と組み合わせた研究がされています。プレイヤーがどのようにネットワーク上でつながり、影響しあい、協力行動が進化するかが研究されています。特に、複雑系ネットワークのスモールワールドネットワーク(Small-World Network)やスケールフリーネットワーク(Scale-Free Netowrk)において、協力関係がどのように促進されるのかが検討されています。

 近年では、AIエージェントが囚人のジレンマを学習し、どのように協力や裏切りを選択するかが研究されています。特に、ことなるAIエージェント間の協力関係を構築する研究は、ロボット工学やマルチエージェントシステム(MAS)での応用が進んでいます。また、進化的ダイナミクスと呼ばれる手法を用い、競争的な環境における協力行動の進化をシミュレートし、現実世界の問題解決に応用する研究が行われています。

"Evolutionary Dynamics: Exploring the Equations of Life."(M. A. Nowak, 2006) では、囚人のジレンマを含む進化ゲーム理論を数学的なモデルを通じて詳しく解説しています。

"Multiagent Systems: Algorithmic, Game-Theoretic, and Logical Foundations"(Yoav Shoham, Kevin Leyton-Brown, 2008) では、マルチエージェントシステム(MAS)に関する、基礎から応用までを解説しています。囚人のジレンマを含むゲーム理論の問題をAIやマルチエージェントシステムを使ってどのようにシミュレートし、解決するかについて詳しく書かれています。

囚人のジレンマゲームを作る

 囚人のジレンマゲームをChatGPTに頼んで、たぶんこんな感じかな作ってもらいました。

 プレイヤー1が「常に裏切り」で、プレイヤー2は協力と裏切りをランダムに選択します。10回繰り返して得点を表示します。

import random

def prisoners_dilemma(player1_choice, player2_choice):
    if player1_choice == "cooperate" and player2_choice == "cooperate":
        return (3, 3)  # 両者協力:3点ずつ
    elif player1_choice == "cooperate" and player2_choice == "defect":
        return (0, 5)  # プレイヤー1協力、プレイヤー2裏切り:プレイヤー1は0点、プレイヤー2は5点
    elif player1_choice == "defect" and player2_choice == "cooperate":
        return (5, 0)  # プレイヤー1裏切り、プレイヤー2協力:プレイヤー1は5点、プレイヤー2は0点
    else:
        return (1, 1)  # 両者裏切り:1点ずつ

# プレイヤーの戦略を定義
choices = ["cooperate", "defect"]

# 各プレイヤーの総得点を初期化
player1_total_score = 0
player2_total_score = 0

# 10回繰り返し
for i in range(10):
    player1_choice = random.choice(choices)
    player2_choice = random.choice(choices)
    
    # ゲームを実行して結果を得る
    result = prisoners_dilemma(player1_choice, player2_choice)
    
    # 得点を集計
    player1_total_score += result[0]
    player2_total_score += result[1]

# 最終結果を表示
print("Final Scores after 10 rounds:")
print(f"  Player 1: {player1_total_score} points")
print(f"  Player 2: {player2_total_score} points")

 しかしながら、しっぺ返し(Tit-for-tat)や、寛大(Generous-Tit-for-tat)を加えてやると、様相は変わってきます。結果はその都度変わります。しっぺ返しが有利ですが、時に寛大が一番になったりします。

import random
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

# 日本語フォントの設定(Windowsのフォントを使用)
font_path = 'C:\\Windows\\Fonts\\meiryo.ttc'  # Windowsのフォントパス
font_prop = fm.FontProperties(fname=font_path)
plt.rcParams['font.family'] = font_prop.get_name()

# プレイヤーの戦略
def 常に協力(opponent_history):
    return 'C'

def 常に裏切り(opponent_history):
    return 'D'

def しっぺ返し(opponent_history):
    if not opponent_history:
        return 'C'
    return opponent_history[-1]

def 寛大(opponent_history):
    if not opponent_history:
        return 'C'
    if opponent_history[-1] == 'D' and random.random() < 0.1:  # 10%の確率で協力
        return 'C'
    return opponent_history[-1]

# ゲームの実行
def play_game(strategy1, strategy2, rounds=5):
    history1 = []
    history2 = []
    score1 = 0
    score2 = 0

    for _ in range(rounds):
        move1 = strategy1(history2)
        move2 = strategy2(history1)
        history1.append(move1)
        history2.append(move2)

        if move1 == 'C' and move2 == 'C':
            score1 += 3
            score2 += 3
        elif move1 == 'C' and move2 == 'D':
            score1 += 0
            score2 += 5
        elif move1 == 'D' and move2 == 'C':
            score1 += 5
            score2 += 0
        elif move1 == 'D' and move2 == 'D':
            score1 += 1
            score2 += 1

    return score1, score2

# 戦略の設定
strategies = [常に協力, 常に裏切り, しっぺ返し, 寛大]

# 初期個体数の設定
population_size = 100
population = [random.choice(strategies) for _ in range(population_size)]

# 世代数の設定
num_generations = 10

# 各世代の戦略ごとの個体数を記録するリスト
history = {strategy.__name__: [] for strategy in strategies}

for generation in range(num_generations):
    scores = {strategy.__name__: 0 for strategy in strategies}
    
    # 各個体がランダムに対戦
    for i in range(0, population_size, 2):
        strategy1 = population[i]
        strategy2 = population[i + 1]
        score1, score2 = play_game(strategy1, strategy2)
        scores[strategy1.__name__] += score1
        scores[strategy2.__name__] += score2
    
    # 次世代の個体を選択
    new_population = []
    for strategy in strategies:
        count = int((scores[strategy.__name__] / sum(scores.values())) * population_size)
        new_population.extend([strategy] * count)
    
    # 個体数が不足している場合はランダムに補充
    while len(new_population) < population_size:
        new_population.append(random.choice(strategies))
    
    population = new_population
    
    # 各世代の戦略ごとの個体数を記録
    for strategy in strategies:
        history[strategy.__name__].append(population.count(strategy))

# グラフの描画
for strategy, counts in history.items():
    plt.plot(range(num_generations), counts, label=strategy)

plt.xlabel('世代')
plt.ylabel('個体数')
plt.title('戦略ごとの個体数の変遷')
plt.legend()
plt.show()

 これに、進化という要素を入れてみると、更にライフゲームっぽくなりますが、パラメータの調整が難しくなります。色々いじりこんで試してみるのも面白いものです。

この記事が気に入ったらサポートをしてみませんか?