📄 genetestview.cpp
字号:
return;
}
}
//给最优染色体分配空间
if((m_maxfitChrom = (char*) malloc(nbytes)) == NULL)
{
MessageBox("内存分配失败!");
return;
}
}
//计算个体适应度函数
void CGenetestView::Objfunc(CIndividual *obj)
{
float Sum,mul;
Sum = 0.0;
//mul = 1.0;
POSITION pos;
for(int i=0;i<m_ntarget;i++)
{
mul = 1.0;
pos = m_WeaponList.GetHeadPosition();
for(int j=0;j<m_nweapon;j++)
{
int FBBH = m_WeaponList.GetAt(pos)->m_nFBMBH;
if(FBBH==i)
{
mul = mul*(1-m_SuccessArray[i][j]);//计算失败的概率
}
m_WeaponList.GetNext(pos);
}
mul = 1-mul;//得到成功的概率
Sum = Sum+m_Worthiness[i]*mul; //得到对目标打击成功的概率和
}
obj->fitness = Sum;//赋值给适应度变量
}
//设置武器目标打击概率数并输出到文件,便于观察
void CGenetestView::SetWTAArray()
{
float m,n,n1;
CString str,str1,str2,str3;;
float Sum = 0;
str = "";
for(int i=0;i<m_ntarget;i++)
{
//m = (float)(i+3);
m = float(rand()%10);//改为随机生成目标价值,实际上应从数据库读出
if (m < 1)
{
m = 1.0;
}
m_Worthiness[i] = m;
//用于输出目标价值
Sum += m;
str1.Format("%f ",m);
str += str1;
str2 = "";
for(int j=0;j<m_nweapon;j++)
{
//n = (float)((j+4-i)*0.1);
n1 = float(rand()%10);
if(n1 < 1)//对应于产生的随机数求余为0的情况
{
n1 = 1.0;
}
n = n1/10;//产生0~1之间的随机数,模拟成功概率,实际上应是读库操作
m_SuccessArray[i][j] = n;
str3.Format("%f ",n);
str2 += str3;
m_PheromoneArray[i][j] = float(6);//信息素初始值,设为固定值
}
WriteLog(str2);
}
str1.Format("总价值为:%f",Sum);
str += str1;
WriteLog(str);
}
//代操作函数
void CGenetestView::Generation(int gen)
{
int j,mate1,mate2;
j = 0;
CString str;
int lchrom = m_ntarget*m_nweapon;
str.Format("第 %d 代:",gen);
CClientDC pDC(this);
pDC.TextOut(0,m_nOutputY,str);
m_nOutputY += 30;
ReleaseDC(&pDC);
WriteLog(str);//书写遗传算法日志
Copy();
while(j<m_npopulationsize)
{
//选择用于交叉的个体的索引
mate1 = select();
mate2 = select();
Crossover(m_oldpop[mate1].chrom,m_oldpop[mate2].chrom,j);
//给新的个体j赋值
m_newpop[j].parent1 = mate1;
m_newpop[j].parent2 = mate2;
m_newpop[j].xsite = m_jcross;
//输出个体,并计算适应度计算函数
JudgeChrom(&m_newpop[j]);
OutputResult(m_newpop[j]);
ObjFunction(&m_newpop[j]);
//给新的个体j+1赋值
m_newpop[j+1].parent1 = mate1;
m_newpop[j+1].parent2 = mate2;
m_newpop[j+1].xsite = m_jcross;
JudgeChrom(&m_newpop[j+1]);
OutputResult(m_newpop[j+1]);
ObjFunction(&m_newpop[j+1]);
j += 2;
}
}
//贝怒利实验
int CGenetestView::flip(float probability)
{
float ppp;
int r = rand();
//str.Format("%d",r);
//length = str.GetLength();
//ppp = ((float)r)/(float)(pow(10,length));//rand()函数所能产生的最大的数就是0x7fff,也就是32767
ppp = (r%1000)/(float)1000;//这样产生随机数比较好一些。这样产生的随机数最小的为0,最大的为0.99
if(ppp <= probability) return 1;
return 0;
}
//选择操作,选出父个体用于产生新的个体
int CGenetestView::select()
{
float rand1,partsum;
int j = 0;
partsum = 0.0;
rand1 = m_fsumfitness*((float)rand())/32767;
do{
partsum += m_oldpop[j].fitness;
j++;
}while((partsum<rand1)&&(j<m_npopulationsize));
return j-1;
}
//交叉操作函数
int CGenetestView::Crossover(char *parent1, char *parent2, int k)
{
int j;
int lchrom = m_ntarget*m_nweapon;
if(flip(m_fcrossover))
{
m_jcross = rand()*(lchrom-1)/32767;
m_ncross += 1;
}
else m_jcross = lchrom;
if(m_jcross != lchrom)
{
for(j=0;j<m_jcross;j++)
{
m_newpop[k].chrom[j] = mutation(parent1[j]);
m_newpop[k+1].chrom[j] = mutation(parent2[j]);
}
for(j = m_jcross;j<lchrom;j++)
{
m_newpop[k].chrom[j] = mutation(parent2[j]);
m_newpop[k+1].chrom[j] = mutation(parent1[j]);
}
}
else
{
for(j=0;j<lchrom;j++)
{
m_newpop[k].chrom[j] = mutation(parent1[j]);
m_newpop[k+1].chrom[j] = mutation(parent2[j]);
}
}
return 1;
}
//变异操作函数
//int CGenetestView::mutation(unsigned char ch)
char CGenetestView::mutation(char ch)
{
int mutate;
mutate = flip(m_fmutation);
if(mutate)
{
m_nmutation += 1;
if(ch) ch = 0;
else ch = 1;
}
if(ch) return 1;
else return 0;
}
//输出得到的染色体到屏幕
void CGenetestView::OutputResult(CIndividual individual)
{
//从个体中得到染色体字符串
CString str,str1;
int m = individual.chrom[0];
int lchrom = m_ntarget*m_nweapon;
str.Format("%d",m);
for(int l=1;l<lchrom;l++)
{
m = individual.chrom[l];
str1.Format("%d",m);
str += str1;
}
//输出字符串
CClientDC dc(this);
dc.TextOut(0,m_nOutputY,str);
ReleaseDC(&dc);
WriteLog(str);
//m_nIndex++;
//m_OutstrArray.SetAt(m_nIndex,str);
}
//新的个体适应度计算函数
void CGenetestView::ObjFunction(CIndividual *individual)
{
float Sum,mul;
Sum = 0.0;
for(int i=0;i<m_ntarget;i++)
{
mul = 1.0;
//pos = m_WeaponList.GetHeadPosition();
for(int j=0;j<m_nweapon;j++)
{
char FBBZ = individual->chrom[i*m_nweapon+j];
if(FBBZ==1)
{
mul = mul*(1-m_SuccessArray[i][j]);//计算失败的概率
}
}
mul = 1-mul;//得到成功的概率
Sum = Sum+m_Worthiness[i]*mul; //得到对目标打击成功的概率和
}
individual->fitness = Sum;//赋值给适应度变量
CString str;
str.Format("适应度:%f",Sum);
CClientDC dc(this);
dc.TextOut(m_ntarget*m_nweapon*15,m_nOutputY,str);
ReleaseDC(&dc);
m_nOutputY += 20;//跳转到下一行
WriteLog(str);
}
//复制操作,用最优个体代替最劣的个体
void CGenetestView::Copy()
{
int lchrom = m_ntarget*m_nweapon;
for(int i=0;i<lchrom;i++)
{
m_oldpop[m_nminpp].chrom[i] = m_oldpop[m_nmaxpp].chrom[i];
}
m_oldpop[m_nminpp].fitness = m_oldpop[m_nmaxpp].fitness;
}
//利用遗传算法的结果初始化信息素
void CGenetestView::InitPheromone()
{
//遗传算法传递过来的结果位于m_oldpop中
//在该函数中用的遗传算法的最优结果是最后一代中的最优结果,后来又定义了全局最优个体变量
//可以考虑用全局最优代替最后一代最优,传结果时,是传最优的一个呢,还是传m(蚂蚁数目)个呢
int i,j;
//CIndividual max = m_oldpop[m_nmaxpp];
//CIndividual *max = m_maxfitChrom;
for(i=0;i<m_ntarget;i++)
{
for(j=0;j<m_nweapon;j++)
{
//若某一武器被分配给了一目标则在此目标和武器之间的路径上信息素值增加0.2
if(m_maxfitChrom[i*m_nweapon+j]==1)
{
m_PheromoneArray[i][j] += float(0.2);
if(m_PheromoneArray[i][j]>10)
m_PheromoneArray[i][j] = float(9.99);
}//将迹的最大值设为10
}
}
}
void CGenetestView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
CSize size;
size.cx = 1024;
size.cy = 4000;
SetScrollSizes(MM_TEXT,size);
}
//日志函数,可用来将运行结果输出到文件
void CGenetestView::WriteLog(LPCTSTR pszFormat)
{
HANDLE hFile ;
DWORD dwByteWritten ;
_TCHAR buf[1024];
wsprintf(buf, "%s", "(%lu): ", GetCurrentThreadId());
va_list arglist;
va_start(arglist, pszFormat);
vsprintf(&buf[0/*lstrlen(buf)*/], pszFormat, arglist);
va_end(arglist);
char strPath[10000];
::GetCurrentDirectory(10000,strPath);
CString strPath1 = strPath;
strPath1 += "\\LogData\\gene.log";
hFile = CreateFile(strPath1,
GENERIC_WRITE,
FILE_SHARE_WRITE ,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE)NULL) ;
if (hFile == NULL)
return ;
DWORD dwSize = GetFileSize (hFile, NULL) ;
if(dwSize != 0xFFFFFFFF)
{
if( dwSize > 3000000)
{
SetFilePointer (hFile, 0, NULL, FILE_BEGIN) ;
SetEndOfFile (hFile) ;
}
}
SetFilePointer (hFile, 0, NULL, FILE_END) ;
CString szTm;
CTime cTm = CTime::GetCurrentTime() ;
szTm = cTm.Format ("%Y.%m.%d-%H:%M:%S ") ;
WriteFile(hFile, buf, _tcslen(buf)*sizeof(_TCHAR), &dwByteWritten, NULL) ;
WriteFile(hFile, _TEXT("\x0D\x0A"), 2*sizeof(_TCHAR), &dwByteWritten, NULL) ;
CloseHandle (hFile) ;
}
//判断交叉变异操作得到的个体是否符合限制条件,若符合返回TRUE
BOOL CGenetestView::JudgeChrom(CIndividual *individual)
{
//个体的染色体其实可以转化成一个m_ntarget行、m_nweapon列的矩阵
//通过判断同一列中1的个数是否大于1,来判断该个体是否符合要求
/*CString str,str1,strN,strN1;
int m = individual->chrom[0];
int lchrom = m_ntarget*m_nweapon;
str.Format("%d",m);
for(int l=1;l<lchrom;l++)
{
m = individual->chrom[l];
str1.Format("%d",m);
str += str1;
}
int leng = str.GetLength();*///调试用显示未调整前的染色体
for(int i=0;i<m_nweapon;i++)
{
char gene;
int num = 0;
//判断j列中1的个数是否大于1,若大于1,则返回错误值,
//因为1个武器不能同时分配给两个数组
float maxSuccessProp = 0.0;
int maxSuccessTarget = -1;
for(int j=0;j<m_ntarget;j++)
{
//得到武器i打击效果最好的目标的索引
if(m_SuccessArray[j][i] > maxSuccessProp)
{
maxSuccessProp = m_SuccessArray[j][i];
maxSuccessTarget = j;
}
//判断武器i是否分配给了目标j
gene = individual->chrom[j*m_nweapon+i];
if(gene==1)
num++;
}
if(num > 1)//不符合规定
{
//可以在此处添加修改不符合条件染色体的代码
//修改原则是将该武器分配给其打击概率最大的目标
for(j = 0;j < m_ntarget;j++)
{
if(j==maxSuccessTarget)
{
individual->chrom[j*m_nweapon+i] = 1;
}
else individual->chrom[j*m_nweapon+i] = 0;
}
//return FALSE;
}
}
/*m = individual->chrom[0];
strN.Format("%d",m);
for(l=1;l<lchrom;l++)
{
m = individual->chrom[l];
strN1.Format("%d",m);
strN += strN1;
}
int leng1 = strN.GetLength();*///调试用显示经调整后的染色体
return TRUE;
}
//输出运行结果
void CGenetestView::OnShowResult()
{
// TODO: Add your command handler code here
CString strout = "下面输出的是本次遗传算法执行所得到的优化结果:";
WriteLog(strout);
strout = "适应度:";
CString str;
str.Format("%f",m_fWholeMaxFit);
strout += str;
WriteLog(strout);
CString str1;
int m = m_maxfitChrom[0];
int lchrom = m_ntarget*m_nweapon;
str.Format("%d",m);
for(int l=1;l<lchrom;l++)
{
m = m_maxfitChrom[l];
str1.Format("%d",m);
str += str1;
}
WriteLog("最优个体的染色体为:");
WriteLog(str);
WriteLog("下面列出具体分配结果");
//分析最优染色体,显示分配结果
CString stroutput;
stroutput = "下面列出具体分配结果:";
for(int n=0;n<m_ntarget;n++)
{
str = "第";
str1 = "";
for(int w=n*m_nweapon;w<(n+1)*m_nweapon;w++)
{
if(m_maxfitChrom[w]==1)
{
str1.Format("%d号、",w%m_nweapon+1);
str += str1;
}
}
if(str1=="")
{
str.Format("没有武器分配到第%d号目标",n+1);
}
else
{
//一个汉字代表两个字符,去掉最后一个顿号、
str = str.Left(str.GetLength()-2);
str1.Format("武器分配给了第%d号目标",n+1);
str += str1;
}
WriteLog(str);
str += ";";
stroutput += str;
}
MessageBox(stroutput);
}
void CGenetestView::WritePheromone()
{
int i,j;
CString str,str1;
WriteLog("下面输出二分图各点之间的迹");
for(j = 0;j<m_nweapon;j++)
{
str.Format("第%d个武器",j+1);
WriteLog(str);
str = "";
for(i = 0;i<m_ntarget;i++)
{
str1.Format("%f ",m_PheromoneArray[i][j]);
str += str1;
}
WriteLog(str);
}
}
//非多线程测试,在主线程中运行蚂蚁算法
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -