蚂蚁应根据其信息素水平进入四个方向之一,但我的蚂蚁永远不会去任何地方。我有一个Test和Runner类来测试这些方法,但除非我在wander()方法中放置一个不同的位置,否则蚂蚁永远不会出现(因为它们位于殖民地)。蚂蚁的位置与其邻居之间根本没有联系。
蚂蚁:
package antcolony;
import java.util.List;
import java.util.LinkedList;
import geo.Position;
import antcolony.simulation.Simulation;
import java.util.Random;
public class Ant {
private static int TIME_TO_GO_HOME = 15;
private Simulation sim;
private Position antPos;
private boolean isItHaveFood;
private double excitement;
private int time;
public Ant(Simulation sim, Position antColony) {
this.antPos = new Position(antColony.getX(), antColony.getY());
this.sim = sim;
}
public Position getPosition() {
return antPos;
}
public void setPosition(Position p) {
antPos = p;
}
public boolean isCarryingFood() {
return isItHaveFood;
}
public void moveTowardsColony() {
if(isCarryingFood() == true ) {sim.putPheromoneOn(antPos, excitement);
excitement *= 0.9;
}
}
public void simulateStep() {
if (isCarryingFood() == true && antPos.samePosition(sim.getColonyPosition())) {
isItHaveFood = false;
++sim.foodDelivered;
}
if (isCarryingFood() == false) {
excitement = 0;
time=0;
}
if (isCarryingFood() == true || time > TIME_TO_GO_HOME) {
moveTowardsColony();
}
if (sim.foodPresent(antPos) != null) {
isItHaveFood = true;
time += 1;
}
if (sim.foodPresent(antPos) != null && sim.getFoodSource().takeFood()) {
excitement = 1;
isItHaveFood = true;
moveTowardsColony();
sim.getFoodSource().takeFood();
}
wander();
}
public void wander() {
double d;
double max = 0.0;
antPos = sim.getColonyPosition();
for(int i = 0; i<antPos.neighbours(sim).size(); i++) {
if(sim.pheromoneOn(antPos.neighbours(sim).get(i)) > max) {
max = sim.pheromoneOn(antPos.neighbours(sim).get(i));
}
}
for(int j = 0; j<antPos.neighbours(sim).size(); j++) {
if(max == sim.pheromoneOn(antPos.neighbours(sim).get(j))) {
antPos = antPos.neighbours(sim).get(j);
//antPos = new Position((antPos.neighbours(sim).get(j).getX()), (antPos.neighbours(sim).get(j).getY()));
}
}
time++;
}
}
模拟:
package antcolony.simulation;
import java.util.Random;
import java.util.List;
import java.util.LinkedList;
import antcolony.Ant;
import antcolony.FoodSource;
import geo.Position;
public class Simulation {
public static Random random = new Random(0);
private double[][] pheromone;
public int foodDelivered = 0;
private List<Ant> ants;
private int size;
private Position colonyPosition;
private FoodSource foodSource;
public Simulation(int size, int antNumber, Position colonyPosition, FoodSource foodSource) {
ants = new LinkedList<Ant>();
for(int h = 0; h<antNumber; h++) {
ants.add(new Ant(this, colonyPosition));
}
this.size = size;
this.colonyPosition = colonyPosition;
this.foodSource = foodSource;
pheromone = new double[size][size];
}
public void getPheromone() {
for(int i = 0; i<size; i++) {
for(int j = 0; j<size; j++) {
System.out.println(pheromone[i][j]);
}
}
}
public void setPheromone(double d) {
for(int i = 0; i<size; i++) {
for(int j = 0; j<size; j++) {
pheromone[i][j] += d;
}
}
}
public void setFoodDelivered() {
foodDelivered += 1;
}
public FoodSource foodPresent(Position pos) {
if(foodSource.getPosition().samePosition(pos)) {
return foodSource;
} else {
return null;
}
}
public void simulateStep() {
for(int h = 0; h < ants.size(); h++) {
ants.get(h).simulateStep();
}
for(int i = 0; i<pheromone.length; i++) {
for(int j = 0; j<pheromone[i].length; j++) {
pheromone[i][j] *= 0.9;
}
}
}
public Position getColonyPosition() {
return colonyPosition;
}
public FoodSource getFoodSource() {
return foodSource;
}
public void putPheromoneOn(Position pos, double pher2) {
pheromone[pos.getX()][pos.getY()] += pher2;
}
public double pheromoneOn(Position pos) {
return pheromone[pos.getX()][pos.getY()];
}
public int getSize() {
return size;
}
public List<Ant> getAnts() {
return ants;
}
public boolean inside(Position pos) {
if(pos.getX() < getSize() && pos.getX() >= 0 && pos.getY() < getSize() && pos.getY() >= 0) {
return true;
} else {
return false;
}
}
}
位置
package geo;
import antcolony.simulation.Simulation;
import antcolony.Ant;
import java.util.List;
import java.util.LinkedList;
public class Position {
public int x, y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int n) {
x += n;
}
public int getY() {
return y;
}
public void setY(int n) {
y += n;
}
public boolean samePosition(Position pos) {
if(getX() == pos.getX() && getY() == pos.getY()) {
return true;
} else {
return false;
}
}
public void towards(Position pos) {
if(samePosition(pos)) {
} else if(this.getX() > pos.getX()){
setX(-1);
} else if(this.getX() < pos.getX()){
setX(1);
} else if(this.getY() > pos.getY()) {
setY(-1);
} else if(this.getY() < pos.getY()) {
setY(1);
}
}
public Position moveUp() {
Position p = new Position(getX(), getY());
p.setY(1);
return p;
}
public Position moveDown() {
Position p = new Position(getX(), getY());
p.setY(-1);
return p;
}
public Position moveRight() {
Position p = new Position(getX(), getY());
p.setX(1);
return p;
}
public Position moveLeft() {
Position p = new Position(getX(), getY());
p.setX(-1);
return p;
}
public List<Position> neighbours(Simulation sim) {
List<Position> list = new LinkedList<Position>();
moveUp();
if(sim.inside(this)) {
list.add(this);
}
moveDown();
if(sim.inside(this)) {
list.add(this);
}
moveRight();
if(sim.inside(this)) {
list.add(this);
}
moveLeft();
if(sim.inside(this)) {
list.add(this);
}
return list;
}
}
FoodSource
package antcolony;
import geo.Position;
import java.util.List;
import java.util.LinkedList;
public class FoodSource {
private Position position;
private int amount;
public int getAmount() {
return amount;
}
public Position getPosition() {
return position;
}
public FoodSource(int amount, Position position) {
this.amount = amount;
this.position = position;
}
public boolean takeFood() {
if(getAmount() > 0) {
amount -= 1;
return true;
} else {
return false;
}
}
}
测试
import antcolony.simulation.Simulation;
import antcolony.Ant;
import antcolony.FoodSource;
import geo.Position;
public class Test {
private static Position origo;
private static Simulation sim;
private static Ant ant;
public static void main(String[] args) {
try {
testPosition();
testFoodSource();
testSimulation();
testAnt();
System.out.println("Minden rendben");
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
private static void testPosition() {
Position pos = new Position(3,4);
Position pos_ = new Position(3,4);
Position pos2 = new Position(4,4);
Position pos3 = new Position(3,5);
Position pos4 = new Position(0,5);
Position pos4_ = new Position(0,5);
origo = new Position(0,0);
assertFalse(pos.samePosition(origo));
assertTrue(pos.samePosition(pos_));
assertTrue(pos.moveRight().samePosition(pos2));
assertTrue(pos.moveUp().samePosition(pos3));
assertTrue(pos.moveUp().moveDown().samePosition(pos));
assertTrue(pos.moveRight().moveLeft().samePosition(pos));
pos_.towards(origo);
assertTrue(pos_.samePosition(pos.moveLeft()));
pos4_.towards(origo);
assertTrue(pos4_.samePosition(pos4.moveDown()));
}
private static void testFoodSource() {
FoodSource fs = new FoodSource(2, new Position(0,0));
assertTrue(fs.takeFood());
assertTrue(fs.takeFood());
assertFalse(fs.takeFood());
}
private static void testSimulation() {
sim = new Simulation(3, 1, origo, new FoodSource(1, new Position(1, 1)));
assertEquals(1, sim.getAnts().size());
ant = sim.getAnts().get(0);
assertTrue(ant.getPosition().samePosition(origo));
sim.simulateStep();
assertFalse(sim.getAnts().get(0).getPosition().samePosition(origo));
assertSimilar(0.0, sim.pheromoneOn(origo));
sim.putPheromoneOn(origo, 1);
sim.putPheromoneOn(origo, 1);
assertSimilar(2.0, sim.pheromoneOn(origo));
}
private static void testAnt() {
/* the ant will reach the food in at most 200 steps */
int i = 0;
while (!ant.isCarryingFood() && i++ < 200) {
sim.simulateStep();
}
assertTrue(ant.isCarryingFood());
assertFalse(ant.getPosition().samePosition(origo));
int j = 0;
/* the ant will reach the colony in 2 steps */
while (ant.isCarryingFood() && j++ < 3) {
sim.simulateStep();
}
assertFalse(ant.isCarryingFood());
}
private static void assertFalse(boolean p) {
if (p) throw new RuntimeException("Assertion failed");
}
private static void assertTrue(boolean p) {
if (!p) throw new RuntimeException("Assertion failed");
}
private static void assertEquals(Object expected, Object actual) {
if (!expected.equals(actual)) {
throw new RuntimeException("Assertion failed, expected: " + expected + ", actual: " + actual);
}
}
private static void assertSimilar(double expected, double actual) {
if (Math.abs(expected - actual) > 0.0001) {
throw new RuntimeException("Assertion failed, expected: " + expected + ", actual: " + actual);
}
}
}
转轮
import antcolony.simulation.Simulation;
import antcolony.Ant;
import antcolony.FoodSource;
import geo.Position;
public class Runner {
Simulation simulation;
final int simulationLength;
public static void main(String[] args) {
Runner tester = new Runner(100, new Simulation(9, 20, new Position(4,4), new FoodSource(100,
new Position(6, 8))));
tester.runSimulation();
}
public Runner(int simulationLength, Simulation simulation) {
this.simulationLength = simulationLength;
this.simulation = simulation;
}
public void runSimulation() {
for (int i = 0; i < simulationLength; i++) {
dump();
simulation.simulateStep();
}
System.out.println("Collected food: " + simulation.foodDelivered);
}
public void dump() {
drawLine();
for (int i = 0; i < simulation.getSize(); i++) {
System.out.print("|");
for (int j = 0; j < simulation.getSize(); j++) {
System.out.print(dumpCell(i, j));
}
System.out.println("|");
}
}
private void drawLine() {
for (int i = 0; i < simulation.getSize() + 1; i++) {
System.out.print("-");
}
System.out.println();
}
private char dumpCell(int i, int j) {
Position pos = new Position(i, j);
if (simulation.getFoodSource().getPosition().samePosition(pos)) {
return 'K';
}
if (simulation.getColonyPosition().samePosition(pos)) {
return 'O';
}
for (Ant ant : simulation.getAnts()) {
if (ant.getPosition().samePosition(pos)) {
if (ant.isCarryingFood()) {
return '+';
}
}
}
for (Ant ant : simulation.getAnts()) {
if (ant.getPosition().samePosition(pos)) {
return 'H';
}
}
if (simulation.pheromoneOn(pos) > 0.1) {
return '.';
}
return ' ';
}
}