使用遗传算法求解三元函数最大值
使用遗传算法求解三元函数z的最大值
z=f(x,y)=xsin(4πx)-ysin(4πy+π)+1
在-1<x<1和-1<y<1上的最大值
#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
//目标函数
double f(double x,double y){
return x*sin(4*pi*x)-y*sin(4*pi*y+pi)+1;
}
//编码转真实数字
double get_n(int a[40],int k){
double ans=0;
for(int i=k;i<k+15;i++){
ans=ans*2+a[i];
}
ans=(ans-16384)/16384;
return ans;
}
//随机数生成函数
int random(){
int r = rand() % 100 + 1;
return (r<=50)?0:1;
}
double random2(){
double r = (rand() % 100 + 1)*1.0/100;
return r;
}
int random3(){
double r = rand() % 30 ;
return r;
}
//个体
struct node{
int code[40];
double n_x;
double n_y;
double ans;
node(){
for(int i=0;i<30;i++){
code[i]=random();
}
n_x=get_n(code,0);
n_y=get_n(code,15);
ans=f(n_x,n_y);
}
void init(int a[40]){
for(int i=0;i<30;i++){
code[i]=a[i];
}
n_x=get_n(code,0);
n_y=get_n(code,15);
ans=f(n_x,n_y);
}
}n[55];
double get_f(node x){
return f(get_n(x.code,0),get_n(x.code,15));
}
//得到每个节点被随机抽取的范围
double p[55];
void set_p(){
double sum=0;
for(int i=0;i<50;i++){
sum+=n[i].ans;
}
p[0]=n[0].ans/sum;
for(int i=1;i<50;i++){
p[i]=p[i-1]+n[i].ans/sum;
}
}
//随机抽取父个体
int get_parent(){
double r = random2();
int parent=0;
for(int i=1;i<50;i++){
if(r>p[i-1]&&r<=p[i]){
parent=i;
break;
}
}
return parent;
}
//输出个体信息
void put_node(node x){
for(int i=0;i<30;i++)
printf("%d",x.code[i]);
printf("\n%lf\n",x.ans);
}
//初始群体
void initpop(){
for(int i=0;i<50;i++){
n[i]=node();
while(n[i].ans<0){
n[i]=node();
}
}
}
//变异
node get_vari(node x){
node temp=x;
double p_vari = random2();
int k=random3();
if(p_vari<=0.8){
temp.code[k]=(temp.code[k]+1)%2;
}
temp.init(temp.code);
return temp;
}
//交叉
node get_child(){
int parent1=get_parent();
int parent2=get_parent();
int k=random3();
int temp[40];
for(int i=0;i<=k;i++){
temp[i]=n[parent1].code[i];
}
for(int i=k+1;i<30;i++){
temp[i]=n[parent2].code[i];
}
node child;
child.init(temp);
child=get_vari(child);
if(child.ans<0)
child=get_child();
if(child.ans<n[parent1].ans)
child=n[parent1];
if(child.ans<n[parent2].ans)
child=n[parent2];
return child;
}
int main(){
srand((unsigned)time(NULL));
initpop();
node children[55];
double mmax=-1;
node anse;
double maxx=-1;
for(int i=0;i<20;i++){//生成20代
printf("----------第%d代----------\n",i+1);
set_p();
for(int i=0;i<50;i++){
children[i]=get_child();
if(children[i].ans>maxx){
maxx=children[i].ans;
anse=children[i];
}
}
for(int i=0;i<50;i++){
n[i]=children[i];
}
put_node(anse);
}
}