📄 ant.java
字号:
package sim.app.antsforage;import sim.field.grid.*;import sim.portrayal.*;import sim.util.*;import sim.engine.*;import java.awt.*;public /*strictfp*/ class Ant extends SimplePortrayal2D implements Steppable { public static final int ADD_PHEROMONE = 0; public static final int MAX_PHEROMONE = 1; public static final int LOCAL_PHEROMONE = 2; public static final int PHEROMONE_TYPE = LOCAL_PHEROMONE; public static final boolean TOROIDAL_WORLD = false; // type of Ant public static final int ORIENTED_ANT = 0; public static final int NSEW_ANT = 1; public static final int EIGHT_NEIGHBOURS_ANT = 2; public static final int ANT_TYPE = ORIENTED_ANT; public static final boolean GREEDY_REPOSITIONING = true; public static final boolean GREEDY_EXPLORATION = true; public static final int N = 0; public static final int NE = 1; public static final int E = 2; public static final int SE = 3; public static final int S = 4; public static final int SW = 5; public static final int W = 6; public static final int NW = 7; public double pheromoneToLeaveBehind; public double minPheromone; public double maxPheromone; public int timeToLive; double subtractingRatio; double pheromoneRatio; int orientation; public boolean getHasFoodItem() { return hasFoodItem; } public void setHasFoodItem(boolean val) { hasFoodItem = val; } public boolean hasFoodItem; public static final double ANT_K = 0.001; public static final double ANT_N = 10.0; boolean justCreated; public Ant( int orientation, double pheromoneToLeaveBehind, double minPheromone, double maxPheromone, int timeToLive ) { this.orientation = orientation; this.pheromoneToLeaveBehind = pheromoneToLeaveBehind; this.minPheromone = minPheromone; this.maxPheromone = maxPheromone; this.timeToLive = timeToLive; subtractingRatio = ( 1.0 / timeToLive ) * maxPheromone; pheromoneRatio = 1.0 * maxPheromone; hasFoodItem = false; justCreated = true; } protected void addInformation( final SimState state, int x, int y, final int orientation ) { final AntsForage af = (AntsForage)state; final DecisionInfo di = af.decisionInfo; final DecisionMaker decisionMaker = af.decisionMaker; if( TOROIDAL_WORLD ) { x = (x+AntsForage.GRID_WIDTH)%AntsForage.GRID_WIDTH; y = (y+AntsForage.GRID_HEIGHT)%AntsForage.GRID_HEIGHT; } else { if( x < 0 || x >= AntsForage.GRID_WIDTH || y < 0 || y >= AntsForage.GRID_HEIGHT ) return; } if( ( af.buggrid.getObjectsAtLocation(x,y) == null || af.buggrid.getObjectsAtLocation(x,y).numObjs < AntsForage.MAX_ANTS_PER_LOCATION ) && af.obstacles.field[x][y] <= 0.5 ) { // toroidal coordinates! di.position.x = x; di.position.y = y; di.orientation = orientation;// di.homePheromoneAmount = /*Strict*/Math.pow( ANT_K + ((AntsForage)state).toHomeGrid.field[di.position.x][di.position.y], ANT_N) ;// di.foodPheromoneAmount = /*Strict*/Math.pow( ANT_K + ((AntsForage)state).toFoodGrid.field[di.position.x][di.position.y], ANT_N );; di.homePheromoneAmount = 0.001 + af.toHomeGrid.field[di.position.x][di.position.y]; di.foodPheromoneAmount = 0.001 + af.toFoodGrid.field[di.position.x][di.position.y]; decisionMaker.addInfo( di ); } } public DecisionInfo decideAction( final SimState state, final int myx, final int myy, final int orientation ) { final AntsForage af = (AntsForage)state; final DecisionMaker decisionMaker = af.decisionMaker; decisionMaker.reset(); // collect the sensory information for the new grid model // this should be done separately in the model, but whatever.... switch( ANT_TYPE ) { case ORIENTED_ANT: switch( orientation ) { case 0: addInformation( state, myx-1, myy+1, (orientation+7)%8 ); // forward-left addInformation( state, myx, myy+1, orientation ); // forward addInformation( state, myx+1, myy+1, (orientation+1)%8 ); // forward-right break; case 1: addInformation( state, myx, myy+1, (orientation+7)%8 ); // forward-left addInformation( state, myx+1, myy+1, orientation ); // forward addInformation( state, myx+1, myy, (orientation+1)%8 ); // forward-right break; case 2: addInformation( state, myx+1, myy+1, (orientation+7)%8 ); // forward-left addInformation( state, myx+1, myy, orientation ); // forward addInformation( state, myx+1, myy-1, (orientation+1)%8 ); // forward-right break; case 3: addInformation( state, myx+1, myy, (orientation+7)%8 ); // forward-left addInformation( state, myx+1, myy-1, orientation ); // forward addInformation( state, myx, myy-1, (orientation+1)%8 ); // forward-right break; case 4: addInformation( state, myx+1, myy-1, (orientation+7)%8 ); // forward-left addInformation( state, myx, myy-1, orientation ); // forward addInformation( state, myx-1, myy-1, (orientation+1)%8 ); // forward-right break; case 5: addInformation( state, myx, myy-1, (orientation+7)%8 ); // forward-left addInformation( state, myx-1, myy-1, orientation ); // forward addInformation( state, myx-1, myy, (orientation+1)%8 ); // forward-right break; case 6: addInformation( state, myx-1, myy-1, (orientation+7)%8 ); // forward-left addInformation( state, myx-1, myy, orientation ); // forward addInformation( state, myx-1, myy+1, (orientation+1)%8 ); // forward-right break; case 7: addInformation( state, myx-1, myy, (orientation+7)%8 ); // forward-left addInformation( state, myx-1, myy+1, orientation ); // forward addInformation( state, myx, myy+1, (orientation+1)%8 ); // forward-right break; } break; case NSEW_ANT: addInformation( state, myx-1, myy, (orientation+7)%8 ); // N addInformation( state, myx+1, myy, (orientation+7)%8 ); // S addInformation( state, myx, myy-1, (orientation+7)%8 ); // E addInformation( state, myx, myy+1, (orientation+7)%8 ); // W break; case EIGHT_NEIGHBOURS_ANT: addInformation( state, myx-1, myy-1, (orientation+7)%8 ); // N addInformation( state, myx-1, myy, (orientation+7)%8 ); // N addInformation( state, myx-1, myy+1, (orientation+7)%8 ); // N addInformation( state, myx+1, myy-1, (orientation+7)%8 ); // S addInformation( state, myx+1, myy, (orientation+7)%8 ); // S addInformation( state, myx+1, myy+1, (orientation+7)%8 ); // S addInformation( state, myx-1, myy, (orientation+7)%8 ); // E addInformation( state, myx+1, myy, (orientation+7)%8 ); // W break; } if( hasFoodItem ) return decisionMaker.getHomeGreedyDecision( state ); else { if( GREEDY_EXPLORATION ) return decisionMaker.getFoodGreedyDecision( state ); else return decisionMaker.getFoodDecision( state ); } } public void addPheromone(DoubleGrid2D grid, int x, int y, double pheromone) { switch( PHEROMONE_TYPE ) { case ADD_PHEROMONE: grid.field[x][y] += /*Strict*/Math.abs(pheromoneToLeaveBehind); if (grid.field[x][y] > maxPheromone) grid.field[x][y] = maxPheromone; break; case MAX_PHEROMONE: grid.field[x][y] = /*Strict*/Math.max( grid.field[x][y], pheromone ); break; case LOCAL_PHEROMONE: double amount = /*Strict*/Math.max( grid.field[x][y], pheromone ); if( x > 0 && y > 0 ) amount = /*Strict*/Math.max( /*Strict*/Math.max( grid.field[x-1][y-1]-subtractingRatio, minPheromone ), amount ); if( x > 0) amount = /*Strict*/Math.max( /*Strict*/Math.max( grid.field[x-1][y]-subtractingRatio, minPheromone ), amount ); if( x > 0 && y < grid.field[x].length-1 ) amount = /*Strict*/Math.max( /*Strict*/Math.max( grid.field[x-1][y+1]-subtractingRatio, minPheromone ), amount ); if( y > 0 ) amount = /*Strict*/Math.max( /*Strict*/Math.max( grid.field[x][y-1]-subtractingRatio, minPheromone ), amount ); if( y < grid.field.length-1 ) amount = /*Strict*/Math.max( /*Strict*/Math.max( grid.field[x][y+1]-subtractingRatio, minPheromone ), amount ); if( x < grid.field.length-1 && y > 0 ) amount = /*Strict*/Math.max( /*Strict*/Math.max( grid.field[x+1][y-1]-subtractingRatio, minPheromone ), amount ); if( x < grid.field.length-1 ) amount = /*Strict*/Math.max( /*Strict*/Math.max( grid.field[x+1][y]-subtractingRatio, minPheromone ), amount );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -