• 遗传算法解决TSP问题


    基本原理在代码中有注释:

      1 #include<iostream>
      2 #include<string>
      3 #include <cstdlib>
      4 #include<ctime>
      5 #include <cmath>
      6 using  std::string;
      7 
      8 struct Position
      9 {
     10     string EID;
     11     double x;
     12     double y;
     13     double z;
     14 
     15 };
     16 
     17 double TSP(int n, struct Position* position,int T,int population_num,int top_num,int * sort)
     18 {
     19     //T;//迭代次数;
     20     //population_num//种群个数
     21     //top_num 选取前边多少个
     22     int *population;//存放种群编码
     23     int *p;
     24     int getPerm(int *b, int n);
     25     population=(int*)malloc(sizeof(int)*population_num*n);//一维数组存放
     26     double *dis;
     27     dis=(double*)malloc(sizeof(double)*n*n);
     28     double *fitness;
     29     fitness=(double*)malloc(sizeof(double)*population_num);
     30 
     31     int *b;
     32     b=(int*)malloc(sizeof(int)*population_num);
     33 
     34 
     35     int *population1;
     36     population1=(int*)malloc(sizeof(int)*population_num*n);
     37 
     38     int* bb;
     39     bb=(int*)malloc(sizeof(int)*n);
     40 
     41     int* bbb;
     42     bbb=(int*)malloc(sizeof(int)*n);
     43 
     44     p=population;
     45     //产生50个初始种群
     46     srand(time(0));
     47     for(int i=0;i<population_num;i++)
     48     {
     49         getPerm(p,n);
     50         p=p+n;
     51     }
     52     //以上生成了50个初始种群,放在population
     53 
     54     //准备好距离矩阵
     55 
     56     int getDis(struct Position* position,double *dis,int n);
     57     getDis(position,dis,n);
     58     
     59     
     60     
     61 
     62 for(int t=0;t<T;t++)
     63 {
     64     //a计算适应度
     65     for(int i=0;i<population_num;i++)
     66     {
     67         fitness[i]=0;
     68         
     69         for(int j=i*n;j<n+i*n-1;j++)
     70         {
     71             int ii=population[j];
     72             int jj=population[j+1];
     73 
     74             fitness[i]+=dis[ii*n+jj];
     75         }
     76         int ii=population[i*n+n-1];
     77         int jj=population[i*n];
     78         fitness[i]+=dis[ii*n+jj];
     79     }
     80 
     81     
     82     //b对适应度进行排序
     83     int getIndex_double(double *a, int *b,int n);
     84 
     85 
     86     getIndex_double(fitness, b,population_num);
     87 
     88 
     89 
     90     //c选择比较好的个体,放入一个新的矩阵population1
     91     for(int i=0;i<population_num;i++)
     92     {
     93         memcpy(&population1[b[i]*n],&population[i*n],4*n);
     94     }
     95 
     96 
     97 
     98 
     99 
    100     //选取比较好的top_num个体,进行交叉操作,放在从top_num+1开始的top_num/2个
    101     for(int i=top_num;i<population_num;i=i+2)
    102     {
    103         memcpy(&population1[i*n],&population1[(i-top_num)*n],n);
    104         memcpy(&population1[(i+1)*n],&population1[(i+1-top_num)*n],n);
    105 
    106         //选择交叉位置
    107         int pos=rand()%n;
    108         int tmp=population1[i*n+pos];
    109         population1[i*n+pos]=population1[(i+1)*n+pos];
    110         population1[(i+1)*n+pos]=tmp;
    111 
    112         //重新生成排列
    113         int getIndex(int *a, int *b,int n);
    114         getIndex(&population1[i*n],bb,n);
    115         memcpy(&population1[i*n],bb,4*n);
    116 
    117         getIndex(&population1[(i+1)*n],bb,n);
    118         memcpy(&population1[(i+1)*n],bb,4*n);
    119 
    120     }
    121 
    122 
    123     //变异操作
    124     //随机选取其中的以为进行变异
    125     int pos_population=rand()%population_num;
    126     int pos=rand()%n;
    127     int value=rand()%n;
    128     population1[pos_population*n+pos]=value;
    129     int getIndex(int *a, int *b,int n);
    130 
    131     getIndex(&population1[pos_population*n],bbb,n);
    132     memcpy(&population1[pos_population*n],bbb,4*n);
    133 
    134 
    135 
    136     memcpy(population,population1,n*population_num*4);
    137 
    138 
    139 }
    140     //保存在population1中,适应度在fitness中,排序在b
    141     int i;
    142     for(i=0;i<population_num;i++)
    143     {
    144         if(b[i]==0)
    145             break;
    146     }
    147 
    148     memcpy(sort,&population[i*n],n*4);
    149     return fitness[i];
    150      
    151 }
    152 
    153 int getDis(struct Position* position,double *dis,int n)
    154 {
    155     for(int i=0;i<n;i++)
    156     {
    157         for(int j=0;j<n;j++)
    158         {
    159             dis[i*n+j]=sqrt((position[i].x-position[j].x)*(position[i].x-position[j].x)+
    160                 (position[i].y-position[j].y)*(position[i].y-position[j].y)+
    161                 (position[i].z-position[j].z)*(position[i].z-position[j].z));
    162             
    163         }
    164     }
    165     return 0;
    166 }
    167 
    168 int getPerm(int *b, int n)
    169 {
    170     //得到一个随机排列
    171     int getIndex(int *a, int *b,int n); 
    172     int* a;
    173     a=(int*)malloc(sizeof(int)*n);
    174     for(int i=0;i<n;i++)
    175         a[i]=rand()%n;
    176     getIndex(a, b,n);
    177 
    178     return 0;
    179 }
    180 
    181 //产生排列
    182 int getIndex(int *a, int *b,int n)
    183 {
    184     for(int i=0;i<n;i++)
    185     {
    186         b[i]=0;
    187     }
    188     for(int i=0;i<n-1;i++)
    189     {
    190         for(int j=i+1;j<n;j++)
    191         {
    192             if(a[i]>=a[j])
    193                 b[i]++;
    194             else
    195                 b[j]++;
    196         }
    197     }
    198     return 0;
    199 }
    200 
    201 int getIndex_double(double *a, int *b,int n)
    202 {
    203     for(int i=0;i<n;i++)
    204     {
    205         b[i]=0;
    206     }
    207     for(int i=0;i<n-1;i++)
    208     {
    209         for(int j=i+1;j<n;j++)
    210         {
    211             if((a[i]-a[j])>=0.0001)
    212                 b[i]++;
    213             else
    214                 b[j]++;
    215         }
    216     }
    217     return 0;
    218 }

    调用函数为:

     1 #include"tsp.h";
     2 
     3 int main()
     4 {
     5     int n=6,i;
     6     struct Position* person;
     7     struct Position* p;
     8     int *sort;
     9     sort=(int*)malloc(sizeof(int)*n);
    10     person=(struct Position*)malloc(sizeof(Position)*n);
    11     p=person;
    12 
    13     p->x=0;p->y=0;p->z=0;p=p+1;
    14     p->x=2;p->y=0;p->z=0;p=p+1;
    15     p->x=3;p->y=1;p->z=0;p=p+1;
    16     p->x=2;p->y=2;p->z=0;p=p+1;
    17     p->x=0;p->y=2;p->z=0;p=p+1;
    18     p->x=0;p->y=1;p->z=0;p=p+1;
    19 
    20     double dis=TSP(n, person,10,20,10,sort);
    21 
    22     printf("%.1f
    顺序为:",dis);
    23 
    24     for(int i=0;i<n;i++)
    25     {
    26         printf("%d ",sort[i]);
    27     }
    28     printf("
    ");
    29 
    30     system("pause"); 
    31     return 0;
    32 }

    原创文章,转载请注明出处,谢谢!

  • 相关阅读:
    git clone 慢,使用镜像
    Mysql 插入 path 插入不进去值
    os.walk 获取文件夹下所有的文件
    Manjaro安装后你需要这样做(仅有网址)
    Mysql 查询优化
    pandas df.to_csv 可保存为 txt 类型 index 设置索引 header 列名 sep 使用什么进行分隔
    pandas pd.to_markdown() 转换为 Markdown pd.to_latex() 转换为 latex
    pandas 读取txt seq分隔符类型 engine指定引擎 header 不将第一行作为列名
    pandas 读取文件时 header设置列名 index_col 设置索引 usecols 读取哪几列 parse_dates 将哪一列设置为时间类型 nrows 读取数据行数
    numpy cumprod 累乘 cumsum 累加 diff 和前一个元素做差值
  • 原文地址:https://www.cnblogs.com/taokongcn/p/4034333.html
Copyright © 2020-2023  润新知