?? wealthmodel.java
字號:
/*$$ * packages uchicago.src.* * Copyright (c) 1999, Trustees of the University of Chicago * All rights reserved. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the following * conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the University of Chicago nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Nick Collier * nick@src.uchicago.edu * * packages cern.jet.random.* * Copyright (c) 1999 CERN - European Laboratory for Particle * Physics. Permission to use, copy, modify, distribute and sell this * software and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies * and that both that copyright notice and this permission notice appear in * supporting documentation. CERN makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without expressed or implied warranty. * * Wolfgang Hoschek * wolfgang.hoschek@cern.ch *$$*/package tom.edu.csustan.astarte;import java.util.Vector;import java.util.ArrayList;import java.util.Arrays;import java.util.Random;import java.util.ListIterator;import java.awt.Color;import java.util.Collections;import java.lang.Math;import uchicago.src.reflector.ListPropertyDescriptor;import uchicago.src.sim.space.*;import uchicago.src.sim.engine.*;import uchicago.src.sim.gui.*;import uchicago.src.sim.util.SimUtilities;import uchicago.src.sim.analysis.*;import cern.jet.random.Uniform;import cern.jet.random.Normal;import uchicago.src.reflector.BooleanPropertyDescriptor;// Simulation models should extend SimModelImpl which does some basic setup// and allows a controller easy access to a simulations initial parameters.public class WealthModel extends SimModelImpl { // Every model must have a schedule private Schedule schedule; // A list of all the agents. Convenient for any method that // iterates through a list of agents. A least one list like this is common // to most simulations. See below for examples of its use.// private ArrayList agentList = new ArrayList(); public static ArrayList agentList = new ArrayList(); // A list of WealthAgents who have been "birthed" and should be introduced // to the simulation in the next turn private Vector birthList = new Vector(); // The Wealth Space - the agent's environment consisting of variable // amounts of wealth arranged on a grid private WealthSpace space; // The 2 dimensional torusr on which the agents act. private static Object2DTorus agentGrid; // A queue that tracks dead agents. private Vector reaperQueue = new Vector(); // A DataRecorder or ObjectDataRecorder allows data generated by // a simulation to be written to a file // Note to self: lines beginning //** should be uncommented to record data private DataRecorder recorder; // default and modifiable parameters of the model private String behaviour = "Both"; // Behaviour of agents public static boolean Exchange = false; // Do exchange model public static boolean Both = false; // Combine exchange and investment economies public static boolean DeathTax = false; // Implement "death tax" public static int MaxAge = 1200; // Age for "death tax" (if turned on) private int MaxInitialWealth = 110; // Maximum initial wealth for agents private int MinInitialWealth = 90; // Minimum initial wealth for agents public static double MinWealth = 1.0; // Minimum wealth public static boolean Moving = false; // Do agents move (for exchange or "synch" models) private static int NumAgents = 1500; // Total number of agents (must be <= 2500) private static int NumLogLogBins = 30; // Number of bins for log:log plot private static int NumPlainBins = 100; // Number of bins for plain plot private static double PlainPlotXMax = 300.0;// Maximum X (wealth) plotted in plain plot (-1 = any) private static double PlainPlotYMax = -1.0; // Maximum Y (P_i) plotted in plain plot (-1 = any) private static boolean PlotLogLog = true; // Whether to display log:log plot private static boolean PlotPlain = true; // Whether to display plain plot public static boolean ROI = false; // Whether to do investment economy (only) public static double ROIMean = 0.00; // Mean return on investment public static double ROIStdDev = 0.05; // Standard deviation of normal dist. of return public static boolean RandomWalk = false; // Whether to do individual random walk public static boolean Smarter = false; // Are some agents smarter? public static int SmarterNum = 50; // 1 in SmarterNum is smarter. public static boolean Sync = false; // Whether to run the sync model instead public static double SyncLatency = 3.0; // Latency in sync mode after "flash" public static int SyncMax = 150; // Max value in sync model public static boolean SyncRegion = true; // Do agents affect only nearbys or everybody (in sync) public static int TaxPCT = 10; // Tax rate for death tax private static boolean ViewAvg = true; // Whether to show average wealth of all agents private static boolean ViewStDAvg = true; // Whether to show moving average of Std. Dev. of wealth of all agents private static boolean ViewStDev = true; // Whether to show standard deviation of wealth of all agents private static boolean ViewStats = true; // Whether to show average wealth of all agents private static boolean WriteStats = false; // Whether to write stats out to a file on pause or stop private static boolean ViewPowerLawExp = true; // Whether to show power law exponent private static int RichMinPct = 90; // Rich above what per cent . . . private static boolean ViewEntropy = true; // Whether to show entropy private static int entropyBin = 5; // size of bins for calculating entropy private boolean replace = true; private static int MAvgRange = 1000; private static double[] StDAvg = new double[MAvgRange]; private static int stepModMAvgRange = 0; private static boolean testing = false; private static int step = 0; // The surface on which the agents and their environment are displayed private DisplaySurface dsurf; // A graph that plots sequence private OpenSequenceGraph statsGraph; // A graph for the "power law" exponent; private OpenSequenceGraph powerlawGraph; // A graph for the entropy; private OpenSequenceGraph entropyGraph; // A histogram for wealth private OpenHistogram bar; // A graph for log-log plot private Plot logLogPlot; // A graph for plain plot private Plot plainPlot; // A histogram for ages// private OpenHistogram barAge; // These inner classes are used by all the data collection methods - i.e. // DataRecorder, SequenceGraph and the Histogram. // All simulations should have a no argument constructor - this is empty and // thus not strictly necessary public WealthModel() { String[] props1 = new String[] {"Both", "Exchange", "ROI", "RandomWalk", "Sync"}; ListPropertyDescriptor pd1 = new ListPropertyDescriptor("Behaviour", props1); descriptors.put("Behaviour", pd1); Controller.ALPHA_ORDER = false; } // The typical way to code a simulation is to divide up the creation of the // simulation into three methods - buildModel(), buildDisplay(), // buildSchedule(). This division is not strictly necessary, but it does // make the creation conceptually clearer. // The buildModel() method is responsible for creating those parts of the // simulation that represent what is being modeled. Consequently, the agents // and their environment are typically created here together with any // optional data collection objects. Of course, this method may call other // methods to help build the model. private void buildModel() { // creates the wealth space using the values in wealthspace.pgm as // the amount of wealth (see WealthSpace.java for more). // space = new WealthSpace("/WealthModel/wealthspace.pgm"); space = new WealthSpace("/wealthspace.pgm"); agentGrid = new Object2DTorus(space.getXSize(), space.getYSize()); // createNormal(ROIMean, ROIStdDev); for (int i = 0; i < NumAgents; i++) { addNewAgent(); } // create a new DataRecorder and write the data to ./wealth_data.txt if (WriteStats) { recorder = new DataRecorder("./wealth_data.txt", this); } // first we make an inner class that implements the DataSource interface // class AgentCountClass implements DataSource {// public Object execute() {// int i = agentList.size();// return new Integer(i);// }// }; class AgentWealthClass implements DataSource { public Object execute() { String s = " "; for (int i = 0; i < agentList.size(); i++) { WealthAgent agent = (WealthAgent)agentList.get(i); if (i < agentList.size() - 1) s = s + agent.getWealth() + ","; else s = s + agent.getWealth(); } return s; } };// recorder.addObjectDataSource("AgentCount", new AgentCountClass()); if (WriteStats) { recorder.addObjectDataSource("AgentWealth", new AgentWealthClass()); } // we could also have done the above with an anonymous inner class // recorder.addObjectDataSource("Agent Count", new DataSource() { // public Object execute() { // return new Integer(agentList.size()); // } // }); } // buildDisplay() builds those parts of the simulation that have to do with // displaying the simulation to a user. private void buildDisplay() { // Create a display to display the agentGrid on the screen. // This will display any Drawable contained within the Object2DTorus. // In a non-batch simulation the agents in a simulation will typically // implement the Drawable interface. Object2DDisplay agentDisplay = new Object2DDisplay(agentGrid); // Rather than have the agentDisplay iterating over each object in the // Object2DTorus, give the display a list of Drawables to display. agentDisplay.setObjectList(agentList); // Maps 4 shades of yellow to integers 1 - 4, and white to 0. ColorMap map = new ColorMap(); map.mapColor(4, new Color(255, 255, 0)); map.mapColor(3, new Color(255, 255, 255 / 3)); map.mapColor(2, new Color(255, 255, 255 / 2)); map.mapColor(1, new Color(255, 255, (int)(255 / 1.2))); map.mapColor(0, Color.white); // WealthSpace.getCurrentWealth returns an Object2DTorus containing an // Integer of value (0 - 4) at each x, y coordinate. Using the map created // above this Value2DDisplay will display will display each of these // Integers as a shade of yellow (or white, if the Integer == 0). Value2DDisplay wealthDisplay = new Value2DDisplay(space.getCurrentWealth(), map); // DisplaySurface does the actual drawing of the various displays on the // user's screen. Displays are displayed in the order they are added. // Our dsurf object is created in the setup() method dsurf.addDisplayableProbeable(wealthDisplay, "Wealth Space"); dsurf.addDisplayableProbeable(agentDisplay, "Agents"); // Histograms get their data from histogramItems. This creates an item // called wealth that gets its data by calling getWealth on each agent // in the agent list. bar.createHistogramItem("Wealth", agentList, new BinDataSource() { public double getBinValue(Object o) { WealthAgent agent = (WealthAgent)o; return agent.getWealth(); } },7 ,0); bar.setYRange(0, 1.0); if (ViewPowerLawExp) { powerlawGraph = new OpenSequenceGraph("Power Law Exponent", this); powerlawGraph.setXRange(0,200); powerlawGraph.setYRange(1.5,4.0); powerlawGraph.setAxisTitles("time", "exponent - alpha"); powerlawGraph.addSequence("alpha", new Sequence() { public double getSValue() { int nMin, n; double xMin, alpha = 0.0; double[] agentWealths = new double[agentList.size()]; for (int i = 0; i < agentList.size(); i++) { WealthAgent a = (WealthAgent) agentList.get(i); agentWealths[i] = a.getWealth(); } java.util.Arrays.sort(agentWealths); nMin = (int) Math.round(agentList.size() * RichMinPct / 100.0); n = agentList.size() - nMin + 1; xMin = agentWealths[nMin]; for (int i = nMin; i < agentList.size(); i++) { alpha = alpha + Math.log(agentWealths[i] / xMin); } alpha = 1 + n * (1 / alpha); return alpha; } }); } if (ViewEntropy) { entropyGraph = new OpenSequenceGraph("Entropy", this); entropyGraph.setXRange(0,200); entropyGraph.setYRange(1.5,4.0); entropyGraph.setAxisTitles("time", "entropy"); entropyGraph.addSequence("entropy", new Sequence() { public double getSValue() { int nBins; double wealthMax = 0.0, entropy = 0.0; for (int i = 0; i < agentList.size(); i++) { WealthAgent a = (WealthAgent) agentList.get(i); if ( a.getWealth() > wealthMax ) wealthMax = a.getWealth(); } nBins = (int) Math.floor(wealthMax/entropyBin) + 1; int[] agentCounts = new int[nBins]; for (int i = 0; i < nBins; i++) agentCounts[i] = 0; for (int i = 0; i < agentList.size(); i++) { WealthAgent a = (WealthAgent) agentList.get(i); agentCounts[(int) Math.floor(a.getWealth()/entropyBin)]++; } for (int i = 0; i < nBins; i++) if ( agentCounts[i] > 0 ) entropy = entropy + ((double) agentCounts[i] / agentList.size()) * Math.log((double) agentList.size() / agentCounts[i]); return entropy; } }); if (testing) { entropyGraph.addSequence("max wealth", new Sequence() { public double getSValue() { double wealthMax = 0.0; for (int i = 0; i < agentList.size(); i++) { WealthAgent a = (WealthAgent) agentList.get(i); if ( a.getWealth() > wealthMax ) wealthMax = a.getWealth(); } return wealthMax; } }); } } if (ViewStats || ViewAvg || ViewStDev || ViewStDAvg ) { statsGraph = new OpenSequenceGraph("Agent Stats.", this); statsGraph.setXRange(0, 200); statsGraph.setYRange(0, 200); statsGraph.setAxisTitles("time", "agent attributes"); if (ViewAvg) { statsGraph.addSequence("Avg. Wealth", new Sequence() { public double getSValue() { double totalWealth = 0; for (int i = 0; i < agentList.size(); i++) { WealthAgent a = (WealthAgent)agentList.get(i); totalWealth += a.getWealth(); } return totalWealth / agentList.size(); } }); } if (ViewStDev) { statsGraph.addSequence("Std. Dev. - Wealth", new Sequence() { public double getSValue() { double totalWealth = 0.0; double avgWealth = 0.0; double calcSD = 0.0; for (int i = 0; i < agentList.size(); i++) { WealthAgent a = (WealthAgent)agentList.get(i); totalWealth += a.getWealth(); } avgWealth = totalWealth / agentList.size(); for (int i = 0; i < agentList.size(); i++) { WealthAgent a = (WealthAgent)agentList.get(i); calcSD += (a.getWealth() - avgWealth) * (a.getWealth() - avgWealth); } calcSD = calcSD / agentList.size(); calcSD = Math.sqrt(calcSD); return calcSD; } }); } if (ViewStDAvg) { statsGraph.addSequence("Std. Dev. - Mvg. Avg.", new Sequence() { public double getSValue() { double totalWealth = 0.0; double avgWealth = 0.0; double calcSD = 0.0; for (int i = 0; i < agentList.size(); i++) { WealthAgent a = (WealthAgent)agentList.get(i); totalWealth += a.getWealth(); } avgWealth = totalWealth / agentList.size(); for (int i = 0; i < agentList.size(); i++) { WealthAgent a = (WealthAgent)agentList.get(i); calcSD += (a.getWealth() - avgWealth) * (a.getWealth() - avgWealth); } calcSD = calcSD / agentList.size(); calcSD = Math.sqrt(calcSD); stepModMAvgRange = (stepModMAvgRange + 1) % MAvgRange;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -