⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ant.java

📁 Java source code for the Ant Colony Optimization Problem.
💻 JAVA
字号:
package jwo.jpss.ants;     // Part of the ant simulation package.
import java.awt.*;		   // For drawing the ant.
import jwo.jpss.spatial.*; // For spatial footprint.
import java.util.*;        // For dynamic collections.

//  *******************************************************
/** Class for representing and drawing Ants.
  * @author Jo Wood
  * @version 1.2, 23rd August, 2001.
  */
//  *******************************************************

public class Ant extends Animal implements Dynamic,Drawable		
{
    // --------------- Object and class variables ---------------

    protected int straightSteps,    // Num. steps taken in a single direction.
                  numSteps;         // Num. steps walked by ant.
    protected float homingInstinct; // Liklihood of ant returning to nest.
    protected boolean goingHome;	
    protected int maxFood;          // Maximum amount of food ant can eat.
    protected Color colour;	        // Ant colour.
    protected float xDir,yDir;      // Current direction taken by ant.
        
                                    // Component drawing the graphics.
    protected GraphicsListener gListener;
    
    private Nest nest;              // Nest in which this ant was born.
    private int foodSize;           // Size of food being carried.

    // Declare immutable ant 'laws'
    private static final float MUTATION = 0.05f;           // Proportion of mutation.
    private static final int   MAX_STRAIGHT_STEPS = 20;    // Maximum straight steps.
    private static final float MAX_HOMING_INSTINCT = 0.1f; // Initial maximum homing prob. 
    private static final int   MAX_FOOD = 10000;           // Initial maximum food capacity.
    private static final int   WIDTH = 6;                  // Width of ant.
    private static final int   HEIGHT = 3;                 // Height of ant.
    private static final int   FEED_RATE = 100;            // Food per cycle that can be eaten.
    private static final int   DONATION_LEVEL = 1000;      // Food level at which ant gives to nest.
    private static final int   METABOLIC_RATE = 1;         // Rate at which ant consumes food.


    // --------------------- Constructors ---------------------
            
    /** Creates an ant with a given food level and location.
      * @param foodLevel Initial food level of the ant.
      * @param x Initial x location of the ant.
      * @param y Initial y location of the ant.
      * @param colour Colour of ant.
      * @param nest Nest in which this ant was born.
      */
    public Ant(int foodLevel, float x, float y, Color colour, Nest nest)
    {
    	super(foodLevel, new Footprint(x,y,WIDTH,HEIGHT));
        this.nest = nest;
        this.colour   = colour;
        straightSteps = (int)(Math.random()*MAX_STRAIGHT_STEPS)+1;
    	numSteps      = (int)(Math.random()*10);
    	homingInstinct= (float)Math.random()*MAX_HOMING_INSTINCT;
    	goingHome     = false;
    	maxFood       = (int)(Math.random()*MAX_FOOD);
    	foodSize      = 0;
    }
    

    /** Creates an ant with similar characteristics of the given
      * parent. Applies a small genetic mutation to inherited characteristics.
      * @param foodLevel Initial food level of the ant.
      * @param parent Ant supplying inheritable characteristics.
      * @param x Initial x location of the ant.
      * @param y Initial y location of the ant.
      * @param nest Nest in which this ant was born.
      */
    public Ant(int foodLevel, Ant parent, float x, float y, Nest nest)
    {
        super(foodLevel, new Footprint(x,y,WIDTH,HEIGHT));
        this.nest = nest;

        float mutation;
        numSteps = (int)(Math.random()*10);
        foodSize = 0;

        // Inherit straight steps with mutation.
        mutation = (float)(MAX_STRAIGHT_STEPS*MUTATION*(Math.random() - 0.5f));
        straightSteps  = Math.round(parent.getStraightSteps()+mutation);

        if (straightSteps <1)
            straightSteps = 1;
 
        // Inherit homing instinct with mutation.
        mutation = (float)(MAX_HOMING_INSTINCT*MUTATION*(Math.random()- 0.5f));
        homingInstinct = parent.getHomingInstinct()+mutation;
 
        // Inherit maximum food capacity.
        mutation = (float)(MAX_FOOD*MUTATION*(Math.random() - 0.5f));
        maxFood = Math.round(parent.getMaxFood()+mutation);

        // Inherit parent colour with mutation.
        colour = parent.getColour();
        if (Math.random() <MUTATION)
        {
            if (Math.random() < 0.5)
                colour = colour.brighter();
            else
                colour = colour.darker();
        }	
    }

    // ------------------- Accessor Methods -------------------

    /** Reports how many steps the ant will take before considering
      * changing direction.
      * @return Number of straight steps taken.
      */    
    public int getStraightSteps()
    {
        return straightSteps;
    }
   
    /** Reports the homing instinct of the ant. Instinct varies between
      * 0 and 1 and represents the probability that the ant will move
      * in a nestward direction whenever it changes direction.  
      * @return Homing instinct between 0 and 1. 
      */    
    public float getHomingInstinct()
    {
        return homingInstinct;
    }
    
    /** Reports much food can be carried by the ant.
      * @return Number of food units the ant can carry.
      */    
    public int getMaxFood()
    {
        return maxFood;
    }
    
    /** Reports the colour of this ant.
      * @return Colour of this ant.
      */    
    public Color getColour()
    {
        return colour;
    }

    // ------------------ Overridden methods ------------------
    
    /** Lets the ant eat some food and updates the size of any
      * carried food.
      * @param foodUnits Number of food units to eat.
      */
    public void eat(int foodUnits)
    {
        super.eat(foodUnits);
        foodSize = Math.round(getFoodLevel()/1000f);	
    }
    
    /** Let the ant metabolise some food and updates the size of any
      * carried food.
      * @param foodUnits Number of food units to metabolise.
      */
    public void metabolise(int foodUnits)
    {
        super.metabolise(foodUnits);
        foodSize = Math.round(getFoodLevel()/1000f);    	
    }


    // ------------------ Implemented methods -----------------   
    
    /** Draws the ant using the given graphics context.
      * @param g Graphics context to draw to.
      */
    public void paint(Graphics g)
    {
        Footprint fp = getBounds();
        int x = Math.round(fp.getXOrigin());
        int y = Math.round(fp.getYOrigin());
        int width = Math.round(fp.getMERWidth());
        int height = Math.round(fp.getMERHeight());
     
        g.setColor(colour);	   
        g.fillOval(x,y,width,height);
    	
        if (getFoodLevel() > 1000)
        {
    	    g.setColor(new Color(0,155,100));
    	    g.fillRect(x+width,y, foodSize+1, foodSize+1);
            g.setColor(colour);
            g.fillRect(x+width,y, foodSize+1, foodSize+1);
        }
    }
    
    /** Adds a graphics listener to this ant. Allows graphics to be
      * drawn by a GraphicsListener.
      * @param gListener Component doing the drawing.
      */
    public void addGraphicsListener(GraphicsListener gListener)
    { 
        this.gListener = gListener;
    }

    /** Let the ant go about its business for one time unit.
      */
    public void evolve()
    {    	
        metabolise(METABOLIC_RATE);	

        if (isAlive())
        {   
            // Find out if the ant is sitting on anything. 
            Enumeration enum = gListener.objectsAt(this).elements();
            while (enum.hasMoreElements())
            {
                SpatialObject spObject = (SpatialObject) enum.nextElement();

                // If ant is sitting on some food, eat it.
                if (spObject instanceof FoodSource)
                {
                    // Attempt to eat food at feeding rate.
                    FoodSource foodSource = (FoodSource)spObject;
                    int foodRemoved=0;

                    if (getFoodLevel()+FEED_RATE <= maxFood)
                        foodRemoved = foodSource.removeFood(FEED_RATE);    	    

            	    if (foodRemoved > 0)
            	    {
            	    	eat(foodRemoved);    	    	    	  
            	    	return;	
            	    }
            	}

            	// If ant finds itself at its own nest, the nest is alive and
                // the ant has enough food units, give half its food to the nest.
            	if (spObject == nest)
            	{
            	    int foodLevel = getFoodLevel();
            	    goingHome = false;    	    	    	

            	    if ((foodLevel > DONATION_LEVEL) && (nest.isAlive()))
            	    {   	    	
            	        nest.addFood(this,foodLevel/2);  
            	        metabolise(foodLevel/2);  	
            	        return;
            	    } 	       	    	
            	}
            }

            // Change direction if any has walked sufficient steps.
            if (numSteps%straightSteps == 0)
            	changeAntDirection();    	    	
    
            move(xDir,yDir);
        	        
            // Only move if ant is within bounds.
            if (gListener.canDraw(this))
            	numSteps++;
            else
            {
                // Change direction if cannot move.
                move(-xDir,-yDir); 	
                changeAntDirection();
            }
        }
    }

    // ---------------------- Private Methods ----------------------
        
    /** Sets a new direction for ant to walk in.
      */
    private void changeAntDirection()
    {   
        // No need to change direction if ant is already going home.
        if (goingHome)
   	        return; 

        // Speed of ant depends on how much it is carrying.
        float speed = 10f/(5f+getFoodLevel()/1000f);
    	
        // If ant decides to go home for first time, calculate direction.
        if ((Math.random() < homingInstinct) || 
            (maxFood - getFoodLevel() < FEED_RATE))
        {
            goingHome = true;    
            Footprint nestFP = nest.getBounds(),
            	      antFP  = getBounds();
    	    float dx =(nestFP.getXOrigin() + nestFP.getMERWidth()/2) - 
                      (antFP.getXOrigin()  + antFP.getMERWidth()/2);  	             
    	    float dy =(nestFP.getYOrigin() + nestFP.getMERHeight()/2) -
                      (antFP.getYOrigin()  + antFP.getMERHeight()/2);
            float scaling = (float)Math.sqrt(dx*dx + dy*dy)/speed; 
    	    
            if (scaling != 0)
            {    	            
                xDir = dx/scaling;
                yDir = dy/scaling;
            }
        }
    	else     // Otherwise calculate new random direction.
        {
            xDir = (float)(Math.random()*2-1)*speed;
            yDir = (float)(Math.random()*2-1)*speed;
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -