zoukankan      html  css  js  c++  java
  • 蚁群算法解决TSP旅行商问题 C# (转)

    转自:http://blog.sina.com.cn/s/blog_6a409d870101lwr8.html
     
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4  
     5 namespace ant_C
     6 {
     7     public static class Common
     8     {
     9        public static double ALPHA = 1.0; //启发因子,信息素的重要程度
    10        public static double BETA = 2.0;   //期望因子,城市间距离的重要程度
    11        public static double ROU = 0.5; //信息素残留参数
    12  
    13        public static int N_ANT_COUNT = 50; //蚂蚁数量
    14        public static int N_IT_COUNT = 10000; //迭代次数
    15        public static int N_CITY_COUNT = 51; //城市数量
    16  
    17        public static double DBQ = 100.0; //总的信息素
    18        public static double DB_MAX = 10e9; //一个标志数,10的9次方
    19  
    20        public static double[,] g_Trial = new double[N_CITY_COUNT, N_CITY_COUNT]; //两两城市间信息素,就是环境信息素
    21        public static double[,] g_Distance=new double[N_CITY_COUNT,N_CITY_COUNT]; //两两城市间距离
    22  
    23        //eil51.tsp城市坐标数据
    24        public static double[]  x_Ary=new double[]
    25        {
    26       37,49,52,20,40,21,17,31,52,51,
    27       42,31,5,12,36,52,27,17,13,57,
    28       62,42,16,8,7,27,30,43,58,58,
    29       37,38,46,61,62,63,32,45,59,5,
    30       10,21,5,30,39,32,25,25,48,56,
    31       30
    32        };
    33     
    34        public static double[] y_Ary=new double[]
    35        {
    36           52,49,64,26,30,47,63,62,33,21,
    37           41,32,25,42,16,41,23,33,13,58,
    38           42,57,57,52,38,68,48,67,48,27,
    39           69,46,10,33,63,69,22,35,15,6,
    40           17,10,64,15,10,39,32,55,28,37,
    41            40
    42        };
    43  
    44        
    45        static int RAND_MAX = 0x7fff; //随机数最大值
    46  
    47        static Random rand = new Random(System.DateTime.Now.Millisecond);
    48  
    49        ////返回指定范围内的随机整数
    50        public static int rnd(int nLow, int nUpper)
    51        {
    52            return nLow + (nUpper - nLow) * rand.Next(RAND_MAX) / (RAND_MAX + 1);
    53        }
    54  
    55        //返回指定范围内的随机浮点数
    56        public static double rnd(double dbLow, double dbUpper)
    57        {
    58            double dbTemp = (double)rand.Next(RAND_MAX) / ((double)RAND_MAX + 1.0);
    59            return dbLow + dbTemp * (dbUpper - dbLow);
    60        }
    61  
    62        //返回浮点数四舍五入取整后的浮点数
    63        public static double ROUND(double dbA)
    64        {
    65            return (double)((int)(dbA + 0.5));
    66        }
    67  
    68     }
    69 }
    View Code
      1 using System;
      2 using System.Collections.Generic;
      3 using System.Text;
      4  
      5 namespace ant_C
      6 {
      7     class CAnt
      8     {        
      9    public int[] m_nPath; //蚂蚁走的路径
     10        int[] m_nAllowedCity;//没去过的城市
     11        
     12    int m_nCurCityNo; //当前所在城市编号
     13    int m_nMovedCityCount; //已经去过的城市数量
     14        public double m_dbPathLength; //蚂蚁走过的路径长度
     15  
     16        public CAnt()
     17        {
     18           m_nPath=new int[Common.N_CITY_COUNT];
     19           m_nAllowedCity=new int[Common.N_CITY_COUNT]; //没去过的城市
     20        }
     21  
     22        //初始化函数,蚂蚁搜索前调用
     23        public void Init()
     24        {
     25  
     26            for (int i = 0; i < Common.N_CITY_COUNT; i++)
     27       {
     28       m_nAllowedCity[i]=1; //设置全部城市为没有去过
     29       m_nPath[i]=0; //蚂蚁走的路径全部设置为0
     30       }
     31  
     32       //蚂蚁走过的路径长度设置为0
     33       m_dbPathLength=0.0; 
     34  
     35       //随机选择一个出发城市
     36           m_nCurCityNo = Common.rnd(0, Common.N_CITY_COUNT);
     37  
     38       //把出发城市保存入路径数组中
     39       m_nPath[0]=m_nCurCityNo;
     40  
     41       //标识出发城市为已经去过了
     42       m_nAllowedCity[m_nCurCityNo]=0; 
     43  
     44       //已经去过的城市数量设置为1
     45       m_nMovedCityCount=1; 
     46  
     47        }
     48  
     49        //选择下一个城市
     50        //返回值 为城市编号
     51        public int ChooseNextCity()
     52        {
     53       int nSelectedCity=-1; //返回结果,先暂时把其设置为-1
     54  
     55       //==============================================================================
     56       //计算当前城市和没去过的城市之间的信息素总和
     57       
     58       double dbTotal=0.0;
     59       double[] prob=new double[Common.N_CITY_COUNT]; //保存各个城市被选中的概率
     60  
     61       for (int i=0;i
     62       {
     63       if (m_nAllowedCity[i] == 1) //城市没去过
     64       {
     65                  prob[i] = System.Math.Pow(Common.g_Trial[m_nCurCityNo,i], Common.ALPHA) * System.Math.Pow(1.0 / Common.g_Distance[m_nCurCityNo,i], Common.BETA); //该城市和当前城市间的信息素
     66       dbTotal=dbTotal+prob[i]; //累加信息素,得到总和
     67       }
     68       else //如果城市去过了,则其被选中的概率值为0
     69       {
     70       prob[i]=0.0;
     71       }
     72       }
     73  
     74       //==============================================================================
     75       //进行轮盘选择
     76       double dbTemp=0.0;
     77       if (dbTotal > 0.0) //总的信息素值大于0
     78       {
     79       dbTemp=Common.rnd(0.0,dbTotal); //取一个随机数
     80  
     81       for (int i=0;i
     82       {
     83       if (m_nAllowedCity[i] == 1) //城市没去过
     84       {
     85       dbTemp=dbTemp-prob[i]; //这个操作相当于转动轮盘,如果对轮盘选择不熟悉,仔细考虑一下
     86       if (dbTemp < 0.0) //轮盘停止转动,记下城市编号,直接跳出循环
     87       {
     88       nSelectedCity=i;
     89       break;
     90       }
     91       }
     92       }
     93       }
     94  
     95       //==============================================================================
     96       //如果城市间的信息素非常小 ( 小到比double能够表示的最小的数字还要小 )
     97       //那么由于浮点运算的误差原因,上面计算的概率总和可能为0
     98       //会出现经过上述操作,没有城市被选择出来
     99       //出现这种情况,就把第一个没去过的城市作为返回结果
    100       
    101       //题外话:刚开始看的时候,下面这段代码困惑了我很长时间,想不通为何要有这段代码,后来才搞清楚。
    102       if (nSelectedCity == -1)
    103       {
    104               for (int i = 0; i < Common.N_CITY_COUNT; i++)
    105       {
    106       if (m_nAllowedCity[i] == 1) //城市没去过
    107       {
    108       nSelectedCity=i;
    109       break;
    110       }
    111       }
    112       }
    113  
    114       //==============================================================================
    115       //返回结果,就是城市的编号
    116       return nSelectedCity;
    117        }
    118  
    119        //蚂蚁在城市间移动
    120        public void Move()
    121        {
    122       int nCityNo=ChooseNextCity(); //选择下一个城市
    123  
    124       m_nPath[m_nMovedCityCount]=nCityNo; //保存蚂蚁走的路径
    125       m_nAllowedCity[nCityNo]=0;//把这个城市设置成已经去过了
    126       m_nCurCityNo=nCityNo; //改变当前所在城市为选择的城市
    127       m_nMovedCityCount++; //已经去过的城市数量加1
    128        }
    129  
    130        //计算蚂蚁走过的路径长度
    131        public void CalPathLength()
    132        {
    133  
    134       m_dbPathLength=0.0; //先把路径长度置0
    135       int m=0;
    136       int n=0;
    137  
    138       for (int i=1;i
    139       {
    140       m=m_nPath[i];
    141       n=m_nPath[i-1];
    142       m_dbPathLength=m_dbPathLength+Common.g_Distance[m,n];
    143       }
    144  
    145       //加上从最后城市返回出发城市的距离
    146       n=m_nPath[0];
    147           m_dbPathLength = m_dbPathLength + Common.g_Distance[m,n];
    148  
    149        }
    150  
    151  
    152        //蚂蚁进行搜索一次
    153        public void Search()
    154        {
    155       Init(); //蚂蚁搜索前,先初始化
    156  
    157       //如果蚂蚁去过的城市数量小于城市数量,就继续移动
    158       while (m_nMovedCityCount < Common.N_CITY_COUNT)
    159       {
    160       Move();
    161       }
    162  
    163       //完成搜索后计算走过的路径长度
    164       CalPathLength();
    165        }
    166  
    167  
    168     }
    169 }
    View Code
      1 using System;
      2 using System.Collections.Generic;
      3 using System.Text;
      4  
      5 namespace ant_C
      6 {
      7     class CTsp
      8     {
      9        CAnt []m_cAntAry; //蚂蚁数组
     10        public CAnt m_cBestAnt; //定义一个蚂蚁变量,用来保存搜索过程中的最优结果
     11                              //该蚂蚁不参与搜索,只是用来保存最优结果
     12  
     13        public CTsp()
     14        {
     15           m_cAntAry=new CAnt[Common.N_ANT_COUNT];
     16            for (int i = 0; i < Common.N_ANT_COUNT; i++)
     17            {
     18               m_cAntAry[i] = new CAnt();
     19            }
     20           m_cBestAnt=new CAnt();
     21        }
     22  
     23        //初始化数据
     24        public void InitData()
     25        {
     26  
     27           //先把最优蚂蚁的路径长度设置成一个很大的值
     28           m_cBestAnt.m_dbPathLength = Common.DB_MAX;
     29  
     30           //计算两两城市间距离
     31            double dbTemp = 0.0;
     32            for (int i = 0; i < Common.N_CITY_COUNT; i++)
     33            {
     34               for (int j = 0; j < Common.N_CITY_COUNT; j++)
     35               {
     36                  dbTemp = (Common.x_Ary[i] - Common.x_Ary[j]) * (Common.x_Ary[i] - Common.x_Ary[j]) + (Common.y_Ary[i] - Common.y_Ary[j]) * (Common.y_Ary[i] - Common.y_Ary[j]);
     37                  dbTemp = System.Math.Pow(dbTemp, 0.5);
     38                  Common.g_Distance[i,j] = Common.ROUND(dbTemp);
     39               }
     40            }
     41  
     42           //初始化环境信息素,先把城市间的信息素设置成一样
     43           //这里设置成1.0,设置成多少对结果影响不是太大,对算法收敛速度有些影响
     44            for (int i = 0; i < Common.N_CITY_COUNT; i++)
     45            {
     46               for (int j = 0; j < Common.N_CITY_COUNT; j++)
     47               {
     48                  Common.g_Trial[i,j] = 1.0;
     49               }
     50            }
     51        
     52        }
     53  
     54  
     55        //更新环境信息素
     56        public void UpdateTrial()
     57        {
     58       //临时数组,保存各只蚂蚁在两两城市间新留下的信息素
     59            double[,] dbTempAry = new double[Common.N_CITY_COUNT, Common.N_CITY_COUNT];
     60  
     61           //先全部设置为0
     62            for (int i = 0; i < Common.N_ANT_COUNT; i++) //计算每只蚂蚁留下的信息素
     63            {
     64               for (int j = 1; j < Common.N_CITY_COUNT; j++)
     65               {
     66                  dbTempAry[i, j] = 0.0;
     67               }
     68            }
     69  
     70  
     71       //计算新增加的信息素,保存到临时数组里
     72       int m=0;
     73       int n=0;
     74            for (int i = 0; i < Common.N_ANT_COUNT; i++) //计算每只蚂蚁留下的信息素
     75       {
     76               for (int j = 1; j < Common.N_CITY_COUNT; j++)
     77       {
     78       m=m_cAntAry[i].m_nPath[j];
     79       n=m_cAntAry[i].m_nPath[j-1];
     80                     dbTempAry[n, m] = dbTempAry[n, m] + Common.DBQ / m_cAntAry[i].m_dbPathLength;
     81       dbTempAry[m,n]=dbTempAry[n,m];
     82       }
     83  
     84       //最后城市和开始城市之间的信息素
     85       n=m_cAntAry[i].m_nPath[0];
     86                  dbTempAry[n, m] = dbTempAry[n, m] + Common.DBQ / m_cAntAry[i].m_dbPathLength;
     87       dbTempAry[m,n]=dbTempAry[n,m];
     88  
     89       }
     90  
     91       //==================================================================
     92       //更新环境信息素
     93            for (int i = 0; i < Common.N_CITY_COUNT; i++)
     94       {
     95               for (int j = 0; j < Common.N_CITY_COUNT; j++)
     96       {
     97                  Common.g_Trial[i,j] = Common.g_Trial[i,j] * Common.ROU + dbTempAry[i,j];  //最新的环境信息素 = 留存的信息素 + 新留下的信息素
     98       }
     99       }
    100  
    101        }
    102  
    103  
    104        //开始搜索
    105        public void Search()
    106        {
    107  
    108       //char cBuf[256]; //打印信息用
    109            string strInfo="";
    110           
    111            bool blFlag = false;
    112  
    113       //在迭代次数内进行循环
    114       for (int i=0;i
    115       {
    116               blFlag = false;
    117  
    118       //每只蚂蚁搜索一遍
    119               for (int j = 0; j < Common.N_ANT_COUNT; j++)
    120       {
    121       m_cAntAry[j].Search(); 
    122       }
    123  
    124       //保存最佳结果
    125               for (int j = 0; j < Common.N_ANT_COUNT; j++)
    126       {
    127       if (m_cAntAry[j].m_dbPathLength < m_cBestAnt.m_dbPathLength)
    128       {       
    129                     m_cBestAnt.m_dbPathLength=m_cAntAry[j].m_dbPathLength;
    130                     m_cBestAnt.m_nPath = m_cAntAry[j].m_nPath;
    131  
    132                      blFlag = true;
    133  
    134                  }
    135       }
    136  
    137       //更新环境信息素
    138       UpdateTrial();
    139  
    140       //输出目前为止找到的最优路径的长度
    141               if (blFlag == true)
    142               {
    143                  strInfo = String.Format("[{0}] {1}", i + 1, m_cBestAnt.m_dbPathLength);
    144                  Console.WriteLine(strInfo);
    145               }
    146  
    147  
    148       }
    149  
    150        }
    151  
    152  
    153  
    154     }
    155 }
    View Code
     
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4  
     5  
     6  
     7 namespace ant_C
     8 {
     9  
    10     class AO
    11     {
    12        static void Main(string[] args)
    13        {
    14            CTsp tsp=new CTsp();
    15           tsp.InitData();
    16           tsp.Search();
    17  
    18            string strInfo="";
    19  
    20            strInfo = String.Format("best path length = {0} ", tsp.m_cBestAnt.m_dbPathLength);
    21           Console.WriteLine(strInfo);
    22  
    23            for (int i = 0; i < Common.N_CITY_COUNT; i++)
    24            {
    25               strInfo = String.Format("{0} ", tsp.m_cBestAnt.m_nPath[i] + 1);
    26               Console.Write(strInfo);
    27            }
    28  
    29           Console.Read();
    30  
    31        }
    32     }
    33 }
  • 相关阅读:
    bzoj-2748 2748: [HAOI2012]音量调节(dp)
    bzoj-2338 2338: [HNOI2011]数矩形(计算几何)
    bzoj-3444 3444: 最后的晚餐(组合数学)
    codeforces 709E E. Centroids(树形dp)
    codeforces 709D D. Recover the String(构造)
    codeforces 709C C. Letters Cyclic Shift(贪心)
    codeforces 709B B. Checkpoints(水题)
    codeforces 709A A. Juicer(水题)
    Repeat Number
    hdu 1003 Max Sum (动态规划)
  • 原文地址:https://www.cnblogs.com/fengbol/p/13921920.html
Copyright © 2011-2022 走看看