📄 experimentswarm.java
字号:
// Copyright James Marshall 2003. Freely distributable under the GNU General Public Licencepackage buffon;/*Scouting time (1-1000)Arousal decay rate (1-10)Classification divisor (1-3000)Fitness function: Difference between predicted size and actual size * -1000 - total scouting time*/import swarm.simtoolsgui.GUISwarmImpl;import swarm.activity.Schedule;import swarm.activity.ScheduleImpl;import swarm.activity.Activity;import swarm.analysis.EZGraph;import swarm.analysis.EZGraphImpl;import swarm.defobj.FArguments;import swarm.defobj.FArgumentsImpl;import swarm.defobj.FCall;import swarm.defobj.FCallImpl;import swarm.defobj.Zone;import swarm.Globals;import swarm.Selector;import swarm.objectbase.Swarm;import swarm.random.UniformIntegerDist;import swarm.random.UniformIntegerDistImpl;import java.util.LinkedList;import java.util.Iterator;import java.util.ListIterator;import buffon.WorldSwarm;import buffon.Ant;import buffon.SequenceAverager;/** The experiment swarm class */class ExperimentSwarm extends GUISwarmImpl{ /** The experiment schedule */ private swarm.activity.Schedule mExperimentSchedule; /** The world swarm */ private WorldSwarm mWorldSwarm; /** Array of scout ants */ private Ant[] mAnts; /** The size of the array of scout ants */ private static final int msNumAnts = 21; /** The experiment's random number generator */ private UniformIntegerDist mRandomGenerator; /** The experiment's list for ordering ants by fitness */ private LinkedList mFitnessOrderedList; /** The experiment's graph for displaying average ant fitness */ private EZGraph mFitnessGraph; /** The experiment's graph for displaying frequency of the one pass strategy */ private EZGraph mOnePassGraph; /** The experiment's graph for displaying average ant scouting time */ private EZGraph mScoutingTimeGraph; /** The sequence average for the experiments */ private SequenceAverager mSequenceAverager; /** The number of generations taken to reach full assesment accuracy */ private int mGenerationsToFullAccuracy; /** Full assesment accuracy achieved in this experiment? */ private boolean mFullAccuracyAchieved; /** The number of experiments to run */ private static final int msNumExperiments = 200; /** The number of generations to run each experiment for */ private static final int msNumGenerations = 60; /** The number of generations to average results over */ private static final int msNumGenerationsForAverage = 10; /** * Activates the experiment swarm * * @param swarmContext * * @return world swarm's activity */ public Activity activateIn(Swarm swarmContext) { super.activateIn(swarmContext); mExperimentSchedule.activateIn(this); return getActivity(); } /** * Builds the experiment swarm's objects * * @return this * * @throw RuntimeException if action could not be created * */ public Object buildObjects() { super.buildObjects(); mWorldSwarm = new WorldSwarm(getZone(), 10, 10); mRandomGenerator = new UniformIntegerDistImpl(Globals.env.globalZone); mFitnessOrderedList = new LinkedList(); mFitnessGraph = new EZGraphImpl(this.getZone(), "Ants' average fitness", "Time", "Fitness", "fitnessGraph"); buildAnts(); try { mFitnessGraph.createSequence$withFeedFrom$andSelector("average fitness", this, new Selector(this.getClass(), "getAverageAntFitness", false)); } catch (Exception exception) { throw new RuntimeException("Could not create action (" + exception.toString() + ")"); } mOnePassGraph = new EZGraphImpl(this.getZone(), "One-pass strategy frequency", "Time", "Frequency", "onePassGraph"); try { mOnePassGraph.createSequence$withFeedFrom$andSelector("one-pass", this, new Selector(this.getClass(), "getOnePassStrategyFrequency", false)); } catch (Exception exception) { throw new RuntimeException("Could not create action (" + exception.toString() + ")"); } mScoutingTimeGraph = new EZGraphImpl(this.getZone(), "Ants' average scouting time", "Time", "Scouting Time", "scoutingTimeGraph"); try { mScoutingTimeGraph.createSequence$withFeedFrom$andSelector("average scouting time", this, new Selector(this.getClass(), "getAverageScoutingTime", false)); } catch (Exception exception) { throw new RuntimeException("Could not create action (" + exception.toString() + ")"); } mSequenceAverager = new SequenceAverager(msNumGenerationsForAverage); return this; } /** * Builds the experiment swarm's ants * * @return void * */ public void buildAnts() { int l1, rand, arousalDecay, scoutingTime, classificationDivisor; boolean onePass; for (l1 = 0; l1 < msNumAnts; l1++) { rand = mRandomGenerator.getIntegerWithMin$withMax(0, 1); if (rand == 0) { onePass = false; } else { onePass = true; } arousalDecay = mRandomGenerator.getIntegerWithMin$withMax(1,Ant.msArousalDecayMax); scoutingTime = mRandomGenerator.getIntegerWithMin$withMax(1, Ant.msScoutingTimeMax); classificationDivisor = mRandomGenerator.getIntegerWithMin$withMax(1, Ant.msClassificationDivisorMax); mAnts[l1] = new Ant(mWorldSwarm, onePass, arousalDecay, scoutingTime, classificationDivisor, mRandomGenerator); } } /** * Creates an FCall object for invoking the specified method on the specified object * * @param Object to invoke method on * @param Method to invoke * * @return FCall object * */ private FCall createCall(Object target, String name) { try { Selector sel = new Selector (target.getClass (), name, false); FArguments fa = new FArgumentsImpl (getZone (), sel); return new FCallImpl (getZone (), target, sel, fa); } catch (Exception e) { e.printStackTrace (System.err); System.exit (1); } return null; } /** * Builds the experiment swarm's actions * * @return this * * @throws RuntimeException if cannot create action * */ public Object buildActions() { int l1, l2; FCall doTkEventsCall, updateStateCall, fitnessGraphStepCall, onePassGraphStepCall, scoutingTimeGraphStepCall, startNewExperimentCall; doTkEventsCall = createCall(getActionCache(), "doTkEvents"); updateStateCall = createCall(this, "updateState"); fitnessGraphStepCall = createCall(mFitnessGraph, "step"); onePassGraphStepCall = createCall(mOnePassGraph, "step"); scoutingTimeGraphStepCall = createCall(mScoutingTimeGraph, "step"); startNewExperimentCall = createCall(this, "startNewExperiment"); mExperimentSchedule = new ScheduleImpl(getZone()); try { for (l1 = 0; l1 < msNumExperiments; l1++) { for (l2 = 0; l2 < msNumGenerations; l2++) { mExperimentSchedule.at$createFAction(l1 * (msNumGenerations + 1) + l2, doTkEventsCall); mExperimentSchedule.at$createFAction(l1 * (msNumGenerations + 1) + l2, updateStateCall); mExperimentSchedule.at$createFAction(l1 * (msNumGenerations + 1) + l2, fitnessGraphStepCall); mExperimentSchedule.at$createFAction(l1 * (msNumGenerations + 1) + l2, onePassGraphStepCall); mExperimentSchedule.at$createFAction(l1 * (msNumGenerations + 1) + l2, scoutingTimeGraphStepCall); } mExperimentSchedule.at$createFAction(l1 * (msNumGenerations + 1) + l2, startNewExperimentCall); } mExperimentSchedule.at$createActionTo$message(msNumExperiments * (msNumGenerations + 1) + 1, this.getControlPanel(), new Selector(this.getControlPanel().getClass(), "setStateQuit", true)); } catch (Exception exception) { throw new RuntimeException("Could not create action (" + exception.toString() + ")"); } return this; } /** * Starts a new experiment and logs the results of the previous one * * @return void * */ public void startNewExperiment() { System.out.println(mSequenceAverager.getAverage() + ", " + mGenerationsToFullAccuracy); mGenerationsToFullAccuracy = 0; mFullAccuracyAchieved = false; mSequenceAverager = new SequenceAverager(msNumGenerationsForAverage); buildAnts(); } /** * Gets the frequency of the one pass strategy among the top 66% of the ant population * * @return The frequency of the one pass strategy among the top 66% of the ant population * */ public double getOnePassStrategyFrequency() { int totalOnePass = 0, totalAnts = 0; Ant ant; Iterator i; i = mFitnessOrderedList.iterator(); while (i.hasNext() && totalAnts < msNumAnts / 3) { ant = (Ant) i.next(); totalAnts++; if (ant.onePassStrategy()) { totalOnePass++; } } return (double) totalOnePass / totalAnts; } /** * Gets the average scouting time among the top 66% percent of the ant population * * @return The average scouting time among the top 66% percent of the ant population * */ public int getAverageScoutingTime() { int totalScoutingTime = 0, totalAnts = 0; Ant ant; Iterator i; i = mFitnessOrderedList.iterator(); while (i.hasNext() && totalAnts < msNumAnts / 3) { ant = (Ant) i.next(); totalAnts++; totalScoutingTime += ant.getScoutingTime(); } return totalScoutingTime / totalAnts; } /** * Gets the average fitness of the top 66% of the ant population * * @return average fitness of the top 66% of the ant population * */ public int getAverageAntFitness() { int totalFitness = 0, totalAnts = 0; Ant ant; Iterator i; i = mFitnessOrderedList.iterator(); while (i.hasNext() && totalAnts < msNumAnts / 3) { ant = (Ant) i.next(); totalAnts++; totalFitness += ant.getFitness(); } return totalFitness / totalAnts; } /** * Processes a generation of the ants * * @return void * */ public void updateState() { int l1, l2, l3, rand, nestSize, estimatedNestSize, fitness, averageFitness, correctAssessments = 0; ListIterator li1; Ant ant, offspring; mFitnessOrderedList.clear(); for (l1 = 0; l1 < msNumAnts; l1++) { averageFitness = 0; for (l2 = 0; l2 < 3; l2++) {// System.out.println("Ant (op: " + mAnts[l1].onePassStrategy() + " ad: " + mAnts[l1].getArousalDecayRate() + " st: " + mAnts[l1].getScoutingTime() + " cd: " + mAnts[l1].getClassificationDivisor() + ")"); // generate nest nestSize = 10 + l2 * 20; mWorldSwarm.newNest(nestSize, nestSize); nestSize = l2; mWorldSwarm.setAnt(mAnts[l1]); // let ant scout nest mWorldSwarm.resetAnt(true); if (mAnts[l1].onePassStrategy()) { for (l3 = 0; l3 < mAnts[l1].getScoutingTime(); l3++) { mWorldSwarm.updateState(); } } else { for (l3 = 0; l3 < mAnts[l1].getScoutingTime() / 2; l3++) { mWorldSwarm.updateState(); } mWorldSwarm.resetAnt(false); for (l3 = 0; l3 < mAnts[l1].getScoutingTime() / 2; l3++) { mWorldSwarm.updateState(); } } // get ant's evaluation of nest size estimatedNestSize = mAnts[l1].getNestSizeEstimate(); // assign ant's fitness fitness = nestSize - estimatedNestSize; if (fitness < 0) { fitness *= -1; } else { correctAssessments++; } fitness *= -1000; fitness -= mAnts[l1].getScoutingTime(); averageFitness += fitness;// System.out.println("estimated nest size at: " + estimatedNestSize + " (actual: " + nestSize + ")");// System.out.println("fitness: " + fitness); } averageFitness /= 3; mAnts[l1].assignFitness(averageFitness);// System.out.println("average fitness: " + averageFitness); } if (!mFullAccuracyAchieved && correctAssessments < msNumAnts * 3) { mGenerationsToFullAccuracy++; }// System.out.println(correctAssessments); // cull lowest scoring 33% of ant population and replace with offspring of top 66% for (l1 = 0; l1 < msNumAnts; l1++) { if (mFitnessOrderedList.size() == 0) { mFitnessOrderedList.addFirst(mAnts[l1]); } else { li1 = mFitnessOrderedList.listIterator(); while (li1.hasNext()) { ant = (Ant) li1.next(); if (ant.getFitness() < mAnts[l1].getFitness()) { li1.previous(); li1.add(mAnts[l1]); break; } } if (!li1.hasNext()) { mFitnessOrderedList.addLast(mAnts[l1]); } } } for (l1 = 0; l1 < msNumAnts / 3; l1++) { ant = (Ant) mFitnessOrderedList.removeLast(); for (l2 = 0; l2 < msNumAnts; l2++) { if (mAnts[l2] == ant) { mAnts[l2] = null; break; } } } li1 = mFitnessOrderedList.listIterator(); while (li1.hasNext()) { ant = (Ant) li1.next(); if (li1.hasNext()) { offspring = ant.mate((Ant) li1.next()); for (l1 = 0; l1 < msNumAnts; l1++) { if (mAnts[l1] == null) { mAnts[l1] = offspring; break; } } } } mSequenceAverager.addToSequence(this.getAverageScoutingTime()); // force garbage collection Runtime.getRuntime().gc(); } /** * ExperimentSwarm constructor * * @param zone to create the ExperimentSwarm in * * @return void * */ public ExperimentSwarm(Zone zone) { super(zone); mExperimentSchedule = null; mWorldSwarm = null; mAnts = new Ant[msNumAnts]; mRandomGenerator = null; mFitnessOrderedList = null; mFitnessGraph = null; mOnePassGraph = null; mScoutingTimeGraph = null; mSequenceAverager = null; mGenerationsToFullAccuracy = 0; mFullAccuracyAchieved = false; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -