📄 遗传算法图案dlg.cpp
字号:
}
}
void CMyDlg::read()
{
seed=m_seed.GetPos();
colony=m_colony.GetPos();
times=m_times.GetPos();
acrossn=m_acrossn.GetPos();
cloner=m_cloner.GetPos();
variancer=m_variancer.GetPos();
cvp=m_cvp.GetPos();
hxfg=m_hxfg.GetPos();
zxfg=m_zxfg.GetPos();
sbcc=m_sbcc.GetPos();
mpbj=m_mpbj.GetPos();
sclc=m_sclc.GetPos()/10.;
qfks=m_qfks.GetPos();
xpnks=m_xpnks.GetPos();
}
void initrgbmat()//初始化rgb矩阵
{
int i,j,x,y;
for(x=0;x<MX;x++)
for(y=0;y<MY;y++)
for(i=0;i<3;i++)
newmat[x][y][i]=0;
for(i=0;i<colony;i++)
{
do
{
x=rand()%MX;
y=rand()%MY;
}
while(newmat[x][y][0]);
for(j=0;j<3;j++)
newmat[x][y][j]=(unsigned char)(1+rand()%254);/////舍弃0,0,0
}
}
int empty(int x,int y)
{
int m,n,k=0;
for(m=-1;m<2;m++)
for(n=-1;n<2;n++)
{
if(!newmat[x+m][y+n][0])
k++;
}
return(k);
}
int aver1(int x,int y, int i)
{
int m,n,u,v,k=0,p;
long c=0L;
for(m=-1;m<2;m++)
for(n=-1;n<2;n++)
{
u=x+m;v=y+n;
p=(int)(newmat[u][v][i]);
if(p)
{ c+=p;k++;}
}
if(k==0) return(1);
else return((int)(c/k));
}
int abs(int k)
{
if(k>=0)
return(k);
else
return(-k);
}
int fitness(int x,int y)
{
int m,s=0;
for(m=0;m<3;m++)
s+=abs((int)(newmat[x][y][m])-aver1(x,y,m));
return(s);
}
void CMyDlg::clone_or_variance()//克隆或变异
{
int i,j,t;
int p_clone,p_variance;//
for(i=1;i<MX-1;i++)
for(j=1;j<MY-1;j++)
if(newmat[i][j][0]&&(rand()%10<cvp))//若为实点,即个体点
{
t=empty(i,j);
p_clone=cloner*t*96;//empty()为周围的空白点数
p_variance=variancer*fitness(i,j);//fitness()为适应度
//4*96=3*128 4为空白点数的中间数,128为色度差的中间数
if(p_clone+p_variance<=0) continue;
if(rand()%(p_clone+p_variance)<p_clone)//克隆
go_clone(i,j,t);
else
go_variance(i,j);
}
}
void CMyDlg::select_across()//选择交叉
{
long i;
unsigned int x,y;
int a,b,c,d;
double r;
CClientDC p(this);
for(i=0L;i<4L*acrossn;i++)
across_point[i]=-1;
for(i=0L;i<2*acrossn;i++)//确定acrossn对交叉点
{ do
{ x=rand()%MX;y=rand()%MY;
}
while(!newmat[x][y][0]);//非个体或已使用
across_point[2*i]=x; across_point[2*i+1]=y;
}
////记录到rgbmat中
for(i=0L;i<acrossn;i++)
{ r=rand()%100/100.+0.01;
a=across_point[4*i];b=across_point[4*i+2];
c=across_point[4*i+1];d=across_point[4*i+3];
x=r*a+(1-r)*b;
y=r*c+(1-r)*d;
if(weight[x][y]<250)
weight[x][y]+=5;////////////////
else weight[x][y]=1;
}
}
void CMyDlg::go_clone(int x, int y,int t)
{
int u,v,m,n,l=0;
int c,i;
char f=0,p;
double a=(rand()%70/100.+0.1);
int dir[3];
CClientDC q(this);
t=rand()%t+1;
for(m=-1;m<2;m++)
{
for(n=-1;n<2;n++)
{
u=x+m;v=y+n;
if(!newmat[u][v][0])
l++;
if(l==t) {f=1;break;}
}
if(f) break;
}
p=variance_dir[x][y];
if(p<8)
{ dir[0]=255*(p/4);dir[1]=255*(p%4/2);dir[2]=255*(p%2);
}
else
{ dir[0]=aver1(x,y,0);dir[1]=aver1(x,y,1);dir[2]=aver1(x,y,2);
}
for(i=0;i<3;i++)
{
c=newmat[x][y][i];
newmat[u][v][i]=(unsigned char)(c+a*(dir[i]-c));
if(!newmat[u][v][i]) newmat[u][v][i]=1;
}
q.SetPixelV(XX+u,YY+v,65536*newmat[u][v][0]+256*newmat[u][v][1]
+newmat[u][v][2]);
}
void CMyDlg::go_variance(int x, int y)
{
int i,c;
double a;
int dir[3];
char p;
CClientDC q(this);
a=(rand()%70/100.+0.1);
p=variance_dir[x][y];
if(p<8)
{ dir[0]=255*(p/4);dir[1]=255*(p%4/2);dir[2]=255*(p%2);
}
else
{ dir[0]=aver1(x,y,0);dir[1]=aver1(x,y,1);dir[2]=aver1(x,y,2);
}
for(i=0;i<3;i++)
{ c=newmat[x][y][i];
newmat[x][y][i]=(unsigned char)(c+a*(dir[i]-c))+1;
}
q.SetPixelV(XX+x,YY+y,65536*newmat[x][y][0]+256*newmat[x][y][1]
+newmat[x][y][2]);
}
void CMyDlg::myclear()
{
int m,n;
CClientDC p(this);
for(m=0;m<MX;m++)
for(n=0;n<MY;n++)
p.SetPixelV(XX+m,YY+n,65536*newmat[m][n][0]+256*newmat[m][n][1]
+newmat[m][n][2]);
}
void CMyDlg::OnDeltaposcolony(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
int t;
t=m_colony.GetPos();
m_acrossn.SetRange(t/3,2*t/3);
m_acrossn.SetPos(t/2);
*pResult = 0;
}
void twist();//扭曲
void sb();
int mymin(int m,int n)
{ if(m>n) m=n;
return(m);
}
int mymax(int m,int n)
{ if(m<n) m=n;
return(m);
}
void initdir()
{
int i,j,h,z,u,v;
char c,d;
h=MX/hxfg;
z=MY/zxfg;
for(i=0;i<hxfg;i++)
for(j=0;j<zxfg;j++)
{
c=rand()%DIR;
if(c==0||c==1) c=0;
else if(c==2||c==3) c=7;
else if((c>=4)&&(c<=9)) c-=3;
else c=8;
for(u=i*h;u<mymin((i+1)*h,MX-1);u++)
for(v=j*z;v<mymin((j+1)*z,MY-1);v++)
variance_dir[u][v]=c;
}
for(i=0;i<MX;i++)
{
if(i%h==0)
{
c=rand()%DIR;d=rand()%DIR;if(c>=8) c=8;if(d>=8) d=8;
}
variance_dir[i][0]=c;
variance_dir[i][MY-1]=d;
}
for(j=0;j<MY;j++)
{
if(j%z==0)
{
c=rand()%DIR;d=rand()%DIR;if(c>=8) c=8;if(d>=8) d=8;
}
variance_dir[0][j]=c;
variance_dir[MX-1][j]=d;
}
sb();//渗变
twist();//扭曲
}
bool diff(int x,int y)
{
int m,n,k,u,v;
k=variance_dir[x][y];
for(m=-1;m<2;m++)
for(n=-1;n<2;n++)
{
u=m+x;v=n+y;
if(u<0||u>MX-1||v<0||v>MY-1) continue;
if(variance_dir[u][v]!=k)
return(1);
}
return(0);
}
void dsb1()//一代渗变
{
int i,j,u,v;
char a,b,c;
for(i=0;i<MX;i++)
for(j=0;j<MY;j++)
if(diff(i,j))
{
a=rand()%9;
b=a%3-1;c=a/3-1;
u=i+b;v=j+c;
if(u<0||u>MX-1||v<0||v>MY-1) continue;
else
variance_dir[i][j]=variance_dir[u][v];
}
}
void dsb2()//一代渗变
{
int i,j,u,v,k;
char m,n;
int s[9];
for(i=1;i<MX-1;i++)
for(j=1;j<MY-1;j++)
{
for(m=-1;m<2;m++)
for(n=-1;n<2;n++)
{
u=i+m;v=j+n;
s[(n+1)*3+(m+1)]=weight[u][v];
}
for(m=1;m<9;m++)
s[m]+=s[m-1];//求权和
if(s[8]==0) continue;
k=rand()%s[8];
for(m=0;m<9;m++)
if(k<s[m]) break;
u=i+m%3-1;
v=j+m/3-1;
variance_dir[i][j]=variance_dir[u][v];
if(weight[u][v]<255) weight[u][v]++;
else weight[u][v]=1;
}
}
void sb()
{
int n;
for(n=0;n<sbcc;n++)
dsb1();
}
void twist()//扭曲
{
int i,j,f;
f=20+rand()%AA;
for(i=0;i<MX;i++)
{
f+=(rand()%3-1);
for(j=0;j<MY;j++)
variance_dir[i][j]=variance_dir[i][(MY+j+f)%MY];
}
f=20+rand()%AA;
for(j=0;j<MY;j++)
{
f+=(rand()%3-1);
for(i=0;i<MX;i++)
variance_dir[i][j]=variance_dir[(MX+i+f)%MX][j];
}
}
int mmax(int u,int v)
{
if(u>v) return(u);else return(v);
}
void initmpmb()
{
int m,n;
mpmbh=0;
for(m=0;m<2*mpbj+1;m++)
for(n=0;n<2*mpbj+1;n++)
{
mpmb[m*(2*mpbj+1)+n]=mpbj+1-mmax(abs(m-mpbj),abs(n-mpbj));
mpmbh+=mpmb[m*(2*mpbj+1)+n];
}
}
void CMyDlg::Onmp() //磨平
{
// TODO: Add your control notification handler code here
m_save.EnableWindow(FALSE);
m_clc.EnableWindow(FALSE);
m_qf.EnableWindow(FALSE);
m_xpn.EnableWindow(FALSE);
mpbj=m_mpbj.GetPos();
mpmb.SetSize((2*mpbj+1)*(2*mpbj+1));
initmpmb();//初始化磨平模板
move_point();//移动指针
clrnewp();
int i,j,c,u,v,m,n;
long s=0L;
for(i=0;i<MX;i++)
for(j=0;j<MY;j++)
{
for(c=0;c<3;c++)
{
s=0L;
for(u=-mpbj;u<=mpbj;u++)
for(v=-mpbj;v<=mpbj;v++)
{
m=i+u;n=j+v;
if(m<0) m=0;else if(m>MX-1) m=MX-1;
if(n<0) n=0;else if(n>MY-1) n=MY-1;
s+=((long)oldp[3*(m*MY+n)+c]*mpmb[(u+mpbj)*(2*mpbj+1)+v+mpbj]);
}
newp[3*(i*MY+j)+c]=s/mpmbh;
}
m_jdt.SetPos((i*MY+j)*100./(MX*MY)+0.5);
}
draw_newp();
m_save.EnableWindow(TRUE);
m_clc.EnableWindow(TRUE);
m_qf.EnableWindow(TRUE);
m_xpn.EnableWindow(TRUE);
m_left.EnableWindow(TRUE);
m_right.EnableWindow(FALSE);
count=1-count;//磨平,磁力场,起伏,橡皮泥四种操作的计数
}
void initpart()
{
int k;
for(k=0;k<clcs;k++)
{
particle[3*k]=rand()%MX;
particle[3*k+1]=rand()%MY;
particle[3*k+2]=rand()%255;
}
}
int g_to_c(long g,long max)//从磁力影响到颜色
{
int c;
c=g/(ZDZS+1-(int)(10*sclc))%256;//////////////////////
return(c);
}
int jl(int m,int n,int x,int y)//距离
{
int d;
d=sqrt((m-x)*(m-x)+(n-y)*(n-y));
return(d);
}
double sum(int d,double k)//d-1~d中的k次的积分
{
double t=k+1;
double a,b;
a=pow(d,t);
if(d==1) b=0;
else
b=pow(d-1,t);
return((a-b)/t);
}
void CMyDlg::Onclc() //磁力场
{
// TODO: Add your control notification handler code here
m_mp.EnableWindow(FALSE);
m_save.EnableWindow(FALSE);
m_qf.EnableWindow(FALSE);
m_xpn.EnableWindow(FALSE);
move_point();//移动指针
sclc=m_sclc.GetPos()/10.;
clcs=m_sclcs.GetPos();
particle.SetSize(3*clcs);
initpart();//初始化质点矩阵
long cs=((long)MX*MX+(long)MY*MY)/80;
long s=0L,max=0L;
int i,j,m,d;double rr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -