Prisoner’s Dilemma on a graph

Mathematica codes

In this blog entry, we will explore the concept of cooperation and defection using evolutionary game theory. This simulation helps us understand how agents in a population interact and how their strategies evolve over time. We will walk through the process step by step and provide in-class activities and homework for students to deepen their understanding.

Introduction

Evolutionary game theory is a powerful tool for studying the emergence of cooperation in groups. It is particularly useful in situations where individuals face a conflict between their selfish interests and the collective benefit of cooperation. In this simulation, we will consider a population of agents and examine how their strategies of cooperation and defection evolve over time.

Setting up the Simulation

To begin, let’s set the total number of agents in our population to 10. This number can be modified to explore different scenarios in the simulation. Next, we need to initialize the distribution of cooperators and defectors in the population by creating a randomly populated list. The list couleur represents the color (strategy) of each agent, with “Red” representing defection and “Blue” representing cooperation.

Initializing the Connection between Agents

In order to model interactions between agents, we need to initialize the connections between them. This can be done randomly by creating a binary matrix G. A value of 1 in the matrix represents a connection between two agents, while a value of 0 indicates no connection. We assume that no agent has a relationship with itself by setting the diagonal entries of G to zero.

Visualizing the Random Network

To visualize the initialized random network, we can use the following code .

It generates a graph plot representing the connections between agents, with each agent represented by a vertex and their strategies indicated by color.

Computing Payoff for an Agent

To analyze the payoff associated with each agent’s strategy, we need to discern if an agent is a cooperator or a defector. We can extract the color (strategy) of an agent using the code couleur[[1]][[2]]. The color “RGBColor[1, 0, 0]” represents defection, while “RGBColor[0, 0, 1]” represents cooperation.

Next, we can find the neighbors of an agent by identifying the positions in the matrix G where there is a connection to that agent. The code Flatten[Position[G[[1]], 1]] returns a list of indices indicating the neighbors of Agent 1.

Computing Payoff for a Defector

Computing the payoff associated with a defector is straightforward. We only need to know the number of cooperators in the agent’s neighborhood. The payoff for a defector is given by the formula

Count[Table[couleur[[Flatten[Position[G[[1]], 1]][[k]]]][[2]], {k, 1, Length[Flatten[Position[G[[1]], 1]]]}], RGBColor[0, 0, 1]] * β.

Here, β represents a parameter that weighs the benefit of cooperation against the cost of cooperating with defectors.

Computing Payoff for a Cooperator

To compute the payoff associated with a cooperator, we need to know both the number of cooperators and the number of defectors in the agent’s neighborhood. The payoff for a cooperator is given by the formula Count[Table[couleur[[Flatten[Position[G[[1]], 1]][[k]]]][[2]], {k, 1, Length[Flatten[Position[G[[1]], 1]]]}], RGBColor[0, 0, 1]] * (β - ψ) - Count[Table[couleur[[Flatten[Position[G[[1]], 1]][[k]]]][[2]], {k, 1, Length[Flatten[Position[G[[1]], 1]]]}], RGBColor[1, 0, 0]] * ψ. Here, ψ represents a parameter that quantifies the cost of cooperating with defectors.

Computing Payoff for Every Agent

To compute the payoff for every agent in the population, we can loop through each agent and calculate their payoff using the previously described formulas. The resulting payoffs will be stored in the list payoff.

Evolving Strategies

Next, each agent compares their own payoff with the highest payoff among their neighbors. If an agent’s payoff is lower than the highest payoff among its neighbors, it adopts the strategy of the agent with the highest payoff. This process simulates the evolution of strategies based on the success of neighboring agents. To identify the agent with the highest payoff among an agent’s neighbors, we can use the code Max[Table[payoff[[Flatten[Position[G[[1]], 1]][[j]]]], {j, 1, Length[Flatten[Position[G[[1]], 1]]]}]]. This code returns the maximum payoff among an agent’s neighbors.

For each agent in the population, we can determine the position of the agent with the highest payoff using the code Intersection[Flatten[Position[payoff, Max[Table[payoff[[Flatten[Position[G[[1]], 1]][[j]]]], {j, 1, Length[Flatten[Position[G[[1]], 1]]]}]]]], Flatten[Position[G[[1]], 1]]]. This code finds the indices where the maximum payoff occurs and identifies the corresponding agents.

Finally, each agent compares its payoff with the highest payoff among its neighbors. If an agent’s payoff is lower, its strategy is updated to match the strategy of the agent with the highest payoff. This update reflects the concept of learning from successful neighbors.

Visualizing the Evolved Graph

To visualize the outcome of the strategy evolution, we can plot the evolved graph using the code GraphPlot[G, VertexLabels -> Automatic, VertexStyle -> couleur]. This graph represents the connections between agents after their strategies have evolved.

Before
After

It remains next to iterate this procedure inside a loop as done with the case of Prisoner’s Dilemma Game on a grid.