Computer Generated Farmers: Information and Nash Equilibrium: Difference between revisions
(One intermediate revision by the same user not shown) | |||
Line 250: | Line 250: | ||
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]] | 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]] | ||
== | == Analysis == | ||
In general, we seemed to get two different results: | In general, we seemed to get two different results: | ||
Line 267: | Line 267: | ||
[[Image:Garph6.JPG]] | [[Image:Garph6.JPG]] | ||
We know that because of the stabilization that occured in the distributions as the game progressed, both results are Nash equilibria. However, it is difficult to tell if either is Pareto-Optimal. | |||
[[Image:Mcphail.JPG ]] |
Latest revision as of 16:54, 5 May 2006
What we are trying to do
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 maximization 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 farmer farmers[] = new farmer[100]; 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; totalProfit = 0; int e; for (e=0; e < 10; e++) { intervals[e] = 0; } for (e=0; e<100; e++) { farmers[e] = new farmer(); } if (i) { for (e=0; e<100; e++) { float f = (float)e; farmers[e].setAlpha(f/100); } } for (e=0; e<100; e++) { if (farmers[e].getAlpha() == 1) { intervals[9]++; } else { intervals[(int) (farmers[e].getAlpha() * 10)]++; } totalAlpha+=farmers[e].getAlpha(); changePrices(); farmers[e].setProfit(currentCornPrice - (-1 * a * farmers[e].getAlpha() + b) * farmers[e].getAlpha() + (currentRicePrice - (-1 * c * (1-farmers[e].getAlpha()) * (1-farmers[e].getAlpha()) + d * (1-farmers[e].getAlpha())))); totalProfit = totalProfit + farmers[e].getProfit(); } } public void drawGraph() { int i; for (i=0; i<10; i++) { intervals[i] = 0; } for (i=0; i<100; i++) { if (farmers[i].getAlpha() == 1) { intervals[9]++; } else { intervals[(int) (farmers[i].getAlpha() * 10)]++; } } 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() { int i; 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)/(100 - totalAlpha); } public void maximize(int i) { float temp = totalAlpha - farmers[i].getAlpha(); totalProfit-= farmers[i].getProfit(); float t = (currentRicePrice - currentCornPrice + b - d + 2 * c) / (2 * a + 2 * c); if (t>1 || t<0) { if ((currentCornPrice - (-1 * a + b)) >= (currentRicePrice - (-1 * c + d))) { t = 1; } else { t = 0; } } farmers[i].setAlpha(t); farmers[i].setProfit((currentCornPrice - (-1 * a * t + b)) * t + (currentRicePrice - (-1 * c * (1-t) + d)) * (1-t)); totalAlpha = temp + farmers[i].getAlpha(); totalProfit+=farmers[i].getProfit(); changePrices(); } public static void main(String[] argv) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 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(); System.out.println("Game created"); String command = "a"; int i = 0; while (!command.equalsIgnoreCase("quit")) { System.out.print("Enter command: "); command = in.readLine(); if (command.equalsIgnoreCase("printstats")) { thisGame.printStats(); } else if (command.equalsIgnoreCase("drawgraph")) { thisGame.drawGraph(); } else if (command.equalsIgnoreCase("all")) { for (int e=0; e < 100; e++) { thisGame.intervals[(int)thisGame.farmers[i].getAlpha()]--; thisGame.maximize(i); thisGame.intervals[(int)thisGame.farmers[i].getAlpha()]++; i++; if (i == 100) { i = 0; } } System.out.println("All 100 farmers have moved."); } else if (command.equalsIgnoreCase("single")) { thisGame.intervals[(int)thisGame.farmers[i].getAlpha()]--; thisGame.maximize(i); thisGame.intervals[(int)thisGame.farmers[i].getAlpha()]++; i++; if (i == 100) { i = 0; } } else if (command.equalsIgnoreCase("quit")) { } else { System.out.println("Incorrect command"); } } } }
The zip file containing all the source code and .class files along with the instructions can be downloaded here: [[1]]
Analysis
In general, we seemed to get two different results:
1)A certain number of farmers profess in one crop, while the others profess in the other-- 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).
2)All 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).
We did not expect the fact that 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 (the distributions become stabilized from round to round and change less). The resulting two distributions are similar to the end result of the segregated neighborhoods problem discussed in Chapter 2 of Samuel Bowles' Microeconomics: Behavior, Institutions, and Evolution. It is also similar to the game pattern below.
Figure 3:
We know that because of the stabilization that occured in the distributions as the game progressed, both results are Nash equilibria. However, it is difficult to tell if either is Pareto-Optimal.