囚人のジレンマ
鳥のアイコンの人が、昨晩呟いてたのをGaucheならどう書くかなーって少しだけ考えたので、そのままさくっと載せてみる。
このコードどうしたらもっと見通し良くなるだろう URL
2013-06-26 01:08:14 via web
まず、囚人のジレンマとは
囚人のジレンマ(しゅうじんのジレンマ、英:Prisoner's Dilemma)とは、ゲーム理論や経済学における重要概念の一つで、下記のようなジレンマを指す:互いに協調する方が裏切り合うよりもよい結果になる事が分かっていても、皆が自身の利益を優先している状況下では、互いに裏切りあってしまう。
「囚人のジレンマ」と言う名称は、後述する司法取引のシナリオからきているものの、このシナリオはあくまでモデルをわかりやすくする為の例にすぎず、ジレンマ自身は純粋に数学的に定式化される。 同種のジレンマが経済現象でも頻繁に見られること(値下げ競争、環境保護など)から、ゲーム理論における重要な研究対象とされ、近年では行動経済学の分野でも研究が進んでいる。
元のRubyで書かれたコード
# input: # strategy_i - strategy of player 1, 2. # output: # payoff_i - payoff rewarded to player 1, 2. def prisoner (strategy_1, strategy_2) if strategy_1 == "m" if strategy_2 == "m" payoff_1 = -1 payoff_2 = -1 elsif strategy_2 == "f" payoff_1 = -9 payoff_2 = -0 end elsif strategy_1 == "f" if strategy_2 == "m" payoff_1 = 0 payoff_2 = -9 elsif strategy_2 == "f" payoff_1 = -6 payoff_2 = -6 end end return payoff_1, payoff_2 end
これをGaucheで書きなおす。
(define (prisoner strtegy-1 strtegy-2) (cond [(and strtegy-1 strtegy-2) (values -6 -6)] [(or strtegy-1 strtegy-2) (if strtegy-1 (values -0 -9) (values -9 -0))] [(and (not strtegy-1) (not strtegy-2)) (values -1 -1)])) ;;test ;;#t を自白した、 #fを自白しなかったとする (prisoner #t #t) (prisoner #f #t) (prisoner #t #f) (prisoner #f #f)
これじゃ、意味が分かりにくいし、なんというかセンスのなさ溢れているので、考えなおした。
そういえば、パターンマッチがあるんだった。なので、書きなおしてこう。
(use util.match) (define (prisoner strtegy-1 strtegy-2) (match (list strtegy-1 strtegy-2) [("f" "f") `((payoff-1 . 6) (payoff-2 . 6))] [("f" "m") `((payoff-1 . 0) (payoff-2 . 9))] [("m" "f") `((payoff-1 . 9) (payoff-2 . 0))] [("m" "m") `((payoff-1 . 1) (payoff-2 . 1))])) ;;test ;;Mum,Finkのイニシャルでm,fを使っている (prisoner "f" "f") (prisoner "f" "m") (prisoner "m" "f") (prisoner "m" "m")
こう書くとシンプルかなって。そんな感じでGauche素敵。
ついでなので、返す値も工夫してみた。
どうでもいいけど
モチベーション3.0でもこれに似た話が出ますね。
AさんとBさんの二人組に対して、Aさんにだけ10ドルを渡して「Bさんに好きなだけ渡して下さい。ただし、Bさんが納得しなければそのお金は回収します」だったかな?