📄 mainfrm.cpp
字号:
// MainFrm.cpp : implementation of the CMainFrame class
//
#include "stdafx.h"
#include "AntColony.h"
#include "SetParDialog.h"
#include "MainFrm.h"
/////////********////////////////////
#include "stdafx.h"
#include "operation.h"
#include "ANT.h"
#include "MAP.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
/////////********////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////////////////////////////////////////////////////////
///////////////////@@@@@@@@@数据采集程序段////////////////////////////////
struct DATA{
unsigned int path[AntNumber][StepLimit];
double Value[AntNumber];
} data[500];
/////////////////////////////////////////////////////////////////////////////
double BestValue=1000,Q=1000;//Q是信息素总量
int GenerLimit=50; //蚁群繁殖代数极限
unsigned int StartPoint=340,TarGetG=1300;
//unsigned int StartPoint=41,TarGetG=1558;
unsigned int BestTrail[StepLimit];//,BestAntGern=0;
MAP map;//生成并初始化地图对象和蚁群对象
ANT ant[AntNumber],ant2[AntNumber2];
SetParDialog SetPD;
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
void MapIn(void)
{ FILE *fp1;
int i,j;
fp1=fopen("map.dat", "r");
for(i=0;i<mapH;i++)
for(j=0;j<mapV;j++)
fscanf(fp1,"%5d",&map.point[i][j].PointType);
fclose(fp1) ;
map.point[0][0].PointType=1;//第一点一定要为不可通过的点
}
void PathOut(void)
{ FILE *fp2;
int i,j;
fp2=fopen("path.dat", "w");
for(i=0;i<AntNumber;i++)
{for(j=0;j<StepLimit;j++)
{
fprintf(fp2, "%5d",ant[i].path[j]);
fprintf(fp2, " ");
}
fprintf(fp2,"\n");
}
fclose(fp2) ;
}
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_COMMAND(ID_SETPAR, OnSetpar)
ON_COMMAND(ID_STARTSIMU, OnStartsimu)
ON_COMMAND(ID_SHOWSHANGE, OnShowshange)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
}
CMainFrame::~CMainFrame()
{
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
void CMainFrame::OnSetpar()
{
// TODO: Add your command handler code here
static int flag=0;
if(!flag)
{
SetPD.m_gener=500;
SetPD.m_beta=2.3;
SetPD.m_alpha=2.2;
}
flag++;
SetPD.DoModal();
}
void CMainFrame::OnStartsimu() //开始仿真
{
int i,j,step;
int BestAntNum;
int mm,nn;
double BetValue;
// MessageBox("start sim");
GenerLimit=SetPD.m_gener;
map.Target=TarGetG;/////////////******************??????????////////////
for(j=0;j<AntNumber;j++)//对蚂蚁和地图初始化其变量 Target
{
ant[j].Target=TarGetG;////////////******************??????????////////////
ant2[j].Target=StartPoint;////////////******************??????????////////////
}
MapIn();
for(i=0;i<GenerLimit;i++)
{
for(j=0;j<AntNumber;j++)//生成新一代蚂蚁 对蚂蚁进行初始化
{
ant[j].init();
ant[j].beta=SetPD.m_beta; //引力系数加强为1.0
ant[j].alpha=SetPD.m_alpha; //XXX
ant2[j].init();
ant2[j].beta=SetPD.m_beta; //引力系数加强为1.0
ant2[j].alpha=SetPD.m_alpha; //XXX
}
for(j=0;j<AntNumber;j++)//init every ant
{
ant[j].path[0]=StartPoint; //init ant j with start point
ant2[j].path[0]=TarGetG; //init ant j with start point
}
for(step=1;step<StepLimit;step++)
{
srand( (unsigned)time( NULL )*(step+1)*rand());
for(j=0;j<AntNumber;j++)
{
if(ant[j].WorkDone==1||ant[j].PathValue==-1)
// continue; //如果某蚂蚁已经达到目标点 或者作废了 则转为处理下一只
goto pp;
CreatArea9(ant[j].path[step-1],j,step);
//生成邻域 9点 放到邻域数组里 以坐标点的形式存储
ant[j].CalculateDr();
//计算每个点的引力概率 放到邻域数组
ant[j].CalculatePr();
//计算每个点的转移概率 放到邻域数组
///////////////////////////////////////////////
BetValue=rand()/(double)RAND_MAX;
//printf("BetValue= %f\n",BetValue);
///////////////////////////////////////////////
if(ant[j].PathValue!=-1)
ant[j].bet(j,step,BetValue);
//根据赌盘算法选取转移点 放到path[step]中
pp: if(ant2[j].WorkDone==1||ant2[j].PathValue==-1)
continue; //如果某蚂蚁已经达到目标点 或者作废了 则转为处理下一只
CreatArea9_ant2(ant2[j].path[step-1],j,step);
//生成邻域 9点 放到邻域数组里 以坐标点的形式存储
ant2[j].CalculateDr();
//计算每个点的引力概率 放到邻域数组
ant2[j].CalculatePr();
//计算每个点的转移概率 放到邻域数组
///////////////////////////////////////////////
BetValue=rand()/(double)RAND_MAX;
//printf("BetValue= %f\n",BetValue);
///////////////////////////////////////////////
if(ant2[j].PathValue!=-1)
ant2[j].bet(j,step,BetValue);
//根据赌盘算法选取转移点 放到path[step]中
}
}
map.UpdateMap(); // 消散信息素;
for(j=0;j<AntNumber;j++)
{
ant2[j].TurnPath();
}
///**********************************************************///
//在此对所得两个种群的蚂蚁进行全面相交,把优化的结果写到第一种群中
// Cross();
for(nn=0;nn<AntNumber;nn++)
for(mm=0;mm<StepLimit;mm++)
data[i].path[nn][mm]=ant[nn].path[mm];//把数据写入data中
///**********************************************************///
for(j=0;j<AntNumber;j++)
{
ant[j].AnalyzePath();//对路径进行处理
}
BestAntNum=GetBestAnt();//得到各代中具有最优值的蚂蚁号码
// PathOut();
if(BestValue>ant[BestAntNum].PathValue&&ant[BestAntNum].PathValue>1)
{
for(j=0;j<StepLimit;j++)
BestTrail[j]=ant[BestAntNum].path[j];
BestValue=ant[BestAntNum].PathValue;
}
for(j=0;j<AntNumber;j++)
{
if(ant[j].PathValue>0) //只更新可行解
map.UpdateInfo(Q/ant[j].PathValue, ant[j].path);
}//加入新一代的信息素
}
////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
DrawPath(BestTrail);
// MessageBox("end sim");
// for(i=0;i<20;i++)
// {
// DrawPath(ant[i].path);
// MessageBox("i");
// }
for(mm=0;mm<GenerLimit;mm++)
for(nn=0;nn<AntNumber;nn++)
AnalyzePathG(mm,nn);
//////////处理以后需要输出//////////
DataOut();
}
int CMainFrame::GetBestAnt()//返回具有最佳路径的蚂蚁编号
{
int i,BestAnt=0;
double TValue[AntNumber];
for(i=0;i<AntNumber;i++)
if(ant[i].PathValue>1)
{
TValue[i]=100000/ant[i].PathValue;
}
else
TValue[i]=0;
for(i=0;i<AntNumber;i++)
if(TValue[i]>TValue[BestAnt])//
BestAnt=i;
return BestAnt;
}
void CMainFrame::CreatArea9(unsigned int core, unsigned int AntNum, int step2)
{
unsigned int i,j,point;
ant[AntNum].area9[1][1].x=core%mapH;
ant[AntNum].area9[1][1].y=core/mapH;//设置中心点-核-现在时刻所在点
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
ant[AntNum].area9[i][j].x=ant[AntNum].area9[1][1].x-1+j;
ant[AntNum].area9[i][j].y=ant[AntNum].area9[1][1].y-1+i;
//填充其他八点 用坐标点的方式
if(ant[AntNum].area9[i][j].x>=mapH||ant[AntNum].area9[i][j].y>=mapV
||ant[AntNum].area9[i][j].x<0||ant[AntNum].area9[i][j].y<0)
{ ant[AntNum].area9[i][j].state=1;
ant[AntNum].area9[i][j].pr=0;
continue; }
//查看各点是否超过地图范围
if(map.point[ant[AntNum].area9[i][j].y][ant[AntNum].area9[i][j].x].PointType)
{ ant[AntNum].area9[i][j].state=1;
ant[AntNum].area9[i][j].pr=0;
continue;
}
//查看各点的状态
point=ant[AntNum].area9[i][j].y*mapH+ant[AntNum].area9[i][j].x;// 对点编码
if(ant[AntNum].FindInPath(point,step2)) //
{ant[AntNum].area9[i][j].state=2;
ant[AntNum].area9[i][j].pr=0;
continue;}
//还要查询禁忌表 把已经走过的点标记为不可通过 ×××
ant[AntNum].area9[i][j].state=0;
ant[AntNum].area9[i][j].pr=map.point[ant[AntNum].area9[i][j].y][ant[AntNum].area9[i][j].x].tau;
//初始信息素 pr 单元
}
if(ant[AntNum].area9[0][1].state==1)
{
ant[AntNum].area9[0][0].state=1;
ant[AntNum].area9[0][0].pr=0;
ant[AntNum].area9[0][2].state=1;
ant[AntNum].area9[0][2].pr=0;
}
if(ant[AntNum].area9[1][0].state==1)
{
ant[AntNum].area9[0][0].state=1;
ant[AntNum].area9[0][0].pr=0;
ant[AntNum].area9[2][0].state=1;
ant[AntNum].area9[2][0].pr=0;
}
if(ant[AntNum].area9[2][1].state==1)
{
ant[AntNum].area9[2][2].state=1;
ant[AntNum].area9[2][2].pr=0;
ant[AntNum].area9[2][0].state=1;
ant[AntNum].area9[2][0].pr=0;
}
if(ant[AntNum].area9[1][2].state==1)
{
ant[AntNum].area9[2][2].state=1;
ant[AntNum].area9[2][2].pr=0;
ant[AntNum].area9[0][2].state=1;
ant[AntNum].area9[0][2].pr=0;
}
}
void CMainFrame::DrawPath(unsigned int *p)
{
int i;
unsigned int x,y,gys,gys2;
gys=400/mapH;
gys2=200/mapH;
CClientDC dc(this);
CPen newpen;
CPen *oldpen;
newpen.CreatePen(PS_SOLID,3,RGB(0,0,0));
oldpen=dc.SelectObject(&newpen);
for(i=0;i<StepLimit;i++)
{
if(*p==ant[0].Target)
break;
x=(*p%mapH)*gys+gys2;
y=(*p/mapV)*gys+gys2;
dc.MoveTo(x,y);
if(*(p+1)==0)
if(*(p+2)==0||i==StepLimit-1)
break;
p++;
x=(*p%mapH)*gys+gys2;
y=(*p/mapV)*gys+gys2;
dc.LineTo(x,y);
}
dc.SelectObject(oldpen);
newpen.DeleteObject();
}
void CMainFrame::OnShowshange()
{
// TODO: Add your command handler code here
int x,y,i;
// StartPoint=41,TarGetG=1598;
///////////////////////////////////////////////////////////////
int x0,y0,x1,y1,a,b,gys;
CClientDC dc(this);
CBrush newbrush;
CBrush *oldbrush;
a=StartPoint%mapH;
b=StartPoint/mapH;
newbrush.CreateSolidBrush(RGB(0,0,255));
gys=400/mapH;
x0=gys*a;
y0=gys*b;
x1=gys*a+gys;
y1=gys*b+gys;
oldbrush=dc.SelectObject(&newbrush);
dc.Rectangle(x0,y0,x1,y1);
dc.SelectObject(oldbrush);
newbrush.DeleteObject();
a=TarGetG%mapH;
b=TarGetG/mapH;
newbrush.CreateSolidBrush(RGB(0,255,0));
x0=gys*a;
y0=gys*b;
x1=gys*a+gys;
y1=gys*b+gys;
oldbrush=dc.SelectObject(&newbrush);
dc.Rectangle(x0,y0,x1,y1);
dc.SelectObject(oldbrush);
newbrush.DeleteObject();
/////////////////////////////////////////////////////////////////
// CClientDC dc(this);
CPen newpen;
CPen *oldpen;
newpen.CreatePen(PS_DOT,1,RGB(0,0,0));
oldpen=dc.SelectObject(&newpen);
x=400/mapH;
y=400/mapH;
for(i=0;i<mapH;i++)
{
dc.MoveTo(x*i,0);
dc.LineTo(x*i,400);
}
for(i=0;i<mapH;i++)
{
dc.MoveTo(0,i*y);
dc.LineTo(400,i*y);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -