Java source code for the Ant Colony Optimization Problem.

源代码在线查看: ant.java

软件大小: 394 K
上传用户: zhuxiaobei123
关键词: Optimization Problem Colony source
下载地址: 免注册下载 普通下载 VIP

相关代码

				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 				            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() 				        {
				            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 				                        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;
				        }
				    }
				}			

相关资源