遗传算法解决N皇后问题

写代码这个事儿,果然不能懈怠,好久不定代码,都生疏了,搞了一天才搞出来。

最主要的问题是卡是杂交算法那块儿了,由于把杂交结果作为函数的返回值,而杂交结果是函数的局部变量,是一个指针,因此当函数执行结束,该指针也被释放掉,当然也就找不到杂交结果啦。

有两个方法可以解决:第一:将其作为函数的一个形参

          第二:将其作为静态变量

下面使用两种杂交算法实现N皇后问题。

  1 // 8queens.cpp : 定义控制台应用程序的入口点。
  2 //
  3 /**/
  4 
  5 #include<iostream>
  6 #include<string.h>
  7 #include<time.h>
  8 #include<map>
  9 #include<string>
 10 using namespace std;
 11 
 12 #define GENERATION_LIMIT 10000
 13 #define OFFSPRING  50
 14 #define QUEENNUM  11
 15 #define MAX_FITNESS 100
 16 char fa[QUEENNUM],mo[QUEENNUM];
 17 //我自己写的杂交算法,随机生成一个随机数mutation,如果是偶数那么将father的前mutation
 18 //个值按顺序赋值给son,将mother的不在son中的元素按序赋值给son
 19 //如果mutation是奇数,那么则将mother的前mutation个值按序赋值给Son
 20 char *CrossOver1(char *father,char *mother)
 21 {
 22     int i,j,k;  
 23     static char static_son[QUEENNUM]={'\0'};//在这里使用静态变量
 24     int num=0;
 25     bool flag[QUEENNUM];
 26     memset(flag,0,sizeof(flag));
 27 
 28     char temp[QUEENNUM]={'\0'};
 29     int mutation=rand()%(QUEENNUM-1);
 30     if(mutation%2==0)
 31     {
 32         for(i=0;i<mutation;++i)
 33         {
 34             temp[num++]=father[i];
 35             flag[father[i]-'0']=true;
 36         }
 37         for(i=0;(i<QUEENNUM-1)&&(num<QUEENNUM-1);++i)
 38         {
 39             if(flag[mother[i]-'0']==false)
 40             {
 41                 temp[num++]=mother[i];
 42                 flag[mother[i]-'0']=true;
 43             }
 44         }
 45     }
 46     else
 47     {
 48         for(i=0;i<mutation;++i)
 49         {
 50             temp[num++]=mother[i];
 51             flag[mother[i]-'0']=true;
 52         }
 53         for(i=0;(i<QUEENNUM-1)&&(num<QUEENNUM-1);++i)
 54         {
 55             if(flag[father[i]-'0']==false)
 56             {
 57                 temp[num++]=father[i];
 58                 flag[father[i]-'0']=true;
 59             }
 60         }
 61     }
 62     strcpy(static_son,temp);
 63     return static_son;
 64 }
 65 //这个算法是从网上找到的算法
 66 char *CrossOver(char* father,char* mother)//交叉函数,返回值为交叉后的子代,具体原理不在这里阐述,在设计文档中有详细说明  
 67 {  
 68     int i,j,k;  
 69     static char static_son[QUEENNUM]={'\0'};
 70     char rnd[QUEENNUM],fath[QUEENNUM],moth[QUEENNUM];
 71     int num=0;
 72     bool flag[QUEENNUM];
 73     memset(flag,0,sizeof(flag));
 74     char temp[QUEENNUM]={'\0'};
 75     int mutation=rand()%(QUEENNUM-1);
 76     strcpy(moth,mother);
 77     strcpy(fath,father);
 78     for ( i = 0; i < QUEENNUM-1; i ++)//根据交叉算子对父母进行交叉  
 79     {  
 80         if (rnd[i] == '1')  
 81         {  
 82             for ( j = 0; j < QUEENNUM-1; j++)  
 83             {  
 84                 if (flag[fath[j]-'0'] ==false)  
 85                 {  
 86                     break;  
 87                 }  
 88             }  
 89             static_son[i]=fath[j];  
 90             flag[fath[j]-'0']=true;
 91         }  
 92         else 
 93         {  
 94             for ( j = 0; j < QUEENNUM-1; j++)  
 95             {  
 96                 if (flag[moth[j]-'0'] ==false)  
 97                 {  
 98                     break;  
 99                 }  
100             }  
101             static_son[i]=moth[j];  
102             flag[moth[j]-'0']=true; 
103         }  
104     }  
105     return static_son;
106     
107 }  
108 unsigned int check(char queen[])
109 {
110     int illegal_num=0;
111     for(int i=0;i<QUEENNUM-1;++i)
112     {
113         for(int j=i+1;j<QUEENNUM-1;++j)
114         {
115             if(abs(queen[i]-queen[j])==abs(j-i))
116                 ++illegal_num;
117         }
118     }
119     return illegal_num;
120 }
121 
122 
123 void initqueen(char queen[])
124 {
125     bool flag[QUEENNUM-1];
126     memset(flag,0,sizeof(flag));
127 //    memset(queen,0,sizeof(queen));
128     int place;
129     for(int i=0;i<QUEENNUM-1;++i)
130     {
131         while(true)
132         {
133             place=rand()%(QUEENNUM-1);
134             if(flag[place]==0)
135             {
136                 queen[i]=place+'0';
137                 flag[place]=1;
138                 break;
139             }
140         }
141 
142     }
143     queen[QUEENNUM-1]='\0';
144 }
145 
146 int main()
147 {
148     char son[2][QUEENNUM],temp[QUEENNUM];
149     int max_fitness,min_fitness,fitness;
150     char final_queen[QUEENNUM]={'\0'};
151     int queen_num=0;
152     map<string,string> mapqueen;
153     //map<char*,int> mapchar;
154     memset(fa,0,sizeof(fa));
155     memset(mo,0,sizeof(mo));    
156     srand((unsigned)time(NULL));
157     initqueen(fa);    
158     initqueen(mo);
159     while(strcmp(fa,mo)==0)
160     {
161         initqueen(mo);
162     }
163     if(check(fa)>check(mo))//fa【】的fitness值小于mo[]的fitness值
164     {
165         strcpy(temp,fa);
166         strcpy(fa,mo);
167         strcpy(mo,temp);
168     }
169 
170     // iteration
171     //每一轮找出fitness值最小的两个孩子作为父亲进行下一轮的杂交
172     for(int i=0;i<GENERATION_LIMIT;++i)
173     {
174         
175         max_fitness=1000;
176         min_fitness=1000;
177         for(int j=0;j<OFFSPRING;++j)
178         {
179             strcpy(temp,CrossOver(fa,mo));
180             temp[QUEENNUM-1]='\0';
181             //变异
182             int mutation1=rand()%(QUEENNUM-1);
183             int mutation2=rand()%(QUEENNUM-1);
184             int temp_mut;
185             temp_mut=temp[mutation1];
186             temp[mutation1]=temp[mutation2];
187             temp[mutation2]=temp_mut;
188             
189             fitness=check(temp);
190             if(min_fitness>fitness)
191             {
192                 if(max_fitness!=1000)
193                 {
194                     strcpy(son[1],son[0]);
195                     max_fitness=min_fitness;
196                 }
197                 strcpy(son[0],temp);
198                 min_fitness=fitness;
199             }
200             else if(max_fitness>fitness&&(strcmp(temp,son[0])!=0))
201             {
202                 max_fitness=fitness;
203                 strcpy(son[1],temp);
204             }
205 
206             if(0==fitness)
207             {
208                 strcpy(final_queen,temp);
209                 final_queen[QUEENNUM-1]='\0';
210                 mapqueen.insert(pair<string,string>(final_queen,final_queen));
211             }
212         
213         }
214         //将最优的孩子赋值给父母
215         strcpy(fa,son[0]);
216         strcpy(mo,son[1]);
217         
218     }
219     
220     map<string,string> ::iterator iter;
221     for(iter=mapqueen.begin();iter!=mapqueen.end();++iter)
222     {
223         cout<<iter->first<<endl;
224     }
225     cout<<mapqueen.size()<<endl;
226     
227     return 0;
228 }
View Code

 

posted @ 2014-03-01 19:01  dupuleng  阅读(492)  评论(0)    收藏  举报