• java遗传算法


      1 import java.util.*;
      2 public class Tsp {  
      3     private String cityName[]={"北京","上海","天津","重庆","哈尔滨","长春","沈阳","呼和浩特","石家庄","太原","济南","郑州","西安","兰州","银川","西宁","乌鲁木齐","合肥","南京","杭州","长沙","南昌","武汉","成都","贵州","福建","台北","广州","海口","南宁","昆明","拉萨","香港","澳门"};
      4     //private String cityEnd[]=new String[34];
      5     private int cityNum=cityName.length;              //城市个数
      6     private int popSize = 50;               //种群数量
      7     private int maxgens = 20000;            //迭代次数
      8     private double pxover = 0.8;            //交叉概率
      9     private double pmultation = 0.05;       //变异概率
     10     private long[][] distance = new long[cityNum][cityNum];
     11     private int range = 2000;               //用于判断何时停止的数组区间
     12     private class genotype {
     13         int city[] = new int[cityNum];      //单个基因的城市序列
     14         long fitness;                      //该基因的适应度
     15         double selectP;                        //选择概率
     16         double exceptp;                        //期望概率
     17         int isSelected;                        //是否被选择
     18     }
     19     private genotype[] citys = new genotype[popSize];
     20     /**
     21      *    构造函数,初始化种群
     22      */
     23     public Tsp() {
     24         for (int i = 0; i < popSize; i++) {
     25             citys[i] = new genotype();
     26             int[] num = new int[cityNum];
     27             for (int j = 0; j < cityNum; j++)
     28                 num[j] = j;
     29             int temp = cityNum;
     30             for (int j = 0; j < cityNum; j++) {
     31                 int r = (int) (Math.random() * temp);
     32                 citys[i].city[j] = num[r];
     33                 num[r] = num[temp - 1];
     34                 temp--;
     35             }
     36             citys[i].fitness = 0;
     37             citys[i].selectP = 0;
     38             citys[i].exceptp = 0;
     39             citys[i].isSelected = 0;
     40         }
     41         initDistance();
     42     }
     43     /**
     44      *  计算每个种群每个基因个体的适应度,选择概率,期望概率,和是否被选择。
     45      */
     46     public void CalAll(){
     47         for( int i = 0; i< popSize; i++){
     48             citys[i].fitness = 0;
     49             citys[i].selectP = 0;
     50             citys[i].exceptp = 0;
     51             citys[i].isSelected = 0;
     52         }
     53         CalFitness();
     54         CalSelectP();
     55         CalExceptP();
     56         CalIsSelected();
     57     }
     58     /**
     59      *    填充,将多选的填充到未选的个体当中
     60      */
     61     public void pad(){
     62         int best = 0;
     63         int bad = 0;
     64         while(true){           
     65             while(citys[best].isSelected <= 1 && best<popSize-1)
     66                 best ++;
     67             while(citys[bad].isSelected != 0 && bad<popSize-1)
     68                 bad ++;
     69             for(int i = 0; i< cityNum; i++)
     70                 citys[bad].city[i] = citys[best].city[i];
     71                 citys[best].isSelected --;
     72                 citys[bad].isSelected ++;
     73                 bad ++;   
     74             if(best == popSize ||bad == popSize)
     75                 break;
     76         }
     77     }
     78     /**
     79      *    交叉主体函数
     80      */
     81     public void crossover() {
     82         int x;
     83         int y;
     84         int pop = (int)(popSize* pxover /2);
     85         while(pop>0){
     86             x = (int)(Math.random()*popSize);
     87             y = (int)(Math.random()*popSize);
     88             executeCrossover(x,y);//x y 两个体执行交叉
     89             pop--;
     90         }
     91     }
     92     /**
     93      * 执行交叉函数
     94      * @param 个体x
     95      * @param 个体y
     96      * 对个体x和个体y执行佳点集的交叉,从而产生下一代城市序列
     97      */
     98     private void executeCrossover(int x,int y){
     99         int dimension = 0;
    100         for( int i = 0 ;i < cityNum; i++)
    101             if(citys[x].city[i] != citys[y].city[i]){
    102                 dimension ++;
    103             }  
    104         int diffItem = 0;
    105         double[] diff = new double[dimension];
    106         for( int i = 0 ;i < cityNum; i++){
    107             if(citys[x].city[i] != citys[y].city[i]){
    108                 diff[diffItem] = citys[x].city[i];
    109                 citys[x].city[i] = -1;
    110                 citys[y].city[i] = -1;
    111                 diffItem ++;
    112             }  
    113         }
    114         Arrays.sort(diff);
    115         double[] temp = new double[dimension];
    116         temp = gp(x, dimension);
    117         for( int k = 0; k< dimension;k++)
    118             for( int j = 0; j< dimension; j++)
    119                 if(temp[j] == k){
    120                     double item = temp[k];
    121                     temp[k] = temp[j];
    122                     temp[j] = item;
    123                     item = diff[k];
    124                     diff[k] = diff[j];
    125                     diff[j] = item;  
    126                 }
    127         int tempDimension = dimension;
    128         int tempi = 0;
    129         while(tempDimension> 0 ){
    130             if(citys[x].city[tempi] == -1){
    131                 citys[x].city[tempi] = (int)diff[dimension - tempDimension];
    132                 tempDimension --;
    133             }  
    134             tempi ++;
    135         }
    136         Arrays.sort(diff);
    137         temp = gp(y, dimension);
    138         for( int k = 0; k< dimension;k++)
    139             for( int j = 0; j< dimension; j++)
    140                 if(temp[j] == k){
    141                     double item = temp[k];
    142                     temp[k] = temp[j];
    143                     temp[j] = item;
    144                     item = diff[k];
    145                     diff[k] = diff[j];
    146                     diff[j] = item;  
    147                 }
    148         tempDimension = dimension;
    149         tempi = 0;
    150         while(tempDimension> 0 ){
    151             if(citys[y].city[tempi] == -1){
    152                 citys[y].city[tempi] = (int)diff[dimension - tempDimension];
    153                 tempDimension --;
    154             }  
    155             tempi ++;
    156         }
    157     }
    158     /**
    159      * @param individual 个体
    160      * @param dimension    维数
    161      * @return 佳点集   (用于交叉函数的交叉点)    在executeCrossover()函数中使用
    162      */
    163     private double[] gp(int individual, int dimension){
    164         double[] temp = new double[dimension];
    165         double[] temp1 = new double[dimension];
    166         int p = 2 * dimension + 3;
    167         while(!isSushu(p))
    168             p++;
    169         for( int i = 0; i< dimension; i++){
    170             temp[i] = 2*Math.cos(2*Math.PI*(i+1)/p) * (individual+1);
    171             temp[i] = temp[i] - (int)temp[i];
    172             if( temp [i]< 0)
    173                 temp[i] = 1+temp[i];
    174         }
    175         for( int i = 0; i< dimension; i++)
    176             temp1[i] = temp[i];
    177         Arrays.sort(temp1);
    178         //排序
    179         for( int i = 0; i< dimension; i++)
    180             for( int j = 0; j< dimension; j++)
    181                 if(temp[j]==temp1[i])
    182                     temp[j] = i; 
    183         return temp;
    184     }
    185     /**
    186      *    变异
    187      */
    188     public void mutate(){
    189         double random;
    190         int temp;
    191         int temp1;
    192         int temp2;
    193         for( int i = 0 ; i< popSize; i++){
    194             random = Math.random();
    195             if(random<=pmultation){
    196                 temp1 = (int)(Math.random() * (cityNum));
    197                 temp2 = (int)(Math.random() * (cityNum));
    198                 temp = citys[i].city[temp1];
    199                 citys[i].city[temp1] = citys[i].city[temp2];
    200                 citys[i].city[temp2] = temp;
    201             }
    202         }      
    203     }
    204     /**
    205      * 打印当前代数的所有城市序列,以及其相关的参数
    206      */
    207     public void print(){
    208     /**
    209      * 初始化各城市之间的距离
    210      */
    211     private void initDistance(){
    212         for (int i = 0; i < cityNum; i++) {
    213             for (int j = 0; j < cityNum; j++){
    214                 distance[i][j] = Math.abs(i-j);
    215             }
    216         }
    217     }
    218     /**
    219      * 计算所有城市序列的适应度
    220      */
    221     private void CalFitness() {
    222         for (int i = 0; i < popSize; i++) {
    223             for (int j = 0; j < cityNum - 1; j++)
    224                 citys[i].fitness += distance[citys[i].city[j]][citys[i].city[j + 1]];
    225             citys[i].fitness += distance[citys[i].city[0]][citys[i].city[cityNum - 1]];
    226         }
    227     }
    228     /**
    229      * 计算选择概率
    230      */
    231     private void CalSelectP(){
    232         long sum = 0;
    233         for( int i = 0; i< popSize; i++)
    234             sum += citys[i].fitness;
    235         for( int i = 0; i< popSize; i++)
    236             citys[i].selectP = (double)citys[i].fitness/sum;
    237     }
    238     /**
    239      * 计算期望概率
    240      */
    241     private void CalExceptP(){
    242         for( int i = 0; i< popSize; i++)
    243             citys[i].exceptp = (double)citys[i].selectP * popSize;
    244     }
    245     /**
    246      * 计算该城市序列是否较优,较优则被选择,进入下一代
    247      */
    248     private void CalIsSelected(){
    249         int needSelecte = popSize;
    250         for( int i = 0; i< popSize; i++)
    251             if( citys[i].exceptp<1){
    252                 citys[i].isSelected++;
    253                 needSelecte --;
    254             }
    255         double[] temp = new double[popSize];
    256         for (int i = 0; i < popSize; i++) {
    257 //          temp[i] = citys[i].exceptp - (int) citys[i].exceptp;
    258 //          temp[i] *= 10;
    259             temp[i] = citys[i].exceptp*10;
    260         }
    261         int j = 0;
    262         while (needSelecte != 0) {
    263             for (int i = 0; i < popSize; i++) {
    264                 if ((int) temp[i] == j) {
    265                     citys[i].isSelected++;
    266                     needSelecte--;
    267                     if (needSelecte == 0)
    268                         break;
    269                 }
    270             }
    271             j++;
    272         }
    273     }
    274     /**
    275      * @param x
    276      * @return 判断一个数是否是素数的函数
    277      */
    278     private boolean isSushu( int x){
    279            if(x<2) return false;
    280            for(int i=2;i<=x/2;i++)
    281            if(x%i==0&&x!=2) return false;
    282            return true;
    283         }
    284     /**
    285      * @param x 数组
    286      * @return x数组的值是否全部相等,相等则表示x.length代的最优结果相同,则算法结束
    287      */
    288     private boolean isSame(long[] x){
    289         for( int i = 0; i< x.length -1; i++)
    290             if(x[i] !=x[i+1])
    291                 return false;
    292         return true;
    293     }
    294     /**
    295      * 打印任意代最优的路径序列
    296      */
    297     private void printBestRoute(){
    298         CalAll();
    299         long temp = citys[0].fitness;
    300         int index = 0;
    301         for (int i = 1; i < popSize; i++) {
    302             if(citys[i].fitness<temp){
    303                 temp = citys[i].fitness;
    304                 index = i;
    305             }
    306         }
    307         System.out.println();
    308         System.out.println("最佳路径的序列:");
    309         for (int j = 0; j < cityNum; j++)
    310         {
    311             String cityEnd[]={cityName[citys[index].city[j]]};
    312             for(int m=0;m<cityEnd.length;m++)
    313             {
    314                 System.out.print(cityEnd[m] + " ");
    315             }
    316         }
    317             //System.out.print(citys[index].city[j] + cityName[citys[index].city[j]] + "  ");
    318             //System.out.print(cityName[citys[index].city[j]]);
    319         System.out.println();
    320     }
    321     /**
    322      * 算法执行
    323      */
    324     public void run(){
    325         long[] result = new long[range];
    326         //result初始化为所有的数字都不相等
    327         for( int i  = 0; i< range; i++)
    328             result[i] = i;
    329         int index = 0;       //数组中的位置
    330         int num = 1;     //第num代
    331         while(maxgens>0){
    332             System.out.println("-----------------  第  "+num+" 代  -------------------------");
    333             CalAll();
    334             print();
    335             pad();
    336             crossover();
    337             mutate();
    338             maxgens --;
    339             long temp = citys[0].fitness;
    340             for ( int i = 1; i< popSize; i++)
    341                 if(citys[i].fitness<temp){
    342                     temp = citys[i].fitness;
    343                 }
    344             System.out.println("最优的解:"+temp);
    345             result[index] = temp;
    346             if(isSame(result))
    347                 break;
    348             index++;
    349             if(index==range)
    350                 index = 0;
    351             num++;
    352         }
    353         printBestRoute();
    354     }
    355     /**
    356      * @param a 开始时间
    357      * @param b   结束时间
    358      */
    359     public void CalTime(Calendar a,Calendar b){
    360         long x = b.getTimeInMillis() - a.getTimeInMillis();
    361         long y = x/1000;
    362         x = x - 1000*y;
    363         System.out.println("算法执行时间:"+y+"."+x+" 秒");
    364     }
    365     /**
    366      *    程序入口 
    367      */
    368     public static void main(String[] args) {
    369         Calendar a = Calendar.getInstance(); //开始时间
    370         Tsp tsp = new Tsp();
    371         tsp.run();
    372         Calendar b = Calendar.getInstance(); //结束时间
    373         tsp.CalTime(a, b);
    374     }
    375 }
    如果有使用请标明来源:http://www.cnblogs.com/duwenlei/
  • 相关阅读:
    【星云测试】Wings-面向企业级的单元测试用例自动编码引擎最新发布
    【星云测试】Wings企业级单元测试自动编码引擎白皮书
    Redis基础之命令篇
    Redis安装与启动
    My Self Introduction
    这就是小学生也会用的四则计算练习APP吗?- by软工结对编程项目作业
    Java余弦计算文本相似度项目—第一次个人编程作业(软件工程)
    Android 开发学习进程0.26 fragment的工厂实例化
    Android 开发学习进程0.25 自定义控件
    Android开发学习进程 0.24 存储机制
  • 原文地址:https://www.cnblogs.com/duwenlei/p/3585914.html
Copyright © 2020-2023  润新知