📄 ant.java
字号:
// Copyright James Marshall 2003. Freely distributable under the GNU General Public Licencepackage buffon;import swarm.space.Discrete2d;import swarm.random.UniformIntegerDist;import swarm.random.UniformIntegerDistImpl;import swarm.Globals;import buffon.WorldSwarm;import java.lang.RuntimeException;/** The ant class */class Ant{ /** The world the ant exists in */ private WorldSwarm mWorld; /** The ant's horizontal position within the nest it is exploring */ private int mXPosition; /** The ant's vertical position within the nest it is exploring */ private int mYPosition; /** The rate at which the ant's arousal level decays */ private int mArousalDecayRate; /** The direction the ant is facing in (0 - 7: 0 = north, 7 = north-west) */ private int mHeading; /** The ant's arousal level */ private int mArousal; /** One-pass scouting strategy? */ private boolean mOnePass; /** The ant's scouting time */ private int mScoutingTime; /** The ant's classification divisor for assessing nest size from arousal level */ private int mClassificationDivisor; /** Should the ant deposit pheremone when moving? */ private boolean mDepositPheremone; /** The ant's (externally assigned) fitness */ private int mFitness; /** The ant's random number generator (random walk) */ private UniformIntegerDist mRandomGenerator; /** The maximum arousal decay rate */ public static final int msArousalDecayMax = 10; /** The maximum scouting time */ public static final int msScoutingTimeMax = 1000; /** The maximum classification divisor */ public static final int msClassificationDivisorMax = 3000; /** The parameterised crossover rate */ public static final double msParameterisedCrossoverRate = 0.1; /** The mutation rate */ public static final double msMutationRate = 0.01; /** The mutation percentage */ public static final double msMutationPercentage = 0.1; /** * Returns true if the ant is using a one-pass scouting strategy * * @return one-pass scouting strategy? * */ public boolean onePassStrategy() { return mOnePass; } /** * Gets the ant's arousal decay rate * * @return the ant's arousal decay rate * */ public int getArousalDecayRate() { return mArousalDecayRate; } /** * Gets the ant's scouting time * * @return the ant's scouting time * */ public int getScoutingTime() { return mScoutingTime; } /** * Gets the ant's classification divisor (for estimating nest size from arousal level) * * @return the ant's classification divisor * */ public int getClassificationDivisor() { return mClassificationDivisor; } /** * Gets the ant's arousal level * * @return the ant's arousal level * */ public int getArousalLevel() { return mArousal; } /** * Gets the ant's estimate of the nest size based on arousal level * * @return ant's estimate of nest size (0 = small, 1 = medium, 2 = large) * */ public int getNestSizeEstimate() { int estimate; estimate = mArousal / mClassificationDivisor; if (estimate > 2) { estimate = 2; } estimate = 2 - estimate; return estimate; } /** * Gets the ant's (externally assigned) fitness * * @return ant's fitness * */ public int getFitness() { return mFitness; } /** * Assigns a fitness to the ant * * @param fitness * * @return void * */ public void assignFitness(int fitness) { mFitness = fitness; } /** * Resets the ant to the entrance of the nest, resets the ant's arousal level and turns pheremone laying on/off * * @param xPosition * @param yPosition * @param depositPheremone * * @return void * */ public void reset(int xPosition, int yPosition, boolean depositPheremone) { mArousal = 0; mXPosition = xPosition; mYPosition = yPosition; mDepositPheremone = depositPheremone; } /** * Moves the ant, possibly depositing pheremone in the old location and detecting pheremone in the new location * * @return void * */ public void move() { boolean moved = false, headingChangesTried[]; int l1, headingChange, newHeading, turnDirection; // determine random turn direction turnDirection = mRandomGenerator.getIntegerWithMin$withMax(0, 1); if (turnDirection == 0) { turnDirection = -1; } // initialise memory of heading changes tried headingChangesTried = new boolean[3]; for (l1 = 0; l1 < 3; l1++) { headingChangesTried[l1] = false; } if (mDepositPheremone) { // deposit pheremone mWorld.getNest().putValue$atX$Y(2, mXPosition, mYPosition); } // move while (!moved) { headingChange = mRandomGenerator.getIntegerWithMin$withMax(-1, 3); if (headingChange == 3) { // temporary fix until poisson or gaussian distribution plugged in headingChange = 1; } else { if (headingChange > 0) { headingChange = 0; } } headingChangesTried[headingChange + 1] = true; newHeading = (mHeading + headingChange + 8) % 8; switch (newHeading) { case 0: if (mWorld.getNest().getValueAtX$Y(mXPosition, mYPosition - 1) >= 0) { mYPosition -= 1; moved = true; } break; case 1: if (mWorld.getNest().getValueAtX$Y(mXPosition + 1, mYPosition - 1) >= 0) { mXPosition += 1; mYPosition -= 1; moved = true; } break; case 2: if (mWorld.getNest().getValueAtX$Y(mXPosition + 1, mYPosition) >= 0) { mXPosition += 1; moved = true; } break; case 3: if (mWorld.getNest().getValueAtX$Y(mXPosition + 1, mYPosition + 1) >= 0) { mXPosition += 1; mYPosition += 1; moved = true; } break; case 4: if (mWorld.getNest().getValueAtX$Y(mXPosition, mYPosition + 1) >= 0) { mYPosition += 1; moved = true; } break; case 5: if (mWorld.getNest().getValueAtX$Y(mXPosition - 1, mYPosition + 1) >= 0) { mXPosition -= 1; mYPosition += 1; moved = true; } break; case 6: if (mWorld.getNest().getValueAtX$Y(mXPosition - 1, mYPosition) >= 0) { mXPosition -= 1; moved = true; } break; case 7: if (mWorld.getNest().getValueAtX$Y(mXPosition - 1, mYPosition - 1) >= 0) { mXPosition -= 1; mYPosition -= 1; moved = true; } break; default: throw new RuntimeException("newHeading out of range"); } if (moved) { mHeading = newHeading; } else { if (headingChangesTried[0] == true && headingChangesTried[1] == true && headingChangesTried[2] == true) { // reset memory of heading changes tried for (l1 = 0; l1 < 3; l1++) { headingChangesTried[l1] = false; } // turn mHeading += turnDirection + 8; mHeading = mHeading % 8; } } } // detect pheremone mArousal += mWorld.getNest().getValueAtX$Y(mXPosition, mYPosition) * 5; // decay arousal level mArousal -= mArousalDecayRate; if (mArousal < 0) { mArousal = 0; } // show ant is here on nest display mWorld.getNest().putValue$atX$Y(1, mXPosition, mYPosition); } /** * Mates the ant with another ant to produce an offspring * * @param other parent ant * * @return offspring ant * */ public Ant mate(Ant parent) { boolean iAmParent, offspringOnePass; int rand, offspringArousalDecay, offspringScoutingTime, offspringClassificationDivisor;; Ant offspring; // determine parent rand = mRandomGenerator.getIntegerWithMin$withMax(0, 1); if (rand == 0) { iAmParent = false; } else { iAmParent = true; } // select parent to inherit one pass strategy from rand = mRandomGenerator.getIntegerWithMin$withMax(1, 100); if ((iAmParent && rand > 100 * msParameterisedCrossoverRate) || (!iAmParent && rand <= 100 * msParameterisedCrossoverRate)) { offspringOnePass = mOnePass; } else { offspringOnePass = parent.mOnePass; } // mutate one pass strategy/* rand = mRandomGenerator.getIntegerWithMin$withMax(1, 100); if (rand <= 100 * msMutationRate) { offspringOnePass = !offspringOnePass; }*/ // select parent to inherit arousal decay rate from rand = mRandomGenerator.getIntegerWithMin$withMax(1, 100); if ((iAmParent && rand > 100 * msParameterisedCrossoverRate) || (!iAmParent && rand <= 100 * msParameterisedCrossoverRate)) { offspringArousalDecay = mArousalDecayRate; } else { offspringArousalDecay = parent.mArousalDecayRate; } // mutate arousal decay rate rand = mRandomGenerator.getIntegerWithMin$withMax(1, 100); if (rand <= 100 * msMutationRate) { rand = mRandomGenerator.getIntegerWithMin$withMax((int) (msArousalDecayMax * msMutationPercentage) * -1, (int) (msArousalDecayMax * msMutationPercentage)); offspringArousalDecay += rand; if (offspringArousalDecay < 1) { offspringArousalDecay = 1; } if (offspringArousalDecay > msArousalDecayMax) { offspringArousalDecay = msArousalDecayMax; } } // select parent to inherit scouting time from rand = mRandomGenerator.getIntegerWithMin$withMax(1, 100); if ((iAmParent && rand > 100 * msParameterisedCrossoverRate) || (!iAmParent && rand <= 100 * msParameterisedCrossoverRate)) { offspringScoutingTime = mScoutingTime; } else { offspringScoutingTime = parent.mScoutingTime; } // mutate scouting time rand = mRandomGenerator.getIntegerWithMin$withMax(1, 100); if (rand <= 100 * msMutationRate) { rand = mRandomGenerator.getIntegerWithMin$withMax((int) (msScoutingTimeMax * msMutationPercentage) * -1, (int) (msScoutingTimeMax * msMutationPercentage)); offspringScoutingTime += rand; if (offspringScoutingTime < 1) { offspringScoutingTime = 1; } if (offspringScoutingTime > msScoutingTimeMax) { offspringScoutingTime = msScoutingTimeMax; } } // select parent to inherit classification divisor from rand = mRandomGenerator.getIntegerWithMin$withMax(1, 100); if ((iAmParent && rand > 100 * msParameterisedCrossoverRate) || (!iAmParent && rand <= 100 * msParameterisedCrossoverRate)) { offspringClassificationDivisor = mClassificationDivisor; } else { offspringClassificationDivisor = parent.mClassificationDivisor; } // mutate classification divisor rand = mRandomGenerator.getIntegerWithMin$withMax(1, 100); if (rand <= 100 * msMutationRate) { rand = mRandomGenerator.getIntegerWithMin$withMax((int) (msClassificationDivisorMax * msMutationPercentage) * -1, (int) (msClassificationDivisorMax * msMutationPercentage)); offspringClassificationDivisor += rand; if (offspringClassificationDivisor < 1) { offspringClassificationDivisor = 1; } if (offspringClassificationDivisor > msClassificationDivisorMax) { offspringClassificationDivisor = msClassificationDivisorMax; } } offspring = new Ant(mWorld, offspringOnePass, offspringArousalDecay, offspringScoutingTime, offspringClassificationDivisor, mRandomGenerator); return offspring; } /** * Ant constructor * * @param world the ant exists in * @param one-pass scouting strategy? * @param the ant's arousal decay rate * @param the ant's scouting time * @param the ant's classification divisor for assessing nest size from arousal level * * @return void * */ public Ant(WorldSwarm world, boolean onePass, int arousalDecayRate, int scoutingTime, int classificationDivisor, UniformIntegerDist randomGenerator) { mWorld = world; mXPosition = -1; mYPosition = -1; mArousalDecayRate = arousalDecayRate; mHeading = 0; mArousal = 0; mOnePass = onePass; mScoutingTime = scoutingTime; mClassificationDivisor = classificationDivisor; mDepositPheremone = true; mFitness = 0; mRandomGenerator = randomGenerator; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -