为什么我的蚂蚁不动?

时间:2015-03-20 08:02:07

标签: java

蚂蚁应根据其信息素水平进入四个方向之一,但我的蚂蚁永远不会去任何地方。我有一个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 ' ';
}

}

0 个答案:

没有答案