Assignments Political Science 209-1 Winter 1999

Assignments Week 2:

1. Write a program that prints "hello, world" on the screen (cf. Kernighan &Ritchie, p. 7).

2. Write a program to print the numbers from 1 to 10 and their squares.


1 1

2 4

3 9

...

3. Write a program to print this triangle:


*

**

***

****

*****

******

*******

********

*********

**********

(Don't use ten printf statements; use nested loops instead.)

4. This program prints the pure Nash equilibria of a Prisoner's Dilemma game:


#include 

int main(int argc, const char ** argv) {
  int m[2][2] = {{3,0},{5,1}};
  int equil;
  int r, c;

  for (r=0; r<2; r++) {
    for (c=0; c<2; c++) {
      equil = (m[r][c]>m[1-r][c]) && (m[c][r]>m[1-c][r]);
      printf("%d ",equil);   
    }

    printf("\n");
    
  }

  return 0;
}

(a) Modify the program to generate the corresponding matrix for a Chicken game.

(b) Modify the program such that it prints "fancy" output of the following type:


+---+---+
|   |   |
+---+---+
|   | * |
+---+---+

(c) Add a routine that adds a "P" if the cell is also a Pareto-optimal outcome, and run the program for both the Prisoner's Dilemma and Chicken games. (A cell is Pareto-optimal if there is no other outcome that would not make at least one of the players worse off. Use a four-double loop.) The output for the Prisoner's Dilemma should be:


+---+---+
| P | P |
+---+---+
| P | * |
+---+---+

5. The rules to play Russian Roulette are the following: Player A starts by loading the revolver with one bullet. If A survives, Player B continues by adding another bullet. If B survives, A has to add a third bullet, etc. The revolver can hold up to six bullets. Which player has the best chance of survival?

(a) Answer the question by computing the probabilities theoretically.

(b) Write a program that estimates the probabilities by simulating the game many times. (Use the built-in random number generator rand(), see Kernigan and Richie, p. 46. You have to include the file to call the function. To generate a double random number from 0.0 to 1.0, use type casting and divide by the system constant RAND_MAX: (double)rand() / (double)RAND_MAX yields the desired number.)

To trace the execution of the program, it is convenient to print the history of each replication:


1: A B A

2: A B

3: A B A B A

4: A

5: A B

...

Assignments Week 3:

Please hand in both source code and output.

1. This exercise asks you to modify the SimplePD sample program.

(a) Modify the main.m file such that the program checks whether each of the four cells is a Nash equilibrium (in pure strategies). (See last week’s exercise 4b).

(b) Simplify the implementation of Player by using the same preference matrix for both row and column players.

Hint: This requires swapping the position "coordinates" (r, c) of the column player. The change allows you to declare a single preference matrix with the curly-bracket notation in its declaration that should be put right before the keyword @implementation in Player.m.

(c) Generalize the program such that it prints matrices with marked equilibria for both the Prisoner's Dilemma and Chicken games.

Hint: Add a second matrix definition as in part b and include a new parameter in the init:playerType: message that selects the matrix type.

2. This exercise introduces an object-oriented version of the Russian Roulette program (see last week's exercise 5).

(a) Complete the program by writing the implementation of Player and Revolver. The other files are provided on the next page.

(b) Report the estimated probability of A's survival.

(c) Reduce the number of replications to 100 and modify the program such that it produces output of the type:


1: A B A

2: A B

3: A B A B A

4: A

5: A B

...

File: main.m:


// include files

int main(int argc, const char ** argv) {
  id playerA, playerB, revolver;
  long int repl;
  long int sum = 0;
  long int n = 1000000;
  
  

  initSwarm(argc,argv);

  playerA = [Player create: globalZone];
  playerB = [Player create: globalZone];
  
  [playerA setOther: playerB];
  [playerB setOther: playerA];
  
  revolver = [Revolver create: globalZone];
  
  for (repl=0; repl<n; repl++) {
    [playerA init: 0];
    [playerB init: 1];
    [revolver empty];
    [playerA play: revolver];
    
    if ([playerA isAlive])
      sum++;
  }
  
  printf("Prob. of A surviving: %8.6f \n", (double)sum/n);
  
  return 0;

}

Header file: Player.h:


// include files

@interface Player: SwarmObject {
 int name;
 int alive;
 id other;
}

-init: (int) n;
-setOther: o;
-(BOOL)isAlive;
-play: r;

@end

Header file: Revolver.h:


// include files

@interface Revolver: SwarmObject {
 int bullets;
}

-empty;
-load;
-(BOOL)trigger;

@end

Assignments Week 4:

As usual, please hand in both source code and output.

This week's exercises ask you to modify the simpleIPD sample program.

1. Simplify the ModelSwarm by replacing all the activity schedules with a simple loop.

Hint: Remove the messages buildActions, activateIn, and stopRunning Instead, introduce a new message called run: (int) time which calls the messages updateMemories, step, and distrPayoffs directly. The time parameter is the loop variable, which means that the players no longer need their own clock.

2. Use the modified version to generate the result of all sixteen strategy combinations exactly as they appear in Cohen, Riolo and Axelrod (see Table 3, p. 10).

Hint: You can create new versions of the modelSwarm for each strategy combination and then remove them by calling [modelSwarm drop]. In order to loop through each combination, you need to parameterize the buildObjects message.

Assignments Week 5:

1. Modify the sample program SimpleList by

a) adding a method (int)getSum: list that returns the sum of all elements’ numbers. Hint: use the structure of printOjbects.

b) adding a method reverse: list that reverses the order of the elements of the parameter list. Hint: There are several ways to do this. The method shuffle should give you an idea. If n is the length of the list, swapping the elements i and n-i-1 for i

c) adding a method makeEven: list that removes all the odd elements from the list.

Hint: again the method shuffle will be helpful. Note that while looping through the list, removing elements.

*d) adding a method sort: list that sorts the list in ascending order after it has been scrambled by the shuffle: list method.

2. This exercise focuses on the evolIPD sample program.

a) Simplify the evolIPD by replacing the implementation of Tournament such that instead of running the iterated game, the class sets the players payoff according to a lookup table int payoff[4][4] = {{...}} holding the final payoffs as defined by Cohen, Riolo and Axelrod (Table 3, p. 10). Make sure that the simplified program produces exactly the same output as the original one. Hint: Only the file Tournament.m needs to be altered, although you may want to remove a few obsolete message definitions from Tournament.h. It is convenient to declare the matrix holding the final scores of the games inside Tournament.m.

b) Try to run the program with 64 players of each type for five different random seeds as specified in the model.setup file. Which strategy appears to dominate?

*c) Alter the program so that it can be run for different random seeds starting with 1 running up to 100. Now modify the model.setup file such that there are 99 TFT players and one all-D player (the other types set to zero). Estimate the probability of TFT prevailing in runs lasting for 30 generations. Why is not all-D winning the whole time since it receives a higher payoff than TFT for each encounter? Calculate the theoretical probability of TFT winning. Is there a way to change the main loop in runTournament such that all-D would dominate?

Assignments Week 6:

1. Modify the GraphIPD program by:

a) adding a graph that shows dynamically the players' average payoff.

b) replacing the frequency graph by a dynamic histogram of EZBin type plotting the frequency of the four strategies.

2. This exercise (which was first announced as an extra exercise on Friday last week) asks you to calculate the average waiting time for two different types of elevators in an apartment building.

Let's start with a simple example with two tenants (labeled 1 and 2). Each of them occupies his or her own floor numbered accordingly 1 and 2. The main entrance is at floor 0. Now let's assume that, each tenant can be either outside or at home. Their whereabouts are governed randomly such that at any point, one of the two will decide to either go outside or return home.

There are two types of elevators: type 0 and type 1. The first of these is a conventional elevator that takes each passenger to whichever floor is selected and stays there after use. By contrast, the modified type 1 always returns to floor 0 after use.

The sample program Elevator (downloadable through the button Elevator Example) offers the code to calculate the average waiting time for the two-tenant model.

a) Derive the theoretical average waiting time for both elevator types in the two-tenant case. For how many events do you have to run the program in order to get close to the theoretical values?

b) Create a generalized version of the program called ElevatorN that simulates the process for the n-tenant case. Hint: Following the template of EvolIPD, create a ModelSwarm to be called by the main program for each parameter combination. Inside the ModelSwarm, use List or Array collections to handle the n agents.

c) Use the modified program to simulate the expected average waiting times for both elevator types in buildings holding n= 1, 2, 3, 4, ..., up to 10 tenants. Hint: You can use the theoretical average waiting times as indicated below to validate your program.

d) Using a data package (or a graph inside Swarm), plot the average waiting times as a function of n.

e) What can be said about the relative efficiency of the two elevator types?

*f) Prove that in the n-tenant case the theoretical waiting times for type 0 and 1 elevators respectively are:

EW(n, type=0) = (n^2 - 1) / (3n)

EW(n, type=1) = (n+1) / 4


Last modified: Tue Feb 16 20:39:05 PST 1999