遗传算法解决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 }

浙公网安备 33010602011771号