Computer Generated Farmers: Information and Nash Equalibrium: Difference between revisions
No edit summary |
|||
(16 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
== What are we trying to do here? == | == What are we trying to do here? == | ||
Picture a hundred farmers in a simple economy, where two crops are farmed: Rice and Corn. In a similar manner as the fisherman’s dilemma, in which a day’s output for one fisherman far affects the yield of the other fisherman, the amount of corn produced affects how much rice is produced. Each crop has a separate price and cost curve. Each farmer has to make individual decision, given the current point on the curves, of what percentage of total yield to devote to corn and rice. Given 100 farmers, will a stable Nash Equilibrium be reached? | Picture a hundred farmers in a simple economy, where two crops are farmed: Rice and Corn. In a similar manner as the fisherman’s dilemma, in which a day’s output for one fisherman far affects the yield of the other fisherman, the amount of corn produced affects how much rice is produced. Each crop has a separate price and cost curve, rather than a matrix which we are used to (in fact, you can think of the values of the matrix as points on the curve). Each farmer has to make their individual decision, given the current point on the curves, of what percentage of total yield to devote to corn and rice. Given 100 farmers and different sets of functions, will a stable Nash Equilibrium be reached? | ||
== Why make a computer simulation of a simple game? == | == Why make a computer simulation of a simple game? == | ||
[[Image:Eden_lot50-1-floor2.jpg]] There are many games with very simple rules or agents result in complex aggregate results. These results are not necessarily very predicable–while there are only a number of desirable outcomes with 2x2 games, games which involve hundreds of agents | [[Image:Eden_lot50-1-floor2.jpg]] | ||
There are many games with very simple rules or agents result in complex aggregate results. These results are not necessarily very predicable–while there are only a number of desirable outcomes with 2x2 games, games which involve hundreds of agents making many moves in succession are rather unpredictable. Our simulation is a simple model of a broad market; the Farmers in this game are stupid-their thought logic is simple, and they don't have the ability to take past mistakes into account to make predictions about the future. By default, there is a possibility that there are systems that will not reach a NASH equalibrium, since it will not take in account past data points to straighten itself. However, despite low intelligence and near perfect information (classical game theory), each farmer will indirectly be influencing the decisions of the other farmers, which could bring some interesting results. | |||
== Implementation == | == Implementation == | ||
100 digital farmers will be generated. Of importance to a farmer: | 100 digital farmers will be generated. Of importance to a farmer: | ||
1)A fixed production capacity at 1 (noted as 100% on the cost function) | |||
1)A fixed production capacity at 1 (noted as 100% on the cost function). | |||
2)An alpha value, which is defined as the percentage of corn he wishes to produce. | 2)An alpha value, which is defined as the percentage of corn he wishes to produce. | ||
3)(1-alpha) is the percentage of his yield that is rice | |||
4) | 3)(1-alpha) is the percentage of his yield that is rice. | ||
4)Price functions. Each farmer will try to maximize their profit according to the price of crops in the market and the profit function. The price function for rice will take the form similar to <b> P = A/X </b>, where where p is profit, A is a constant, and X is the quantity of crops the farmer is producing, with no asymptote--the more units of a product produced, the less the production cost (usually) is. The price function of corn will also be determined by a <b> P = B/X </b> function, this time P standing for price of the crop, B is some constant, and X is the total number of the crop being produced. | |||
'''Figure 1: The Price and Cost Functions''' | '''Figure 1: The Price and Cost Functions''' | ||
[[Image:Graph1.JPG]] | [[Image:Graph1.JPG]] | ||
Line 19: | Line 26: | ||
== The maximation function == | == The maximation function == | ||
The economic actors in this experiment are programmed to maximize their returns and minimize the strategies of other actors. Given the information in figure 1, digital farmers will try to maximize x, the amount of crop to produce, given the following | The economic actors in this experiment are programmed to maximize their returns and minimize the strategies of other actors. Given the information in figure 1, digital farmers will try to maximize x, the amount of crop to produce, given the following maximazation function: | ||
'''Figure 2: Maximation Function of Farmer''' | '''Figure 2: Maximation Function of Farmer''' | ||
[[Image:Equation1.JPG]] | [[Image:Equation1.JPG]] | ||
== The Overall Flow of the Simulation == | |||
1) The program first creates 100 farmers, with either random alpha values or evenly spread out alpha values. Therefore, each farmer will start with a different ''starting'' preference for how much corn to make. | |||
2) The farmers are indexed, and using the fixed inverse price curves shown above, farmers one at a time will try a best response function (function ''maximize''), until all farmers have had a chance to maximize or change strategies. | |||
3) A frequency distribution graph will output the distribution of alpha levels at the end of each round of play. | |||
[[Image:Graph3.JPG]] | |||
4) There are 100 rounds of play. Therefore, as a default, we expect at some point for the distributions from round to round to stabilize. This would be a sign of Nash Equilibrium. | |||
== The Code of the Program == | |||
The programming was done in jEdit on the computers at the Tome Scientific building. The project consisted of a file which held the implementation functions and another file which defined the object FARMER. From a programming perspective, many functions which could have been publicly defined in the FARMER class were globalized and inserted into the implementation/main function file. | |||
'''''farmerGame.java''''' | |||
<nowiki> | |||
import java.io.*; | |||
public class farmerGame { | |||
private farmers[]; | |||
private int intervals[] = new int[10]; | |||
private float currentCornPrice; | |||
private float currentRicePrice; | |||
private float a; | |||
private float b; | |||
private float c; | |||
private float d; | |||
private float X; | |||
private float Y; | |||
private float totalAlpha; | |||
private float totalProfit; | |||
public farmerGame(boolean i); { | |||
totalAlpha = 0; | |||
int i; | |||
farmers = new farmer[100]; | |||
if (i) { | |||
for (i=0; i<100; i++) { | |||
farmers[i].setAlpha((float)i/100); | |||
} | |||
} | |||
else { | |||
for (i=0; i<100; i++) { | |||
farmers[i].setAlpha(Math.random()); | |||
} | |||
} | |||
for (i=0; i<100; i++) { | |||
intervals[(int)(farmers[i].getAlpha() * 100)]++; | |||
} | |||
} | |||
public void drawGraph() { | |||
int i; | |||
System.out.print("0-0.1 |"); | |||
for (i=0; i<intervals[0]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[0] + ")"); | |||
System.out.print("0.1-0.2|"); | |||
for (i=0; i<intervals[1]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[1] + ")"); | |||
System.out.print("0.2-0.3|"); | |||
for (i=0; i<intervals[2]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[2] + ")"); | |||
System.out.print("0.3-0.4|"); | |||
for (i=0; i<intervals[3]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[3] + ")"); | |||
System.out.print("0.4-0.5|"); | |||
for (i=0; i<intervals[4]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[4] + ")"); | |||
System.out.print("0.5-0.6|"); | |||
for (i=0; i<intervals[5]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[5] + ")"); | |||
System.out.print("0.6-0.7|"); | |||
for (i=0; i<intervals[6]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[6] + ")"); | |||
System.out.print("0.7-0.8|"); | |||
for (i=0; i<intervals[7]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[7] + ")"); | |||
System.out.print("0.8-0.9|"); | |||
for (i=0; i<intervals[8]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[8] + ")"); | |||
System.out.print("0.9-1 |"); | |||
for (i=0; i<intervals[9]; i++) { | |||
System.out.print("*"); | |||
} | |||
System.out.println(" (" + intervals[9] + ")"); | |||
} | |||
public void printStats() { | |||
totalAlpha=0; | |||
totalProfit=0; | |||
int i; | |||
for (i=0; i<100; i++) { | |||
totalalpha+=farmers[i].getAlpha(); | |||
totalprofit+=farmers[i].getProfit(); | |||
} | |||
System.out.println("Average alpha: " + (totalAlpha/100)); | |||
System.out.println("Average profit: " + (totalProfit/100)); | |||
System.out.println("Current price for Corn: " + currentCornPrice); | |||
System.out.println("Current price for Rice: " + currentRicePrice); | |||
} | |||
public void changePrices() { | |||
currentCornPrice = (float)(X)/totalAlpha; | |||
currentRicePrice = (float)(Y)/totalAlpha; | |||
} | |||
public void maximize(int i) { | |||
float temp = totalAlpha - farmers[i].getAlpha(); | |||
//check if 0 or 1 is better strategy. | |||
float t = (currentRicePrice - currentCornPrice + b - d + 2 * c) / (2 * a + 2 * c); | |||
if ((currentCornPrice - (-a * t + b)) * t + (currentRicePrice - (-c * (1-t) + d)) * (1-t) < (currentCornPrice - (-a + b))) { | |||
t = 1 | |||
} | |||
if ( | |||
farmer fake = new farmer() | |||
farmers[i].setProfit(); | |||
totalAlpha = temp + farmers[i].getAlpha(); | |||
} | |||
public static void main(String[] argv) throws IOException { | |||
farmerGame thisGame = new farmerGame(argv[0].equals("even")); | |||
thisGame.a = Float.parseFloat(argv[1]); | |||
thisGame.b = Float.parseFloat(argv[2]); | |||
thisGame.c = Float.parseFloat(argv[3]); | |||
thisGame.d = Float.parseFloat(argv[4]); | |||
thisGame.X = Float.parseFloat(argv[5]); | |||
thisGame.Y = Float.parseFloat(argv[6]); | |||
thisGame.changePrices(); | |||
} | |||
} | |||
'''''Farmer OBJECT''''' | |||
</nowiki> | |||
The zip file containing all the source code and .class files along with the instructions can be downloaded here: [[http://www.dickinson.edu/~araih/FarmerGame.zip]] | |||
== Results== | |||
In general, we seemed to get two different results: one where all the farmers choose an alpha value somewhere near the middle, more towards the crop with the higher payoff (for a good example of this, try doing farmerGame even 2 3 1 2 50 50), and the other where a certain number of farmers profess in one crop, while the others profess in the other, where more farmers profess in the crop with the higher payoff (for a good example of this, try doing farmerGame even 1 1 1 1 50 50). The split game and the converging game seem to happen at a random probability, for example 1 1 1 1 10 10 converges but 1 1 1 1 10 100 splits. We have yet to come up with a definite mathematical correlation for what causes the switch, but once the game enters one of these patterns, it steadily heads to a NASH equalibrium where none of the farmers will change their strategy. |
Latest revision as of 15:43, 5 May 2006
What are we trying to do here?
Picture a hundred farmers in a simple economy, where two crops are farmed: Rice and Corn. In a similar manner as the fisherman’s dilemma, in which a day’s output for one fisherman far affects the yield of the other fisherman, the amount of corn produced affects how much rice is produced. Each crop has a separate price and cost curve, rather than a matrix which we are used to (in fact, you can think of the values of the matrix as points on the curve). Each farmer has to make their individual decision, given the current point on the curves, of what percentage of total yield to devote to corn and rice. Given 100 farmers and different sets of functions, will a stable Nash Equilibrium be reached?
Why make a computer simulation of a simple game?
There are many games with very simple rules or agents result in complex aggregate results. These results are not necessarily very predicable–while there are only a number of desirable outcomes with 2x2 games, games which involve hundreds of agents making many moves in succession are rather unpredictable. Our simulation is a simple model of a broad market; the Farmers in this game are stupid-their thought logic is simple, and they don't have the ability to take past mistakes into account to make predictions about the future. By default, there is a possibility that there are systems that will not reach a NASH equalibrium, since it will not take in account past data points to straighten itself. However, despite low intelligence and near perfect information (classical game theory), each farmer will indirectly be influencing the decisions of the other farmers, which could bring some interesting results.
Implementation
100 digital farmers will be generated. Of importance to a farmer:
1)A fixed production capacity at 1 (noted as 100% on the cost function).
2)An alpha value, which is defined as the percentage of corn he wishes to produce.
3)(1-alpha) is the percentage of his yield that is rice.
4)Price functions. Each farmer will try to maximize their profit according to the price of crops in the market and the profit function. The price function for rice will take the form similar to P = A/X , where where p is profit, A is a constant, and X is the quantity of crops the farmer is producing, with no asymptote--the more units of a product produced, the less the production cost (usually) is. The price function of corn will also be determined by a P = B/X function, this time P standing for price of the crop, B is some constant, and X is the total number of the crop being produced.
Figure 1: The Price and Cost Functions
The cost function is a simple direct relationship: as the amount of corn or rice produced increases, the cost decreases by slope -a or -c.
The maximation function
The economic actors in this experiment are programmed to maximize their returns and minimize the strategies of other actors. Given the information in figure 1, digital farmers will try to maximize x, the amount of crop to produce, given the following maximazation function:
Figure 2: Maximation Function of Farmer
The Overall Flow of the Simulation
1) The program first creates 100 farmers, with either random alpha values or evenly spread out alpha values. Therefore, each farmer will start with a different starting preference for how much corn to make.
2) The farmers are indexed, and using the fixed inverse price curves shown above, farmers one at a time will try a best response function (function maximize), until all farmers have had a chance to maximize or change strategies.
3) A frequency distribution graph will output the distribution of alpha levels at the end of each round of play.
4) There are 100 rounds of play. Therefore, as a default, we expect at some point for the distributions from round to round to stabilize. This would be a sign of Nash Equilibrium.
The Code of the Program
The programming was done in jEdit on the computers at the Tome Scientific building. The project consisted of a file which held the implementation functions and another file which defined the object FARMER. From a programming perspective, many functions which could have been publicly defined in the FARMER class were globalized and inserted into the implementation/main function file.
farmerGame.java
import java.io.*; public class farmerGame { private farmers[]; private int intervals[] = new int[10]; private float currentCornPrice; private float currentRicePrice; private float a; private float b; private float c; private float d; private float X; private float Y; private float totalAlpha; private float totalProfit; public farmerGame(boolean i); { totalAlpha = 0; int i; farmers = new farmer[100]; if (i) { for (i=0; i<100; i++) { farmers[i].setAlpha((float)i/100); } } else { for (i=0; i<100; i++) { farmers[i].setAlpha(Math.random()); } } for (i=0; i<100; i++) { intervals[(int)(farmers[i].getAlpha() * 100)]++; } } public void drawGraph() { int i; System.out.print("0-0.1 |"); for (i=0; i<intervals[0]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[0] + ")"); System.out.print("0.1-0.2|"); for (i=0; i<intervals[1]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[1] + ")"); System.out.print("0.2-0.3|"); for (i=0; i<intervals[2]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[2] + ")"); System.out.print("0.3-0.4|"); for (i=0; i<intervals[3]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[3] + ")"); System.out.print("0.4-0.5|"); for (i=0; i<intervals[4]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[4] + ")"); System.out.print("0.5-0.6|"); for (i=0; i<intervals[5]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[5] + ")"); System.out.print("0.6-0.7|"); for (i=0; i<intervals[6]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[6] + ")"); System.out.print("0.7-0.8|"); for (i=0; i<intervals[7]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[7] + ")"); System.out.print("0.8-0.9|"); for (i=0; i<intervals[8]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[8] + ")"); System.out.print("0.9-1 |"); for (i=0; i<intervals[9]; i++) { System.out.print("*"); } System.out.println(" (" + intervals[9] + ")"); } public void printStats() { totalAlpha=0; totalProfit=0; int i; for (i=0; i<100; i++) { totalalpha+=farmers[i].getAlpha(); totalprofit+=farmers[i].getProfit(); } System.out.println("Average alpha: " + (totalAlpha/100)); System.out.println("Average profit: " + (totalProfit/100)); System.out.println("Current price for Corn: " + currentCornPrice); System.out.println("Current price for Rice: " + currentRicePrice); } public void changePrices() { currentCornPrice = (float)(X)/totalAlpha; currentRicePrice = (float)(Y)/totalAlpha; } public void maximize(int i) { float temp = totalAlpha - farmers[i].getAlpha(); //check if 0 or 1 is better strategy. float t = (currentRicePrice - currentCornPrice + b - d + 2 * c) / (2 * a + 2 * c); if ((currentCornPrice - (-a * t + b)) * t + (currentRicePrice - (-c * (1-t) + d)) * (1-t) < (currentCornPrice - (-a + b))) { t = 1 } if ( farmer fake = new farmer() farmers[i].setProfit(); totalAlpha = temp + farmers[i].getAlpha(); } public static void main(String[] argv) throws IOException { farmerGame thisGame = new farmerGame(argv[0].equals("even")); thisGame.a = Float.parseFloat(argv[1]); thisGame.b = Float.parseFloat(argv[2]); thisGame.c = Float.parseFloat(argv[3]); thisGame.d = Float.parseFloat(argv[4]); thisGame.X = Float.parseFloat(argv[5]); thisGame.Y = Float.parseFloat(argv[6]); thisGame.changePrices(); } } '''''Farmer OBJECT'''''
The zip file containing all the source code and .class files along with the instructions can be downloaded here: [[1]]
Results
In general, we seemed to get two different results: one where all the farmers choose an alpha value somewhere near the middle, more towards the crop with the higher payoff (for a good example of this, try doing farmerGame even 2 3 1 2 50 50), and the other where a certain number of farmers profess in one crop, while the others profess in the other, where more farmers profess in the crop with the higher payoff (for a good example of this, try doing farmerGame even 1 1 1 1 50 50). The split game and the converging game seem to happen at a random probability, for example 1 1 1 1 10 10 converges but 1 1 1 1 10 100 splits. We have yet to come up with a definite mathematical correlation for what causes the switch, but once the game enters one of these patterns, it steadily heads to a NASH equalibrium where none of the farmers will change their strategy.