遗传算法解决网络布线问题 tsp

Code:
  1. // File: CgaTsp.h the head of class   
  2. #ifndef GATSP_H   
  3. #define GATSP_H   
  4.   
  5. #include <vector>   
  6. #include <fstream>   
  7. #include <algorithm>   
  8. #include <iostream>   
  9. using namespace std;   
  10.   
  11.   
  12.   
  13. // 变异概率                
  14. #define MUTATION_RATE       0.2   
  15.   
  16. // 杂交概率   
  17. #define CROSSOVER_RATE  0.75   
  18.   
  19. // 基因组数目   
  20. #define POP_SIZE              40   
  21.   
  22. // 为2的倍数   
  23. #define NUM_BEST_TO_ADD 2   
  24.   
  25. // 产生随机数   
  26. inline int    RandInt(int x,int y)   
  27. {   
  28.   
  29.     return rand()%(y-x+1)+x;   
  30. }   
  31. inline double RandFloat()            
  32. {   
  33.   
  34.     return (rand())/(RAND_MAX+1.0);   
  35. }   
  36.   
  37. // 计算机坐标结构   
  38. struct CoOrd   
  39. {   
  40.         float x,y;   
  41.         CoOrd(){};   
  42.         CoOrd(float a, float b):x(a),y(b){};   
  43. };   
  44.   
  45. // 基因组结构   
  46. struct SGenome   
  47. {   
  48.     // 连接计算机间的路径(基因组)   
  49.     vector<int>     vecPC;   
  50.        
  51.    // 适应分数   
  52.   double         dFitness;   
  53.   
  54.   
  55.     // 构造函数   
  56.     SGenome():dFitness(0){}   
  57.        
  58.     SGenome(int nc): dFitness(0)   
  59.     {   
  60.         vecPC = GrabPermutation(nc);   
  61.     }   
  62.   
  63.     // 创建计算机间随机的一条路径   
  64.     vector<int> GrabPermutation(int &limit);   
  65.   
  66.     // 在GrabPermutation函数中使用   
  67.     bool        TestNumber(const vector<int> &vec, const int &number);   
  68.   
  69. };   
  70.   
  71.   
  72. // 遗传算法类   
  73. class CgaTSP   
  74. {   
  75. private:   
  76.   
  77.     // 计算机坐标向量   
  78.     vector<CoOrd> m_vecPCCoOrds;   
  79.     vector<SGenome>     m_vecPopulation;   
  80.     vector<int>  m_savevecPC;   
  81.   
  82.   
  83.     double              m_dMutationRate;   
  84.   
  85.     double              m_dCrossoverRate;   
  86.   
  87.     // 整个种子群体的总适应性分   
  88.     double              m_dTotalFitness;   
  89.        
  90.     // 在此之前找到的最短路径   
  91.     double              m_dShortestRoute;   
  92.     // 把所有代中的最短路径保存起来   
  93.     double              m_saveShortestRoute;   
  94.   
  95.     // 最长路径   
  96.     double              m_dLongestRoute;   
  97.   
  98.     // 种子群中的基因组数目   
  99.     int                   m_iPopSize;   
  100.   
  101.     // 染色体数目   
  102.     int                   m_iChromoLength;   
  103.   
  104.     // 新一代中适应分最高的成员   
  105.     int                   m_iFittestGenome;   
  106.   
  107.     // 表明已经到了那一代   
  108.     int                   m_iGeneration;   
  109.   
  110.     // 交换变异   
  111.     void              MutateEM(vector<int> &chromo);   
  112.   
  113.   
  114.   
  115.     // 部分匹配杂交   
  116.     void              CrossoverPMX(const vector<int> &mum,    
  117.                                    const vector<int> &dad,    
  118.                                            vector<int>       &baby1,    
  119.                                            vector<int>       &baby2);   
  120.         
  121.     SGenome&        RouletteWheelSelection();   
  122.   
  123.   
  124.     // 计算计算机之间连接路径的长度   
  125.      double   GetTourLength(const vector<int> &route);   
  126.   
  127.     void             CalculatePopulationsFitness();   
  128.   
  129.     void             CalculateBestWorstAvTot();   
  130.        
  131.     void             Reset();   
  132.   
  133.     void             CreateStartingPopulation();   
  134.   
  135.     // 计算两个计算之间的长度   
  136.     double  CalculateA_to_B(const CoOrd &PC1, const CoOrd &PC2);   
  137.   
  138.     // 建立坐标   
  139.     void CreateCoOrd();   
  140.   
  141. public:   
  142.   
  143.     // 构造函数   
  144.     CgaTSP(double     mut_rat,   
  145.              double   cross_rat,   
  146.              int          pop_size,   
  147.              int          NumPC   
  148.          ):m_dMutationRate(mut_rat),   
  149.             m_dCrossoverRate(cross_rat),   
  150.             m_iPopSize(pop_size),   
  151.                         m_iFittestGenome(0),   
  152.                         m_iGeneration(0),   
  153.                         m_dShortestRoute(999999999),   
  154.                         m_saveShortestRoute(999999999),   
  155.                         m_dLongestRoute(0),   
  156.                         m_iChromoLength(NumPC)   
  157.                                          
  158.   
  159.   
  160.     {   
  161.         // 建立坐标   
  162.             CreateCoOrd();   
  163.             // 清除基因组生成新的基因组   
  164.         CreateStartingPopulation();   
  165.     }   
  166.   
  167.   
  168.     ~CgaTSP()   
  169.     {   
  170.     }   
  171.   
  172. // 把所有的遗传算法的步骤进行合并到一个函数   
  173.   void  Epoch();   
  174.   void Show();   
  175. };   
  176.   
  177. #endif   
  178.   
  179. //File: CgaTsp.cpp    
  180. #include "CgaTSP.h"   
  181. #include <math.h>   
  182. #include <time.h>   
  183. #include <vector>   
  184. #include <fstream>   
  185. #include <algorithm>   
  186. #include <iostream>   
  187. using namespace std;   
  188.   
  189. // 随机生成一个基因并返回   
  190. vector<int> SGenome::GrabPermutation(int &limit)   
  191. {   
  192.     vector<int> vecPerm;   
  193.        
  194.     for (int i=0; i<limit; i++)   
  195.     {   
  196.         // 0到limint-1为计算机的序号   
  197.         int NextPossibleNumber = RandInt(0, limit-1);   
  198.   
  199.         // 向量中存在随见生成的序号就在生成一次   
  200.         while(TestNumber(vecPerm, NextPossibleNumber))   
  201.         {   
  202.             NextPossibleNumber = RandInt(0, limit-1);   
  203.         }   
  204.            
  205.         // 把新生成的序号放进向量   
  206.         vecPerm.push_back(NextPossibleNumber);   
  207.     }   
  208.   
  209.     // 返回基因   
  210.     return vecPerm;   
  211. }   
  212.   
  213. // 测试number是否已经存在向量中   
  214. bool SGenome::TestNumber(const vector<int> &vec, const int &number)   
  215. {   
  216.     for (int i=0; i<vec.size(); ++i)   
  217.     {   
  218.         if (vec[i] == number)   
  219.         {   
  220.             return true;   
  221.         }   
  222.     }   
  223.   
  224.     return false;   
  225. }   
  226.   
  227. // 计算路径长度和适应性分   
  228. void CgaTSP::CalculatePopulationsFitness()   
  229. {   
  230.     // 对于每组基因计算路径长度   
  231.     for (int i=0; i<m_iPopSize; ++i)   
  232.     {   
  233.   
  234.         // 计算计算机间路径的总长度   
  235.         double TourLength = GetTourLength(m_vecPopulation[i].vecPC);   
  236.   
  237.            
  238.         m_vecPopulation[i].dFitness = TourLength;   
  239.            
  240.            
  241.         if (TourLength < m_dShortestRoute)   
  242.         {   
  243.             m_dShortestRoute = TourLength;   
  244.   
  245.             // 代表适应性分最高的成员   
  246.             m_iFittestGenome = i;   
  247.         }   
  248.            
  249.            
  250.         if (TourLength > m_dLongestRoute)   
  251.         {   
  252.             m_dLongestRoute = TourLength;   
  253.         }   
  254.   
  255.     }   
  256.   
  257.     // 计算适应性分   
  258.     for (i=0; i<m_iPopSize; ++i)   
  259.     {   
  260.         m_vecPopulation[i].dFitness =    
  261.         m_dLongestRoute - m_vecPopulation[i].dFitness;   
  262.     }   
  263.   
  264. }   
  265.   
  266. // 计算两个计算机之间的路径长度   
  267. double CgaTSP::CalculateA_to_B(const CoOrd &PC1, const CoOrd &PC2)   
  268. {   
  269.     double xDist = PC1.x - PC2.x;   
  270.     double yDist = PC1.y - PC2.y;   
  271.        
  272.     return sqrt(xDist*xDist + yDist*yDist);   
  273. }   
  274.   
  275. // 计算所有计算机连接起来的路径长度   
  276. double CgaTSP::GetTourLength(const vector<int> &route)   
  277. {   
  278.     double TotalDistance = 0;   
  279.        
  280.     for (int i=0; i<route.size()-1; ++i)   
  281.     {   
  282.         int PC1 = route[i];   
  283.         int PC2 = route[i+1];   
  284.            
  285.         TotalDistance += CalculateA_to_B(m_vecPCCoOrds[PC1], m_vecPCCoOrds[PC2]);   
  286.     }   
  287.     // 返回总的路径长度   
  288.     return TotalDistance;   
  289. }   
  290.   
  291. // 选择基因(轮盘赌选择法)   
  292. SGenome& CgaTSP::RouletteWheelSelection()   
  293. {   
  294.     // 随机生成0到1的数乘以总的适应性分   
  295.     double fSlice   = RandFloat() * m_dTotalFitness;   
  296.        
  297.     double cfTotal  = 0.0;   
  298.        
  299.     int SelectedGenome = 0;   
  300.        
  301.     for (int i=0; i<m_iPopSize; ++i)   
  302.     {   
  303.         // 累计适应性分   
  304.         cfTotal += m_vecPopulation[i].dFitness;   
  305.            
  306.         if (cfTotal > fSlice)    
  307.         {   
  308.             SelectedGenome = i;   
  309.                
  310.             break;   
  311.         }   
  312.     }   
  313.        
  314.     return m_vecPopulation[SelectedGenome];   
  315. }   
  316.   
  317.   
  318. void ChooseSection(int &beg,   
  319.                    int &end,   
  320.                    const int vec_size,   
  321.                    const int min_span)   
  322. {   
  323.        
  324.     beg = RandInt(0, vec_size-1-min_span);   
  325.        
  326.     end = beg;   
  327.        
  328.     //find an end   
  329.     while (end <= beg)   
  330.     {   
  331.         end = RandInt(0, vec_size-1);   
  332.     }   
  333. }   
  334.   
  335. // 交换变异操作(随机基因进行交换)   
  336. void CgaTSP::MutateEM(vector<int> &chromo)   
  337. {   
  338.     // 根据变异率确定是否发生变异   
  339.     if (RandFloat() > m_dMutationRate)    
  340.         return;   
  341.   
  342.     // 选择第一个基因(计算机)   
  343.     int pos1 = RandInt(0, chromo.size()-1);   
  344.   
  345.     // 选择第二个基因(计算机)   
  346.     int pos2 = pos1;   
  347.   
  348.     while (pos1 == pos2)   
  349.     {   
  350.         pos2 = RandInt(0, chromo.size()-1);   
  351.     }   
  352.   
  353.     // 交换位置   
  354.     swap(chromo[pos1], chromo[pos2]);   
  355. }   
  356.   
  357. // 置换杂交   
  358. void CgaTSP::CrossoverPMX(const vector<int> &mum,    
  359.                                         const vector<int>   &dad,    
  360.                                         vector<int>       &baby1,    
  361.                                         vector<int>       &baby2)   
  362. {   
  363.     baby1 = mum;   
  364.     baby2 = dad;   
  365.        
  366.     // 杂交率   
  367.     if ( (RandFloat() > m_dCrossoverRate) || (mum == dad))    
  368.     {   
  369.         return;   
  370.     }   
  371.   
  372.     // 选择基因组的一节   
  373.     int beg = RandInt(0, mum.size()-2);   
  374.        
  375.     int end = beg;   
  376.        
  377.     // 在选择另一节   
  378.     while (end <= beg)   
  379.     {   
  380.         end = RandInt(0, mum.size()-1);   
  381.     }   
  382.   
  383.        
  384.     vector<int>::iterator posGene1, posGene2;   
  385.   
  386.     for (int pos = beg; pos < end+1; ++pos)   
  387.     {   
  388.         // 交换的两个基因   
  389.         int gene1 = mum[pos];   
  390.         int gene2 = dad[pos];   
  391.   
  392.         if (gene1 != gene2)   
  393.         {   
  394.             // 在第一个后代中进行交换   
  395.             posGene1 = find(baby1.begin(), baby1.end(), gene1);   
  396.             posGene2 = find(baby1.begin(), baby1.end(), gene2);   
  397.   
  398.             swap(*posGene1, *posGene2);   
  399.   
  400.             // 在第二个后代中进行交换   
  401.             posGene1 = find(baby2.begin(), baby2.end(), gene1);   
  402.             posGene2 = find(baby2.begin(), baby2.end(), gene2);   
  403.                
  404.             swap(*posGene1, *posGene2);   
  405.         }   
  406.            
  407.     }// 下一对基因   
  408. }      
  409.   
  410. // 清除基因组生成新的基因组   
  411. void CgaTSP::CreateStartingPopulation()   
  412. {   
  413.   
  414.     m_vecPopulation.clear();   
  415.        
  416.     // 基因组数目   
  417.     for (int i=0; i<m_iPopSize; ++i)   
  418.     {   
  419.         m_vecPopulation.push_back(SGenome(m_iChromoLength));   
  420.     }   
  421.     m_iGeneration    = 0;   
  422.     m_dShortestRoute = 9999999;   
  423.     m_iFittestGenome = 0;   
  424.   
  425. }   
  426.   
  427. void CgaTSP::Reset()   
  428. {   
  429.   
  430.     m_dShortestRoute    = 999999999;   
  431.     m_dLongestRoute     = 0;   
  432.     m_dTotalFitness     = 0;   
  433. }   
  434.   
  435. void CgaTSP::Epoch()   
  436. {   
  437.   
  438.     // 设置变量   
  439.     Reset();   
  440.        
  441.     // 计算每个基因组的适应性分   
  442.     CalculatePopulationsFitness();   
  443.     if (m_dShortestRoute < m_saveShortestRoute)   
  444.     {   
  445.         m_saveShortestRoute = m_dShortestRoute;   
  446.         // 把路径保存下来   
  447.          m_savevecPC = m_vecPopulation[m_iFittestGenome].vecPC;   
  448.   
  449.     }   
  450.   
  451.     // 为新种群创建临时向量   
  452.     vector<SGenome> vecNewPop;   
  453.   
  454.     // 把上一代中最适应的精英加入到种群   
  455.     for (int i=0; i<NUM_BEST_TO_ADD; ++i)   
  456.     {   
  457.         vecNewPop.push_back(m_vecPopulation[m_iFittestGenome]);   
  458.     }   
  459.        
  460.   
  461.     // 创建种群的其他成员   
  462.     while (vecNewPop.size() != m_iPopSize)   
  463.     {   
  464.        
  465.         // 选取两个基因作为父代   
  466.         SGenome mum = RouletteWheelSelection();   
  467.         SGenome dad = RouletteWheelSelection();   
  468.   
  469.         // 两个后代   
  470.         SGenome baby1, baby2;   
  471.            
  472.         // 进行杂交   
  473.         CrossoverPMX(mum.vecPC,   
  474.                            dad.vecPC,   
  475.                            baby1.vecPC,   
  476.                            baby2.vecPC);   
  477.   
  478.         // 变异   
  479.         MutateEM(baby1.vecPC);   
  480.         MutateEM(baby2.vecPC);   
  481.   
  482.         // 加入新种群   
  483.         vecNewPop.push_back(baby1);   
  484.         vecNewPop.push_back(baby2);   
  485.     }   
  486.   
  487.     // 复制到下一代   
  488.     m_vecPopulation = vecNewPop;   
  489.   
  490.     // 代数加一   
  491.     ++m_iGeneration;   
  492. }   
  493.   
  494. // 建立坐标   
  495. void CgaTSP::CreateCoOrd()   
  496. {   
  497.     CoOrd ThisPC;   
  498.     float x;   
  499.     float y;   
  500.     for (int i=0; i<m_iChromoLength; i++)   
  501.     {   
  502.         scanf("%f%f", &x,&y);   
  503.         ThisPC.x = x;   
  504.         ThisPC.y = y;   
  505.         m_vecPCCoOrds.push_back(ThisPC);   
  506.     }   
  507. }   
  508.   
  509. // 输出结果   
  510. void CgaTSP::Show()   
  511.   {   
  512.       int k;   
  513.       int p;   
  514.     for(int i=0; i<m_iChromoLength-1; i++)   
  515.     {   
  516.         // 获取相邻两个电脑之间的序号   
  517.         k = m_savevecPC[i];   
  518.         p = m_savevecPC[i+1];   
  519.         printf("Cable requirement to connect(%.0f,%.0f) to (%.0f,%.f) is %.2lf/n",m_vecPCCoOrds[k].x , m_vecPCCoOrds[k].y,    
  520.             m_vecPCCoOrds[p].x, m_vecPCCoOrds[p].y, CalculateA_to_B(m_vecPCCoOrds[k], m_vecPCCoOrds[p])+16);   
  521.     }   
  522.     printf("Number of feet of cable required is%.2lf/n", m_saveShortestRoute + 16*(m_iChromoLength-1));   
  523.   }   
  524.   
  525. // 主函数   
  526. int main()   
  527. {   
  528.     CgaTSP* tsp;   
  529.     srand( (unsigned)time( NULL ) );   
  530.     // 输入计算机数   
  531.     int nc;   
  532.     int flag=0;   
  533.     while(scanf("%d", &nc) && nc !=0)   
  534.     {   
  535.         // 初始化遗传算法类   
  536.         tsp = new CgaTSP(MUTATION_RATE,   
  537.                        CROSSOVER_RATE,   
  538.                            POP_SIZE,   
  539.                         nc);   
  540.   
  541.         // 进行50进化   
  542.         for(int i=0; i<50; i++)   
  543.         tsp->Epoch();   
  544.         printf("Network # %d/n", ++flag);   
  545.         tsp->Show();   
  546.   
  547.         // 释放空间   
  548.         delete tsp;   
  549.   
  550.     }   
  551.            
  552.         return 0;   
  553. }  

 

你可能感兴趣的:(算法,网络,测试,null,IM)