xiaolu1998 发表于 2005-2-28 14:23

[求助]帮改一下程序

<P>我搜到一个java版蚂蚁算法的程序,我不懂JAVA请高手帮我改成c或matlab</P>
<P>package ant;
/*
* @(#)Antcolony.java 1.0 03/05/22
*
* You can modify the template of this file in the
* directory ..\JCreator\Templates\Template_2\Project_Name.java
*
* You can also create your own project template by making a new
* folder in the directory ..\JCreator\Template\. Use the other
* templates as examples.
*
*/</P>
<P>import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.Vector;</P>
<P>class AntCanvas extends Canvas
{
    //画布,一切画图操作均由该类完成
//Image image;
Color obs_color;//障碍物颜色
Color origin_color;//我的颜色
Color back_color;//背景色
        Color end_color;//食物点的颜色
//boolean first;
boolean reset;</P>
<P>/* public AntCanvas(Image img) {</P>
<P>  super();
   image = img;
  obs_color = Color.white;
  setBackground(Color.black);
  setForeground(Color.white);
  first = true;
  reset = false;</P>
<P> }*/</P>
<P> public AntCanvas() {</P>
<P>  super();
   //image = null;
   back_color=Antcolony.BACK_COLOR;
  setBackground(back_color);
  setForeground(Color.white);
  obs_color = Antcolony.OBS_COLOR;
  origin_color=Antcolony.ORIGIN_COLOR;
                end_color=Antcolony.End_COLOR;
  //first = true;
  reset = true;</P>
<P> }</P>
<P> public void Clear() {
        //清空画布
  reset = true;
  repaint();
}</P>
<P>
public void paint(Graphics g) {
  int i;
                //重画的时候仅仅画障碍物
  g.setColor(Color.black);
  g.fillRect(0,0,size().width,size().height);
  g.setColor(obs_color);
  for(i=0;i&lt;Antcolony.obsCount;i++){
   g.fillRect(Antcolony.obsP.x,Antcolony.obsP.y,1,1);
  }</P>
<P> }
public void process(){
        //处理动画的过程
  Graphics g=this.getGraphics();
                g.setColor(end_color);
   for(int j=0;j&lt;Antcolony.EndPts;j++){
                  //画所有的食物点
                  g.fillRect(Antcolony.EndPt.x,Antcolony.EndPt.y,2,2);
                }
                for(int i=0;i&lt;Antcolony.antCount;i++){
                  //每只蚂蚁开始决策,并画蚂蚁
   Antcolony.ants.Process();
   Antcolony.ants.Draw(g);
  }
                for(int i=0;i&lt;Antcolony.phe.size();i++){
                        Pheromone v=(Pheromone)(Antcolony.phe.elementAt(i));
                        //Antcolony的drawPhe变量标志是否画信息素
                        switch(Antcolony.drawPhe){
                        case (1):
                            v.Draw(g);
                            break;
                        case (2):
                            if(v.kind==1)v.Draw(g);
                            break;
                        case (3):
                            if(v.kind==0)v.Draw(g);
                            break;
                        }
                        v.delimit(g);
                }
           g.setColor(origin_color);
                for(int i=0;i&lt;Antcolony.OriginPts;i++){
                  //画所有的窝
                  g.fillRect(Antcolony.OriginPt.x,Antcolony.OriginPt.y,2,2);
                }</P>
<P> }
Graphics GetGra() {</P>
<P>  return this.getGraphics();
}
}
public class Antcolony extends Applet  implements Runnable  {
boolean isStandalone = false;//系统的参数,是否独立运行,不用管
Thread runner;//创建一个线程,让动画平滑的运行
boolean running;//是否让动画运行
        boolean reset=false;//是否按下了重置按钮
static Color OBS_COLOR=Color.red;//障碍物的颜色
static Color ORIGIN_COLOR=Color.yellow;//窝的颜色
static Color BACK_COLOR=Color.black;//背景色
static Color ANT_COLOR=Color.white;//蚂蚁的颜色
        static Color End_COLOR=Color.cyan;//食物点的颜色
AntCanvas canvas=new AntCanvas();//画图用的画布
int obs_grid[][];//障碍物网格数组,这是个width*height的矩阵,数组中存储的是障碍物数组(obsP[])的指标,这样做可以加快索引的速度
        static Point obsP[];//障碍物数组,存储的是点的信息,指标是障碍物的总数
static int obsCount;//障碍物的数量,最大为width*height
static Point EndPt[];//食物点数组,值为食物点坐标。
        static int EndPts=1;//食物点的个数,初始的时候为1,最大数为100
        static int Pheromone_grid[][][];//信息素网格数组,2*width*height的三维矩阵,第一维是信息素种类(窝的信息素为0,食物的为1),它存储的是信息素的种类和值
        static Vector phe;//信息素向量(相当于一个数组),当环境更新信息素的时候,只需要查找这个向量就可以了,不用搜索整个width*height这么多的Pheromone_grid数组点
        static int Max_Pheromone=500000;//最大信息素数值,应该根据地图的复杂程度来定,越复杂越大!
static Point OriginPt[];//窝点信息
        static int OriginPts=1;//窝的个数,最大为100
static int width=300,height=300;//环境的长和宽
static int antCount;//蚂蚁的数量
        static int Delimiter=5;//信息素消散的速率,为整数,越大则消散的越快
        static int FoodR=10;//食物和窝产生梯度的信息素的半径
static ant ants[];//蚂蚁数组
        static int drawPhe=2;//画信息素的模式,0为不画,1为画所有的信息素,2为画食物的信息素,3为画窝的信息素
int delay=10;//每次运行的间隔速率,越小程序运行越快(这个参数基本没用,因为当蚂蚁多了以后,处理过程很耗时间)</P>
<P>        //下面是一些控件信息
        Button btnStart=new Button("开始");
        Button btnReset=new Button("重来");
        Button btnMap=new Button("编辑地图");
        Button btnConfig=new Button("设置");
        Choice choPDraw=new Choice();
public void init() {
                //初始化函数,先画各种控件
  setLayout(new BorderLayout());
                Panel pan=new Panel();
                add("South",pan);
                this.add("Center",canvas);
                pan.add(btnStart);
                pan.add(btnReset);
                pan.add(btnConfig);
                pan.add(btnMap);
                pan.add(choPDraw);
                choPDraw.addItem("不画信息素");
                choPDraw.addItem("画所有信息素");
                choPDraw.addItem("画食物信息素");
                choPDraw.addItem("画窝的信息素");
                choPDraw.select(2);</P>
<P>                //初始化各个数组
  obs_grid=new int ;
                phe=new Vector();
                Pheromone_grid=new int ;
                for(int i=0;i&lt;width;i++){
   for(int j=0;j&lt;height;j++){
    obs_grid=-1;
                                for(int k=0;k&lt;2;k++){
                                  Pheromone_grid=0;
                                }
   }
  }</P>
<P>   antCount=50;//蚂蚁个数缺省为50
                //初始化蚂蚁,这些属性都是蚂蚁的最原始的属性
  ants=new ant;
        for(int i=0;i&lt;antCount;i++){
          ants= new ant(new Point(0,0),3,i,this,ANT_COLOR,0.001,50);
  }</P>
<P>                //下面装载缺省的地图,包括障碍物、食物点、窝点的位置,都放到数组grid[][]中然后交给init_map函数统一处理
                int grid[][]=new int;</P>
<P>                //下面从地图库中加在地图
                Maps maps=new Maps();
                maps.LoadMap(grid,0);
                //初始化地图
                reinit_map(grid);</P>
<P>                //初始化所有的蚂蚁
  reinit();
}
        public void reinit_map(int grid[][]){
                //将数组grid[][]中存储的信息转换到当前的环境数据结构中
                //相当于把一个位图信息width*height像素转化成窝、食物、障碍物</P>
<P>                //先停止程序的运行
                running=false;
                btnStart.setLabel("开始");</P>
<P>
                obsCount=0;
                EndPts=0;
                OriginPts=0;
                obsP=new Point;
                OriginPt=new Point;
                EndPt=new Point;</P>
<P>                //清空obs_grid和Pheromone两个数组中的值
                for(int i=0;i&lt;width;i++){
   for(int j=0;j&lt;height;j++){
    obs_grid=-1;
                                for(int k=0;k&lt;2;k++){
                                  Pheromone_grid=0;
                                }
   }
  }</P>
<P>                //从grid数组中读取信息
                for(int i=0;i&lt;width;i++){
                  for(int j=0;j&lt;height;j++){
                    switch (grid){
                    case 1:
                      //如果grid[][]存的是障碍物
                      obs_grid=obsCount;
                      obsP=new Point(i,j);
                      obsCount++;
                      break;
                    case 2:
                      //如果grid[][]存的窝点信息,多余的窝点信息省去了
                      if(OriginPts&lt;100){
                          OriginPt=new Point(i,j);
                          OriginPts++;
                      }
                      break;
                    case 3:
                      //如果grid[][]存的食物点信息,多余的食物点信息省去了
                      if(EndPts&lt;100){
                          EndPt=new Point(i,j);
                          EndPts++;
                      }
                      break;
                    }
                  }
                }
            //如果没有指定窝,则随机的选择一点
            if(OriginPts==0){
              for(int i=0;i&lt;width;i++){
                int  j;
                for(j=0;j&lt;height;j++){
                  if(obs_grid&lt;0){
                    OriginPt=new Point(i,j);
                    OriginPts++;
                    break;
                  }
                }
                if(j&lt;height-1){
                  break;
                }
              }
            }
        }
public void reinit(){
                //重新初始化整个环境</P>
<P>                //先停止程序的运行
                running=false;
                btnStart.setLabel("开始");</P>
<P>
  //清空所有信息素Pheromone数组中的值
                for(int i=0;i&lt;width;i++){
   for(int j=0;j&lt;height;j++){
                                for(int k=0;k&lt;2;k++){
                                  Pheromone_grid=0;
                                }
   }
  }</P>
<P>                //初始化蚂蚁数组,antCount只蚂蚁在不同的窝点之间进行随机的分配
        for(int i=0;i&lt;antCount;i++){
                        int index=(int)(OriginPts*Math.random());
          ants.OriginPt=new Point(OriginPt);
                        ants.init();
  }</P>
<P>                //清空信息素向量
                phe.removeAllElements();</P>
<P>                //在每个食物点和窝点周围分布一定量的按照梯度递减的信息素,分配的是一个点为中心的半径为FoodR的圆,并且信息素按照半径递减
  for(int i=0;i&lt;EndPts;i++){
                   for(int x=-FoodR;x&lt;=FoodR;x++){
                        int y=(int)(Math.sqrt(FoodR*FoodR-x*x));
                        for(int yy=-y;yy&lt;=y;yy++){
                            Pheromone_grid[(EndPt.x+x+width)%width][(EndPt.y+yy+height)%height]=(int)(1000*(1-Math.sqrt(x*x+yy*yy)/FoodR));
                        }
                    }
                }
                for(int i=0;i&lt;OriginPts;i++){
                   for(int x=-FoodR;x&lt;=FoodR;x++){
                        int y=(int)(Math.sqrt(FoodR*FoodR-x*x));
                        for(int yy=-y;yy&lt;=y;yy++){
                            Pheromone_grid[(OriginPt.x+x+width)%width][(OriginPt.y+yy+height)%height]=(int)(1000*(1-Math.sqrt(x*x+yy*yy)/FoodR));
                        }
                    }
                }</P>
<P>                //重画
  canvas.repaint();</P>
<P>                //让程序开始运行
                //running=true;
}
public void paint(Graphics g) {
  canvas.repaint();
}</P>
<P>
public static void main(String[] args) {
    Antcolony applet = new Antcolony();
    applet.isStandalone = true;
    Frame frame;
    frame = new Frame() {
      protected void processWindowEvent(WindowEvent e) {
        super.processWindowEvent(e);
        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
          System.exit(0);
        }
      }
      public synchronized void setTitle(String title) {
        super.setTitle(title);
        enableEvents(AWTEvent.WINDOW_EVENT_MASK);
      }
    };
    frame.setTitle("Applet Frame");
    frame.add(applet, BorderLayout.CENTER);
    applet.init();
    applet.start();
    frame.setSize(300,320);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2);
    frame.setVisible(true);
  }
  public void start()
  //下面三个函数是控制线程的
{
  if (runner == null)
  {
   runner= new Thread(this);
   runner.start();
   //running = true;
  }
}</P>
<P> public void stop()
{
  if (runner!=null)
  {
   runner.stop();
   runner=null;
   running = false;
  }
}</P>
<P> public void run() {</P>
<P>  int i;
                //线程一直运行下去
  while (true) {
          if(running){
       //如果开始动画,就进行canvas的处理
                          canvas.process();
                        }
    try { Thread.sleep(delay);}
    catch (InterruptedException e) {
   }
  }</P>
<P> }
        public boolean action(Event evt, Object o) {
      if (evt.target == btnMap) {
                //开始编辑地图面板
   running=false;
                        btnStart.setLabel("开始");
   MapPad ctl = new MapPad(this);
                 ctl.setSize(308,380);
                        ctl.show();
                        return true;
  }else if(evt.target == btnStart){
                  if(!running){
                    //如果刚刚按下了重置按钮就重新初始化一下
                    if(reset)reinit();
                    btnStart.setLabel("停止");
                    reset=false;
                    running=true;
                  }else{
                    btnStart.setLabel("开始");
                    running=false;
                  }
                  return true;
                }else if(evt.target == btnReset){
                  running=false;
                  int j=0;
                  //表示已经按下了重置按钮,以便下次开始的时候进行重新初始化
                  reset=true;
                  repaint();
                  btnStart.setLabel("开始");
                  return true;
                }else if(evt.target == btnConfig){
                        running=false;
                        btnStart.setLabel("开始");
     Configer ctl = new Configer(this);
                 ctl.setSize(300,300);
                        ctl.show();
                        return true;
                }else if(evt.target == choPDraw){
                  //选择画信息素的模式
                  drawPhe=choPDraw.getSelectedIndex();
                  if(drawPhe!=1){canvas.repaint();}
                  return true;
                }
                return false;</P>
<P>        }
/**Destroy the applet*/
  public void destroy() {
  //当结束程序的时候,把线程也结束
    if (runner!=null)
    {
       running = false;
       runner.stop();
       runner=null;
    }
  }</P>
<P>}
</P>



<P>package ant;
import java.awt.*;
import java.applet.*;
import java.util.Vector;</P>
<P>public class ant{
Point nowPt;//当前点坐标
int VR;//速度,每次蚂蚁能走动的最大长度
  int id;//标识
  Point lastPt;//上一点坐标
Color color;//蚂蚁的颜色
Color back_color;//背景的严肃
int height,width;//世界的尺寸
        int Phe;//每次释放信息素的数值
Antcolony local_colony;//主程序的指针
        Vector HistoryPoint;//记录一次觅食过程历史上的所有点
        double Main_direct;//主方向
        Point FoodPt;//记录的食物点,是否找到时候判断用
        Point OriginPt;//窝的坐标
        Point AimPt;//目标点,是窝或者食物
        Point StartPt;//起始点,是窝或者食物
        int FoundTimes;//找到食物或者窝的次数
        int Max_Pheromone;//最大能够释放的信息素
        int Pheromone_count;//当前还拥有的信息素的总量
        boolean Judged=false;//判断寻找目标点的工作是否已经进行了
        double mistake;//犯错误的概率
        int memory;//记忆走过点的数目
        double Count_distance;//走过的总路程,为单程的路程,也就是说找到食物或者窝就从新计数了。
        public double Min_distance;//当前这只蚂蚁再没次往返的时候的最小总距离
public ant(Point nowpt,int vr,int idd,Antcolony colony,Color c,double mist,int mem){
  nowPt=new Point(nowpt.x,nowpt.y);
                OriginPt=new Point(nowpt.x,nowpt.y);
                FoodPt=new Point(nowpt.x,nowpt.y);
                StartPt=new Point(nowpt);
                AimPt=new Point(nowpt);
                lastPt=nowPt;
  VR=vr;
  id=idd;
  color=c;
  back_color=Antcolony.BACK_COLOR;
  height=Antcolony.height;
  width=Antcolony.width;
  local_colony=colony;
                Phe=200;
                mistake=mist;
                HistoryPoint=new Vector();
                Main_direct=-1;
                FoundTimes=0;
                Max_Pheromone=local_colony.Max_Pheromone;
                Pheromone_count=Max_Pheromone;
                memory=mem;
                Count_distance=0;
                Min_distance=-1;
}
        public void init(){
          nowPt=new Point(OriginPt);
          lastPt=new Point(OriginPt);
          FoodPt=new Point(OriginPt);
          AimPt=new Point(OriginPt);
          StartPt=new Point(OriginPt);
          HistoryPoint.removeAllElements();
          Main_direct=-1;
          FoundTimes=0;
          Pheromone_count=Max_Pheromone;
          Count_distance=0;
          Min_distance=-1;
        }
public void Draw(Graphics g) {
          //把蚂蚁在屏幕上画出来,先擦除上次画的点,然后再画蚂蚁现在的点。
  g.setColor(back_color);
  g.fillOval((int) lastPt.x,(int)lastPt.y,1,1);
  g.setColor(color);
  g.fillOval((int) nowPt.x, (int) nowPt.y,1,1);
}
public void Process(){
        //这个函数是蚂蚁进行决策的主程序,首先判断蚂蚁是否已经找到了目标点
        //(目标点在没找到食物的时候是食物点,找到以后是自己的窝)
        //然后计算蚂蚁的主方向,也就是让蚂蚁的爬动有一个惯性,当没有信息素作指导的时候蚂蚁按照主方向运动
        //开始搜索自己周围的空间信息,包括有多少信息素,是否有障碍物。最后根据信息素的大小决定移动到那个点
        //根据决策的目标进行真实的移动,其中包括了避障的行为,洒下信息素。</P>

<P>        if(Judged==false){
          //如果已经判断完结束与否了就不进行再一次的判断了,也就是说目前蚂蚁已经到了目标点,
          //如果再判断,它就会在目标点原地不动了,因此这是候不判断,让蚂蚁走起来
          if(JudgeEnd()){
              //判断,如果找到了目标点那么就退出该程序
              Judged=true;
              return;
          }
        }
        Judged=false;
        //如果没找到,就选择一个方向,这个方向是主方向加上一个随机扰动得到的,有SelectDirect函数完成
        double direct=SelectDirect();</P>
<P>        //下面是如果根据计算的移动方向得到蚂蚁的下一点,即deltx,delty
        int deltx=0,delty=0;
        //direct是方向角,根据方向计算位移
        deltx=(int)(VR*Math.cos(direct));
        delty=(int)(VR*Math.sin(direct));</P>
<P>        //kind表示当前蚂蚁是在找食物还是在找窝,如果是找窝就是1,找食物就是0。
        int kind=FoundTimes%2;</P>
<P>        //计算当前点的信息素,注意,如果获得的信息素总跟kind变量相反,
        //也就是说,如果当前蚂蚁找食物呢,那么它所关心的信息素就是找我的蚂蚁留下的,反之亦然。
        int here=local_colony.Pheromone_grid;</P>
<P>        //记录搜索的环境中找到的最大的信息素
        int maxphe=here;</P>
<P>        //记住根据主方向角得到的位移,如果信息素并不能告诉蚂蚁应该往那里走,那么就要根据主方向角决定了
          int deltx1,delty1;
          deltx1=deltx;delty1=delty;</P>
<P>        //开始搜索环境,搜索的空间是以当前点为中心,VR为半径的四方形内,即VR/2*VR/2的正方形
          for(int x=-VR;x&lt;=VR;x++){
             for(int y=-VR;y&lt;=VR;y++){
                //xx,yy表示搜索到哪一个点了,+width然后再%width是为了让坐标循环起来,
                //在这个程序中,坐标是循环的,也就是在一个球面上
                int xx=(nowPt.x+x+width)%width;
                int yy=(nowPt.y+y+height)%height;</P>
<P>                //循环的时候要除去当前点。
                if(x!=0||y!=0){
                  //的到要搜寻的点的信息素
                  int phe=local_colony.Pheromone_grid;</P>
<P>                  //如果搜索点的信息素比已经找到过的信息素多
                  if(maxphe&lt;phe){</P>
<P>                      //如果当前点的信息素是0,没说的,赶紧上正轨,否则,就要根据随机数
                      //以mistake来决定蚂蚁犯错误的概率,即如果犯错误,它就不按信息素最大的方向走
                      double ra=Math.random();
                      if(here==0||ra&gt;mistake){
                          boolean found=false;
                          //查一下内存最近走过的memory的点数,从而避免当地转圈
                          int size=HistoryPoint.size();
                          int minsize=memory;
                          if(size&lt;memory)minsize=size;
                          for(int i=size-1;i&gt;=size-minsize;i--){
                             Point pt=(Point)(HistoryPoint.elementAt(i));
                             if(pt.x==xx&amp;&amp;pt.y==yy){
                                found=true;
                                break;
                             }
                          }
                          if(!found){
                            //如果没有原地转圈,那么记录信息素。
                            maxphe=local_colony.Pheromone_grid;
                            deltx=x;
                            delty=y;
                          }
                      }//end here==0||ra&gt;0.001
                    }//end maxphe&lt;here
                }//end if x!=0
            }//end for y
        }//end for x
        Point pt;</P>
<P>        //根据获得的信息的来的位移deltx,delty,来具体的进行移位
        pt=Evade_obs(deltx,delty);</P>
<P>        //如果卡住了,就根据主方向来确定位移,如果主方向也卡住了,那蚂蚁就会随机变换自己的主方向!
        if(pt.x==nowPt.x&amp;&amp;pt.y==nowPt.y){
          pt=Evade_obs(deltx1,delty1);
        }</P>
<P>        //播撒信息素
        Scatter();</P>
<P>        //记录走过的距离
        Count_distance+=Distance(lastPt,nowPt);</P>
<P>        //改变当前点位置
        lastPt=new Point(nowPt.x,nowPt.y);</P>
<P>        //根据memory的大小记录走过的点,并忘掉memory以前的点
        HistoryPoint.insertElementAt(lastPt,HistoryPoint.size());
        if(HistoryPoint.size()&gt;memory){
          HistoryPoint.removeElementAt(0);
        }
        nowPt=new Point(pt.x,pt.y);
     }</P>
<P>
        private void Scatter(){
        //释放信息素函数,每只蚂蚁有一个信息素的最大含量max_Pheromone,
        //并且,每次蚂蚁都释放Phe单位信息素,并且从总量Phe_count中减去Phe,直到用完所有的信息素。
            if(Pheromone_count&lt;=0)return;
            //决定释放信息素的种类
            int kind=FoundTimes%2;</P>
<P>            //获得当前点环境已有信息素的值
            int Phec=local_colony.Pheromone_grid;
            boolean ofound=false;
            if(Phec!=0){
                //如果当前点已经有信息素了
                for(int i=0;i&lt;local_colony.phe.size();i++){
                    //在信息素向量中查找该点的信息
                    Pheromone ph=(Pheromone)(local_colony.phe.elementAt(i));
                    if(lastPt.x==ph.x&amp;&amp;lastPt.y==ph.y&amp;&amp;ph.kind==kind){
                        //找到了,则看看蚂蚁所在的位置是否是刚刚走过的,如果不是才撒信息素
                        int size=HistoryPoint.size();</P>
<P>                        //如果在表中找到信息素,则用ofound记录。
                        ofound=true;
                        boolean found=false;
                        if(size&gt;4){
                           for(int j=size-4;j&lt;size-1;j++){
                              Point pt=(Point)(HistoryPoint.elementAt(j));
                              if(pt.x==lastPt.x&amp;&amp;pt.y==lastPt.y){
                                //如果当前点重复了以前走过的路,就不释放
                                found=true;
                                break;
                              }
                            }
                        }
                        if(!found){
                        //如果当前点不重复,则开始撒
                             ph.Add(Phe);
                             local_colony.Pheromone_grid+=Phe;</P>
<P>                             //让还剩下的信息素总量减少
                             Pheromone_count-=Phe;
                        }
                        break;
                    }
                }
              }
          if(Phec==0||!ofound){
            //如果当前环境没有信息素,或者当前环境的信息素来自窝或者食物,则新建一个信息素元素放到列表中
                Pheromone ph=new Pheromone(lastPt.x,lastPt.y,local_colony.phe.size(),local_colony.Delimiter,id,local_colony,Phec,kind);
                ph.Add(Phe);
                local_colony.Pheromone_grid+=Phe;
                local_colony.phe.addElement(ph);
                //让还剩下的信息素总量减少
                 Pheromone_count-=Phe;
           }</P>
<P>           //根据还剩下信息素的量调整释放信息素的数值Phe,这里为线性模型即Phe=0.0005*Pheromone_count
           //如果把剩余信息量看成数组count(n)的话,那么根据本模型,
           //count(n)满足下面的递推公式count(n)=(1-0.005)*count(n-1)
           //也就是说count(n)以几何级数的速度递减,这样,蚂蚁刚走出的地方信息素远远高于后走的地方
           //这个模型是否科学?有待研究
           Phe=(int)(0.005*Pheromone_count);</P>
<P>           //如果剩余信息素已经太小了,则按照等差数列递减
           if(Phe&lt;=10)Phe=10;
        }
private boolean JudgeEnd(){
    //这个函数判断是否已经找到了目标点
    //首先获得当前蚂蚁是正在找窝还是在找食物。
    int kind=FoundTimes%2;
    if(kind==0){
        //如果是找食物,那么需要把所有的食物点坐标与当前点比较,距离小于VR就认为是找到
        int i;
        for(i=0;i&lt;local_colony.EndPts;i++){
            if(Distance(nowPt,local_colony.EndPt)&lt;=VR){
              //如果找到了食物,就直接移动到食物点
              lastPt=new Point(nowPt.x,nowPt.y);
              nowPt.x=local_colony.EndPt.x;
              nowPt.y=local_colony.EndPt.y;</P>
<P>              //计算最后的总距离
              Count_distance+=Distance(lastPt,nowPt);
              //比较大小,记录较小的距离
              if(Count_distance&lt;Min_distance||Min_distance&lt;0){
                 Min_distance=Count_distance;
              }
              //清除总距离记录
              Count_distance=0;</P>
<P>              //同时记录这只蚂蚁的目标点是它的窝,起始点是这个找到的食物点
              AimPt=new Point(OriginPt);
              StartPt=new Point(nowPt);
              //并把当前点标为自己找到的食物点
              FoodPt=new Point(nowPt.x,nowPt.y);</P>
<P>              //找到了食物就把找到次数+1
              FoundTimes++;</P>
<P>              //改变主方向为原来方向的镜面反方向
              Main_direct=(Math.PI+Main_direct)%(2*Math.PI);</P>
<P>              //重新把自己能撒的信息素置为最大值
              Pheromone_count=Max_Pheromone;</P>
<P>              //清空记录的所有点
              HistoryPoint.removeAllElements();</P>
<P>              //返回找到为真
              return true;
            }
        }
      //否则没找到
      return false;
    }
    if(kind==1){
        //如果是找窝,因为目标点已经明确,所以比较目标点和当前点的距离,小于VR表示已经找到
        if(Distance(nowPt,AimPt)&lt;=VR){
            lastPt=new Point(nowPt.x,nowPt.y);
            //如果找到了目标,就直接移动到目标点
            nowPt.x=AimPt.x;
            nowPt.y=AimPt.y;</P>
<P>              //计算最后的总距离
              Count_distance+=Distance(lastPt,nowPt);
              //比较大小,记录较小的距离
              if(Count_distance&lt;Min_distance||Min_distance&lt;0){
                  Min_distance=Count_distance;
              }
              //清除总距离记录
              Count_distance=0;
            //把目标点定为食物点,起始点定为窝
            AimPt=new Point(FoodPt);
            StartPt=new Point(OriginPt);</P>
<P>            //重新置信息素
            Pheromone_count=Max_Pheromone;</P>
<P>            //清空历史纪录
            HistoryPoint.removeAllElements();</P>
<P>            //主方向反向
            Main_direct=(Math.PI+Main_direct)%(2*Math.PI);</P>
<P>            //找到次数+1
            FoundTimes++;
            return true;
        }
        return false;
    }
    return false;
}
        private double SelectDirect(){
                //选择方向,最后选择的方向为主方向加一个随机扰动
                double direct,e=0;
                if(Main_direct&lt;0){
                      //如果目前还没有主方向角,就随机的选择一个
        e=2*Math.PI*Math.random();
                      Main_direct=e;
                }
                //选择主方向角
                direct=Main_direct;</P>
<P>                //做一个随机模型,产生两个随机数,x,y都是内的,这样x^2-y^2就是一个
                //[-1,1]的随机数,并且在0点附近的概率大,两边小
                double re=Math.random();
                double re1=Math.random();
                direct+=Math.PI*(re*re-re1*re1)/2;
                if(re&lt;0.02){
                  //以小概率0.02改变主方向的值,主方向的选取为从蚂蚁记住的点中随机选一个点,计算当前点和这个点之间的方向角。
                  int size=(int)(re1*memory)+1;
                  if(HistoryPoint.size()&gt;size){
                    Point pt=(Point)(HistoryPoint.elementAt(HistoryPoint.size()-size));
                    if(pt.x!=nowPt.x||pt.y!=nowPt.y){
                       Main_direct=GetDirection(pt,nowPt);
                    }
                  }
                }
               return direct;</P>
<P>        }
        private Point Evade_obs(int deltx,int delty){
              //这个函数根据决策的位移值进行敝张的判断,算出真实可以移动到的点
              //要移动到的目标点是(nowPt+delt),当前点是nowPt,那么搜索nowPt到(nowPt+delt)
              //这条直线上的所有点,看有没有障碍物!根据直线的参数方程:
              //x=p1x+(p2x-p1x)*t,y=p1y+(p2y-p1y)*t;
              //其中t是参数,取值,步长为abs(max{p2x-p1x,p2y-p1y}),
              //p1,p2在这里分别是nowPt和nowPt+delt
              Point pt=new Point(0,0);
              int x,y;
              int delt=deltx;
              if(Math.abs(delty)&gt;Math.abs(deltx))delt=delty;
              if(delt==0)return nowPt;
              for(double t=0;t&lt;=1;t+=1/(double)(Math.abs(delt))){
                  x=(int)(deltx*t+nowPt.x);
                  y=(int)(delty*t+nowPt.y);
                  x=(x+width)%width;
                  y=(y+height)%height;
                  if(local_colony.obs_grid&gt;=0){</P>
<P>                     //如果移动方向发现障碍物,那么就改变目标点和主方向
                     //新目标点为障碍物前方的点,主方向随机取值
                     deltx=pt.x-nowPt.x;delty=pt.y-nowPt.y;
                     double disturb=4*Math.PI*(Math.random()-0.5);
                     Main_direct=(disturb+2*Math.PI)%(2*Math.PI);
                     break;
                  }
                  pt=new Point(x,y);
                }</P>
<P>                //计算得出实际能够到达的目标点
  x=(nowPt.x+deltx+width)%width;
  y=(nowPt.y+delty+height)%height;
         return new Point(x,y);
        }
        private double GetDirection(Point pt1,Point pt2){
        //这个函数为指定两个点pt1和pt2,给出pt1--&gt;pt2的方向角
        //此函数的难度主要在于,我们的世界是球面,因此需要从多个方向计算方向角,
        //其中方向角是所有可能的角中使得两点连线距离最短的角。
               double e;
               int deltx1=pt2.x-pt1.x;
               int deltx2;
               if(pt2.x&gt;pt1.x)deltx2=pt2.x-pt1.x-width;
               else deltx2=pt2.x+width-pt1.x;
               int delty1=pt2.y-pt1.y;
               int delty2;
               if(pt2.y&gt;pt1.y)delty2=pt2.y-pt1.y-height;
               else delty2=pt2.y+height-pt1.y;
               int deltx=deltx1,delty=delty1;
               if(deltx==0&amp;&amp;delty==0)return -1;
               if(Math.abs(deltx2)&lt;Math.abs(deltx1)){
    deltx=deltx2;
               }
        if(Math.abs(delty2)&lt;Math.abs(delty1)){
                  delty=delty2;
               }
               if(deltx!=0){
                    e=Math.atan((double)(delty)/(double)(deltx));
                    if(deltx&lt;0){
                       if(e&lt;0) e=e-Math.PI;
                       else e=e+Math.PI;
                    }
                }else{
                    if(delty&gt;0)e=Math.PI/2;
                    else e=-Math.PI/2;
                }
                e=(e+Math.PI*2)%(2*Math.PI);
                return e;
        }
        private double Distance(Point pt1,Point pt2){
        //给定两点pt1,pt2,计算它们之间的距离,难点在于世界是球面,所有有坐标循环的情况,
        //这里计算的是所有可能距离中最小的
            int dx1=pt1.x-pt2.x;
            int dx2;
            int dx,dy;
            if(pt1.x&gt;pt2.x)dx2=pt1.x+width-pt2.x;
            else dx2=pt2.x+width-pt1.x;
            int dy1=pt1.y-pt2.y;
            int dy2;
            if(pt1.y&gt;pt2.y)dy2=pt1.y+height-pt2.y;
            dy2=pt2.y+height-pt1.y;
            if(Math.abs(dx1)&lt;Math.abs(dx2))dx=dx1;
            else dx=dx2;
            if(Math.abs(dy1)&lt;Math.abs(dy2))dy=dy1;
            else dy=dy2;
            return Math.sqrt(dx*dx+dy*dy);
        }
    public void clone(ant ant1){
        //把蚂蚁ant1的属性拷贝到本蚂蚁
     nowPt=new Point(ant1.nowPt);
        OriginPt=new Point(ant1.OriginPt);
        FoodPt=new Point(ant1.FoodPt);
        StartPt=new Point(ant1.StartPt);
        AimPt=new Point(ant1.AimPt);
        lastPt=new Point(ant1.lastPt);
        VR=ant1.VR;
        id=ant1.id;
        color=ant1.color;
        back_color=ant1.back_color;
        height=ant1.height;
        width=ant1.width;
        local_colony=ant1.local_colony;
        Phe=ant1.Phe;
        mistake=ant1.mistake;
        HistoryPoint=ant1.HistoryPoint;
        Main_direct=ant1.Main_direct;
        FoundTimes=ant1.FoundTimes;
        Max_Pheromone=ant1.Max_Pheromone;
        Pheromone_count=ant1.Pheromone_count;
        memory=ant1.memory;
        Count_distance=ant1.Count_distance;
        Min_distance=ant1.Min_distance;
    }
}</P>
页: [1]
查看完整版本: [求助]帮改一下程序