用遗传算法实现旅行商问题的Java实现

用遗传算法实现旅行商问题的Java实现
利用工作之余,实现了这个算法。
从小便喜欢人工智能,梦想长大成为科学家,去研究机器人。
实现这个算法,也算是对小时候的梦想迈出了一小步吧!
网上找了很久,找不到java实现,所以就自己切身写了一下。
如果也有同样爱好者,请联系我:
msn be_heackAThotmail.com
程序模拟的是在10*10的一个城市当中,在ENV.java里面定义了15个城市(城市数目可以调整)
现在贴源代码如下。
ENV.java 一些环境信息,也包含进化的一些数据,比如变异率,等等。
 1  /**
 2   * 
 3    */
 4  package  geneAlgo;
 5 
 6  import  java.util.ArrayList;
 7  import  java.util.List;
 8 
 9  /**
10   *  @author  KONGHE
11   * 
12    */
13  public   class  ENV {
14       public   static   int  GENE_LENGTH  =   15 ;//如果要添加新的城市,必须要修改这里对应
15 
16       public   static   int  GROUP_SIZE  =   50 ;
17 
18       public   static   double  DISSOCIATION_RATE  =   0.01 ;
19 
20       public   static   double  ADAPT_GOAL  =   26.6 ;
21 
22       public   static   int  SEQ_MAX_GROUP  =   8 ;
23 
24       public   static   int  SEQ_GROUP_MAX_LENGTH  =   13 ;
25 
26       public   static   int  SEQ_BREAK_START  =   1 ;
27 
28       public   static   double  CHANGE_FIRST_SEQ  =   0.5 ;
29 
30       public   static   double  IF_HAVE_CHILDREN  =   0.8 ;
31 
32       public   static   int  KEEP_BEST_NUM  =   1 ; //  keep the best to next generation
33 
34       public   static   int  DIS_AFTER_MAX_GENE  =   40 ; // after how many generation will it change itself
35 
36       //  how much rate to keep bad rate while compare
37       public   static   double  KEEP_BAD_INDIVIDAL  =   0.0 ;
38 
39       public   static   double  KEEP_BAD_INDIVIDAL_MAX  =   0.5 ;
40 
41       public   static   double  KEEP_BAD_INDIVIDAL_MIN  =   0.0 ;
42 
43       public   static   int  CITIES_LIST[][]  =   new   int [ENV.GENE_LENGTH][ 2 ];
44       static  {
45          CITIES_LIST[ 0 ][ 0 =   1 ;
46          CITIES_LIST[ 0 ][ 1 =   1 ;
47          CITIES_LIST[ 1 ][ 0 =   3 ;
48          CITIES_LIST[ 1 ][ 1 =   1 ;
49          CITIES_LIST[ 2 ][ 0 =   2 ;
50          CITIES_LIST[ 2 ][ 1 =   2 ;
51          CITIES_LIST[ 3 ][ 0 =   1 ;
52          CITIES_LIST[ 3 ][ 1 =   4 ;
53          CITIES_LIST[ 4 ][ 0 =   3 ;
54          CITIES_LIST[ 4 ][ 1 =   5 ;
55          CITIES_LIST[ 5 ][ 0 =   5 ;
56          CITIES_LIST[ 5 ][ 1 =   4 ;
57          CITIES_LIST[ 6 ][ 0 =   6 ;
58          CITIES_LIST[ 6 ][ 1 =   2 ;
59          CITIES_LIST[ 7 ][ 0 =   7 ;
60          CITIES_LIST[ 7 ][ 1 =   4 ;
61          CITIES_LIST[ 8 ][ 0 =   8 ;
62          CITIES_LIST[ 8 ][ 1 =   5 ;
63          CITIES_LIST[ 9 ][ 0 =   8 ;
64          CITIES_LIST[ 9 ][ 1 =   7 ;
65          CITIES_LIST[ 10 ][ 0 =   4 ;
66          CITIES_LIST[ 10 ][ 1 =   8 ;
67          CITIES_LIST[ 11 ][ 0 =   6 ;
68          CITIES_LIST[ 11 ][ 1 =   6 ;
69          CITIES_LIST[ 12 ][ 0 =   4 ;
70          CITIES_LIST[ 12 ][ 1 =   2 ;
71          CITIES_LIST[ 13 ][ 0 =   7 ;
72          CITIES_LIST[ 13 ][ 1 =   6 ;
73          CITIES_LIST[ 14 ][ 0 =   2 ;
74          CITIES_LIST[ 14 ][ 1 =   7 ;
75      }
76 
77       public   static   long  getRandomInt( long  from,  long  to) {
78 
79           return  from  >  to  ?  from : ( long ) Math.round(Math.random()  *  (to  -  from)  +  from);
80      }
81 
82       public   static   boolean  doOrNot( double  rate) {
83           return  Math.random()  <=  rate;
84      }
85 
86       public   static  List getGeneLinkList() {
87          List geneList  =   new  ArrayList();
88           for  ( int  i  =   1 ; i  <=  ENV.GENE_LENGTH  -   1 ; i ++ ) {
89              geneList.add(i);
90          }
91           return  geneList;
92      }
93  }
94 
Evolution.java 主程序
 1  package  geneAlgo;
 2 
 3  public   class  Evolution {
 4 
 5       public   static   void  main(String[] args) {
 6          Population originalPopulation  =  Population.getOriginalPopulation();
 7          
 8          Individal x  =  Individal.getRandomIndividal();
 9 
10           int  i  =   0 ;
11           while  (originalPopulation.getBestAdapt().getAdaptability()  >  ENV.ADAPT_GOAL) {
12  //         while(i<20){
13              originalPopulation.evolute();
14              originalPopulation.printBest();
15  //             originalPopulation.print();
16              i ++ ;
17          }
18          originalPopulation.printBest();
19           //  Individal y = Individal.getRandomIndividal();
20           //  x.print();
21           //  y.print();
22           //   //   // x.print();
23           //  x.makeBabyWith(y);
24 
25           //  GeneSeqMap map = new GeneSeqMap();
26           //  map.addObjects(3, 4);
27           //  map.addObjects(4, 6);
28           //  map.addObjects(7, 3);
29           //  map.print();
30           //  Population x = evolution.getOriginalPopulation();
31           //   // System.out.println(x.getAdaptability());
32           //  x.print();
33           //  System.out.println(ENV.doOrNot(1));
34      }
35 
36  }
37 
GeneSeqMap.java 工具类
 1  package  geneAlgo;
 2 
 3  import  java.util.HashMap;
 4  import  java.util.Iterator;
 5  import  java.util.Map;
 6  import  java.util.Set;
 7 
 8  public   class  GeneSeqMap {
 9       private  Map < Integer, Integer >  seqMap  =   new  HashMap < Integer, Integer > ();
10 
11       public   void  addObjects( int  a,  int  b) {
12           if  (seqMap.containsKey(b)  &&  seqMap.get(b)  ==  a) {
13              seqMap.remove(b);
14               return ;
15          }
16           if  (seqMap.containsKey(a)) {
17               //  in this project, it's not possible
18               int  tempValue  =  seqMap.get(a);
19              seqMap.remove(a);
20              seqMap.put(b, tempValue);
21               return ;
22          }  else   if  (seqMap.containsValue(a)) {
23              Set entries  =  seqMap.entrySet();
24              Iterator iter  =  entries.iterator();
25               while  (iter.hasNext()) {
26                  Map.Entry entry  =  (Map.Entry) iter.next();
27                  Integer key  =  (Integer) entry.getKey();
28                  Integer value  =  (Integer) entry.getValue();
29                   if  (value  ==  a) {
30                      seqMap.remove(key);
31                      seqMap.put(key, b);
32                       if (seqMap.containsKey(b)){
33                           int  val = seqMap.get(b);
34                          seqMap.remove(b);
35                          seqMap.remove(key);
36                          seqMap.put(key, val);
37                      }
38                       return ;
39                  }
40              }
41          }
42           if  (seqMap.containsKey(b)) {
43               int  value  =  seqMap.get(b);
44              seqMap.remove(b);
45              seqMap.put(a, value);
46               return ;
47          }  else   if  (seqMap.containsValue(b)) {
48               //  it's not possible
49               return ;
50          }
51          seqMap.put(a, b);
52      }
53 
54       public  Integer getValueByKey(Integer key) {
55           if  (seqMap.containsKey(key)) {
56               return  seqMap.get(key);
57          }  else  {
58               return   null ;
59          }
60      }
61 
62       public  Integer getKeyByValue(Integer value) {
63           if  (seqMap.containsValue(value)) {
64              Set entries  =  seqMap.entrySet();
65              Iterator iter  =  entries.iterator();
66               while  (iter.hasNext()) {
67                  Map.Entry < Integer, Integer >  entry  =  (Map.Entry < Integer, Integer > ) iter.next();
68                  Integer key  =  entry.getKey();
69                  Integer val  =  entry.getValue();
70                   if  (value  ==  val) {
71                       return  key;
72                  }
73              }
74          } 
75           return   null ;
76          
77      }
78 
79       public   void  print() {
80          Set < Integer >  keys  =  seqMap.keySet();
81          Iterator iter  =  keys.iterator();
82           while  (iter.hasNext()) {
83              Integer key  =  (Integer) iter.next();
84              System.out.println(key  +   "   "   +  seqMap.get(key)  +   " ; " );
85          }
86      }
87  }
88 
Individal.java 个体类
  1  package  geneAlgo;
  2 
  3  import  java.util.ArrayList;
  4  import  java.util.List;
  5 
  6  public   class  Individal {
  7       private   int  genes[]  =   new   int [ENV.GENE_LENGTH];
  8 
  9       public   int [] getGenes() {
 10           return  genes;
 11      }
 12 
 13       public   void  setGenes( int [] genes) {
 14           this .genes  =  genes;
 15      }
 16 
 17       private   int [] getClone( int [] source) {
 18           int  result[]  =   new   int [source.length];
 19           for  ( int  i  =   0 ; i  <  source.length; i ++ ) {
 20              result[i]  =  source[i];
 21          }
 22           return  result;
 23      }
 24 
 25       public  Individal[] makeBabyWith(Individal partner) {
 26           //  parents have only two children
 27          Individal children[]  =   new  Individal[ 2 ];
 28           int  genes1[]  =  getClone( this .genes);
 29           int  genes2[]  =  getClone(partner.getGenes());
 30           if  (ENV.doOrNot(ENV.IF_HAVE_CHILDREN)) {
 31              GeneSeqMap seqMap  =   new  GeneSeqMap(); //  used to correct illegal exchange
 32              List < Integer >  seqBreak  =   new  ArrayList < Integer > ();
 33              List < Integer >  seqChange  =   new  ArrayList < Integer > ();
 34              seqBreak.add(ENV.SEQ_BREAK_START);
 35               int  i  =  ( int ) ENV.getRandomInt( 1 , ENV.GENE_LENGTH  -  ENV.SEQ_BREAK_START  -   1 );
 36               int  j  =   1 ;
 37               while  (seqBreak.get(seqBreak.size()  -   1 +  i  <=  ENV.GENE_LENGTH  -   1   &&  j  <=  ENV.SEQ_MAX_GROUP) {
 38                  seqBreak.add(seqBreak.get(seqBreak.size()  -   1 +  i);
 39                  i  =  ( int ) ENV.getRandomInt(i  +   1 , ENV.GENE_LENGTH);
 40              }
 41 
 42              j  =   0 ;
 43               boolean  changeFirstSeq  =  ENV.doOrNot(ENV.CHANGE_FIRST_SEQ);
 44               for  (i  =   0 ; i  <  seqBreak.size(); i ++ ) {
 45                   int  nextBreakPos  =  (i  ==  seqBreak.size()  -   1   ?  ENV.GENE_LENGTH : seqBreak.get(i  +   1 ));
 46                   for  ( int  m  =  seqBreak.get(i); m  <  nextBreakPos; m ++ ) {
 47                       if  ((j  ==   0   &&  changeFirstSeq)  ||  (j  ==   1   &&   ! changeFirstSeq)) {
 48                          seqMap.addObjects(genes1[m], genes2[m]);
 49                           int  temp  =  genes1[m];
 50                          genes1[m]  =  genes2[m];
 51                          genes2[m]  =  temp;
 52                          seqChange.add(m);
 53                      }  else  {
 54                           break ;
 55                      }
 56                  }
 57                  j  =   1   -  j;
 58              }
 59 
 60               for  ( int  m  =   0 ; m  <  ENV.GENE_LENGTH; m ++ ) {
 61                   if  (seqChange.contains(m)) {
 62                       continue ;
 63                  }
 64                  Integer genes1Change  =  seqMap.getKeyByValue(genes1[m]);
 65                  Integer genes2Change  =  seqMap.getValueByKey(genes2[m]);
 66                   if  (genes1Change  !=   null ) {
 67                      genes1[m]  =  genes1Change.intValue();
 68                  }
 69                   if  (genes2Change  !=   null ) {
 70                      genes2[m]  =  genes2Change.intValue();
 71                  }
 72              }
 73 
 74          }
 75          children[ 0 =   new  Individal();
 76          children[ 1 =   new  Individal();
 77          children[ 0 ].setGenes(genes1);
 78          children[ 1 ].setGenes(genes2);
 79           return  children;
 80      }
 81 
 82       public   void  dissociation() {
 83           //  change own gene sequence by dissociation percente.
 84           for  ( int  i  =   1 ; i  <  genes.length; i ++ ) {
 85               //  boolean ifChange = ENV.doOrNot(ENV.DISSOCIATION_RATE * (ENV.GENE_LENGTH - 1));
 86               boolean  ifChange  =  ENV.doOrNot(ENV.DISSOCIATION_RATE);
 87               if  (ifChange) {
 88                   //  long start = ENV.getRandomInt(1, ENV.GENE_LENGTH - 1);
 89                   long  start  =  i;
 90                   long  goStep  =  ENV.getRandomInt( 1 , ENV.GENE_LENGTH  -   2 );
 91                   long  changePos  =  start  +  goStep;
 92                   if  (changePos  >=  ENV.GENE_LENGTH) {
 93                      changePos  =  changePos  -  ENV.GENE_LENGTH  +   1 ;
 94                  }
 95                   int  temp  =  genes[( int ) start];
 96                  genes[( int ) start]  =  genes[( int ) changePos];
 97                  genes[( int ) changePos]  =  temp;
 98              }
 99 
100          }
101      }
102 
103       public   void  print() {
104           for  ( int  i  =   0 ; i  <  genes.length; i ++ ) {
105              System.out.print(genes[i]  +   " ; " );
106          }
107          System.out.print( " -- "   +   this .getAdaptability());
108          System.out.println();
109      }
110 
111       public   double  getAdaptability() {
112           int  seq[]  =   this .getGenes();
113           double  totalLength  =   0 ;
114           for  ( int  i  =   0 ; i  <  seq.length  -   1 ; i ++ ) {
115               double  length  =  Math.hypot(ENV.CITIES_LIST[seq[i]][ 0 -  ENV.CITIES_LIST[seq[i  +   1 ]][ 0 ],
116                      ENV.CITIES_LIST[seq[i]][ 1 -  ENV.CITIES_LIST[seq[i  +   1 ]][ 1 ]);
117              totalLength  +=  length;
118          }
119           return  totalLength;
120      }
121 
122       public   static  Individal getRandomIndividal() {
123          Individal individal  =   new  Individal();
124           int [] geneSeq  =  individal.getGenes();
125          List geneList  =  ENV.getGeneLinkList();
126           int  tempLength  =  geneList.size();
127           for  ( int  i  =   1 ; i  <=  tempLength; i ++ ) {
128               long  random  =  ENV.getRandomInt( 0 , ENV.GENE_LENGTH  *   5 );
129               int  seq  =  ( int ) random  %  geneList.size();
130              geneSeq[i]  =  (Integer) geneList.get(seq);
131              geneList.remove(seq);
132          }
133           return  individal;
134      }
135 
136  }
137 
Population.java 群体类
  1  package  geneAlgo;
  2 
  3  import  java.util.ArrayList;
  4  import  java.util.List;
  5 
  6  public   class  Population {
  7 
  8       private   long  eras  =   0 ;
  9 
 10       private   double  historyBest  =  ENV.ADAPT_GOAL  +   50 ;
 11 
 12       private  List < Individal >  individals  =   new  ArrayList < Individal > ();
 13 
 14       public  List < Individal >  getIndividals() {
 15           return  individals;
 16      }
 17 
 18       public   void  setIndividals(List < Individal >  individals) {
 19           this .individals  =  individals;
 20      }
 21 
 22       public   boolean  addIndividal(Individal individal) {
 23           boolean  result  =   true ;
 24           if  ( this .individals.size()  >=  ENV.GROUP_SIZE) {
 25              result  =   false ;
 26          }  else  {
 27               this .individals.add(individal);
 28          }
 29           return  result;
 30      }
 31 
 32       public   void  print() {
 33           for  ( int  i  =   0 ; i  <  individals.size(); i ++ ) {
 34              individals.get(i).print();
 35          }
 36      }
 37 
 38       public   static  Population getOriginalPopulation() {
 39          Population original  =   new  Population();
 40          Individal a  =  Individal.getRandomIndividal();
 41          Individal b  =  Individal.getRandomIndividal();
 42           while  (original.addIndividal(a.getAdaptability()  <  b.getAdaptability()  ?  a : b)) {
 43              a  =  Individal.getRandomIndividal();
 44              b  =  Individal.getRandomIndividal();
 45          }
 46           return  original;
 47      }
 48 
 49       public   void  evolute() {
 50          Population evoPool  =   new  Population();
 51           //  make evolution pool
 52           while  (evoPool.individals.size()  <  ENV.GROUP_SIZE) {
 53               int  indi1  =  ( int ) ENV.getRandomInt( 0 , ENV.GROUP_SIZE  -   1 );
 54               int  indi2  =  ( int ) ENV.getRandomInt( 0 , ENV.GROUP_SIZE  -   1 );
 55               while  (indi2  ==  indi1) {
 56                  indi2  =  ( int ) ENV.getRandomInt( 0 , ENV.GROUP_SIZE  -   1 );
 57              }
 58               if  ( this .individals.get(indi1).getAdaptability()  ==   this .individals.get(indi2).getAdaptability()) {
 59                   if  (ENV.KEEP_BAD_INDIVIDAL  <=  ENV.KEEP_BAD_INDIVIDAL_MAX) {
 60                      ENV.KEEP_BAD_INDIVIDAL  +=   0.0004 ;
 61                  }
 62              }  else  {
 63                   if  (ENV.KEEP_BAD_INDIVIDAL  >=  ENV.KEEP_BAD_INDIVIDAL_MIN)
 64                      ENV.KEEP_BAD_INDIVIDAL  -=   0.00005 ;
 65              }
 66               boolean  ifKeepBad  =  ENV.doOrNot(ENV.KEEP_BAD_INDIVIDAL);
 67               if  (ifKeepBad) {
 68                  evoPool.addIndividal( this .individals.get(indi1).getAdaptability()  >   this .individals.get(indi2)
 69                          .getAdaptability()  ?   this .individals.get(indi1) :  this .individals.get(indi2));
 70              }  else  {
 71                  evoPool.addIndividal( this .individals.get(indi1).getAdaptability()  <=   this .individals.get(indi2)
 72                          .getAdaptability()  ?   this .individals.get(indi1) :  this .individals.get(indi2));
 73              }
 74               //  if (this.individals.get(indi1).getAdaptability() <= this.individals.get(indi2).getAdaptability()) {
 75               //  evoPool.addIndividal(individals.get(indi1));
 76               //  } else {
 77               //  evoPool.addIndividal(individals.get(indi2));
 78               //  }
 79          }
 80          Population newPopulation  =   new  Population();
 81           for  ( int  i  =   0 ; i  <  ENV.GROUP_SIZE  -   1 ; i  =  i  +   2 ) {
 82              Individal children[]  =  evoPool.getIndividals().get(i).makeBabyWith(evoPool.getIndividals().get(i  +   1 ));
 83              children[ 0 ].dissociation();
 84              children[ 1 ].dissociation();
 85              newPopulation.addIndividal(children[ 0 ]);
 86              newPopulation.addIndividal(children[ 1 ]);
 87          }
 88           this .setIndividals(newPopulation.getIndividals());
 89           this .eras ++ ;
 90      }
 91 
 92       public   long  getEras() {
 93           return  eras;
 94      }
 95 
 96       public   void  setEras( long  eras) {
 97           this .eras  =  eras;
 98      }
 99 
100       public   void  printBest() {
101          Individal x  =  getBestAdapt();
102          x.print();
103          System.out.print( " eras: "   +   this .getEras());
104          System.out.print( "  historyBest: "   +   this .historyBest);
105          System.out.print( "  keep bad rate: "   +  ENV.KEEP_BAD_INDIVIDAL);
106          System.out.println();
107      }
108 
109       public  Individal getBestAdapt() {
110          Individal x  =   null ;
111           for  ( int  i  =   0 ; i  <  ENV.GROUP_SIZE; i ++ ) {
112               if  (x  ==   null ) {
113                  x  =   this .getIndividals().get(i);
114              }  else  {
115                   if  ( this .getIndividals().get(i).getAdaptability()  <  x.getAdaptability()) {
116                      x  =   this .getIndividals().get(i);
117                  }
118              }
119          }
120           if  (x.getAdaptability()  <   this .historyBest) {
121               this .historyBest  =  x.getAdaptability();
122          }
123           return  x;
124      }
125  }
126 


你可能感兴趣的:(用遗传算法实现旅行商问题的Java实现)