resera.pl (2379B)
1 #!/usr/bin/perl 2 3 use strict; 4 use warnings; 5 6 my $iterations = 100000; 7 8 my $frequencies = [ 9 [0, 0], 10 [0, 0] 11 ]; 12 13 # default taken from http://en.wikipedia.org/wiki/Prisoner%27s_dilemma 14 my $payoff_matrices = [ 15 [ 16 [3, 0], 17 [5, 1] 18 ], 19 [ 20 [3, 0], 21 [5, 1] 22 ] 23 ]; 24 25 # also takes command line arguments 26 if (scalar @ARGV == 8) { 27 $payoff_matrices->[0] = [ 28 [$ARGV[0], $ARGV[2]], 29 [$ARGV[4], $ARGV[6]] 30 ]; 31 $payoff_matrices->[1] = [ 32 [$ARGV[1], $ARGV[5]], 33 [$ARGV[3], $ARGV[7]] 34 ]; 35 } 36 37 for (my $i = 0; $i < $iterations; $i++) { 38 # players must choose simultaneously--don't update the frequencies in loop 39 my $choices = [undef, undef]; 40 foreach my $player (0, 1) { 41 # find the probability the other player will choose the first option 42 my $other_player = ($player + 1) % 2; 43 my $frequency = $frequencies->[$other_player]; 44 my $chose_first = $frequency->[0]; 45 my $total_choices = $chose_first + $frequency->[1]; 46 my $p = .5; 47 unless ($total_choices == 0) { 48 $p = $chose_first / $total_choices; 49 } 50 # find the expected value of each option 51 # we'll skip the /2, since we're comparing them 52 my $pm = $payoff_matrices->[$player]; 53 my $first_choice_ev = $p * $pm->[0][0] + (1 - $p) * $pm->[0][1]; 54 my $second_choice_ev = $p * $pm->[1][0] + (1 - $p) * $pm->[1][1]; 55 # pick the choice with the highest ev, or choose at random if they tie 56 if ($first_choice_ev != $second_choice_ev) { 57 $choices->[$player] = ($first_choice_ev > $second_choice_ev) ? 0 : 1; 58 } 59 else { 60 $choices->[$player] = int(rand() + .5); 61 } 62 } 63 # update frequencies to reflect this round 64 foreach my $player (0, 1) { 65 $frequencies->[$player][$choices->[$player]]++; 66 } 67 } 68 69 my $pm = " Column 1 | Column 2\n" . 70 " ---------------------\n" . 71 "Row 1 | %3d, %3d | %3d, %3d\n" . 72 "Row 2 | %3d, %3d | %3d, %3d\n\n"; 73 printf( 74 $pm, 75 $payoff_matrices->[0][0][0], 76 $payoff_matrices->[1][0][0], 77 $payoff_matrices->[0][0][1], 78 $payoff_matrices->[1][1][0], 79 $payoff_matrices->[0][1][0], 80 $payoff_matrices->[1][0][1], 81 $payoff_matrices->[0][1][1], 82 $payoff_matrices->[1][1][1], 83 ); 84 foreach my $player (0, 1) { 85 printf( 86 "Player %d: (%.3f%%, %.3f%%)\n", 87 $player, 88 ($frequencies->[$player][0] / $iterations) * 100, 89 ($frequencies->[$player][1] / $iterations) * 100 90 ); 91 }