📄 gayhdlg.cpp
字号:
// GAyhDlg.cpp : implementation file
//
#include "stdafx.h"
#include "GAyh.h"
#include "GAyhDlg.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGAyhDlg dialog
CGAyhDlg::CGAyhDlg(CWnd* pParent /*=NULL*/)
: CDialog(CGAyhDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CGAyhDlg)
m_pc = 0.6;
m_pm = 0.1;
m_maxgeneration = 500;
m_size =100;
m_fxy = 0.0;
m_x = 0.0;
m_y = 0.0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CGAyhDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CGAyhDlg)
DDX_Control(pDX, IDC_LIST_SHOW, m_show);
DDX_Text(pDX, IDC_PC, m_pc);
DDX_Text(pDX, IDC_pm, m_pm);
DDX_Text(pDX, IDC_MAXGENERATION, m_maxgeneration);
DDX_Text(pDX, IDC_POPSIZE, m_size);
DDX_Text(pDX, IDC_EDIT1, m_fxy);
DDX_Text(pDX, IDC_EDIT2, m_x);
DDX_Text(pDX, IDC_EDIT3, m_y);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CGAyhDlg, CDialog)
//{{AFX_MSG_MAP(CGAyhDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_YHRUN, OnYhrun)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGAyhDlg message handlers
BOOL CGAyhDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
CRect rect;
m_show.GetClientRect(&rect);
int width=rect.Width()/4;
m_show.InsertColumn(0,_T("遗传代数"),LVCFMT_LEFT,width*0.8);
m_show.InsertColumn(1,_T("平均适应度"),LVCFMT_LEFT,width*0.8);
m_show.InsertColumn(2,_T("最优值"),LVCFMT_LEFT,width*0.8);
m_show.InsertColumn(4,_T("x值"),LVCFMT_LEFT,width*0.8);
m_show.InsertColumn(5,_T("y值"),LVCFMT_LEFT,width);
InsertItems();
return TRUE; // return TRUE unless you set the focus to a control
}
void CGAyhDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CGAyhDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CGAyhDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
genotype* CGAyhDlg::newsize()
{
genotype *p;
p=new genotype[m_size+1];
return p;
}
void CGAyhDlg::OnYhrun()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
srand((unsigned)time(NULL));
generation = 0;
initialize();
evaluate();
keep_the_best();
while(generation<m_maxgeneration)
{
generation++;
select();
across();
mutate();
report();
evaluate();
elitist();
}
InsertItems();
m_show.SetRedraw(TRUE);
m_fxy=population[m_size].fitness;
m_x=population[m_size].gene[0];
m_y=population[m_size].gene[1];
UpdateData(FALSE);
delete population;
delete newpopulation;
}
void CGAyhDlg::initialize()
{
int i, j;
double lbound=-10.0;
double ubound=10.0;
population=newsize();
newpopulation=newsize();
data=new Data[m_maxgeneration];
for (i = 0; i < NVARS; i++)
{
for (j = 0; j < m_size; j++)
{
population[j].fitness = 0;
population[j].rfitness = 0;
population[j].cfitness = 0;
population[j].lower[i] = lbound;
population[j].upper[i]= ubound;
population[j].gene[i] = randval(population[j].lower[i],
population[j].upper[i]);
}
}
}
double CGAyhDlg::randval(double low, double high)
{
double val;
val = ((double)(rand()%1000)/1000.0)*(high - low) + low;
return(val);
}
void CGAyhDlg::evaluate()
{
int mem;
int i;
double x[NVARS+1];
for (mem = 0; mem < m_size; mem++)
{
for (i = 0; i < NVARS; i++)
x[i+1] = population[mem].gene[i];
population[mem].fitness = 0.5-(sin(sqrt((x[1]-2)*(x[1]-2)+x[2]*x[2]))*sin(sqrt((x[1]-2)*(x[1]-2)+x[2]*x[2]))-0.5)/((1+0.001*((x[1]-2)*(x[1]-2)+x[2]*x[2]))*(1+0.001*((x[1]-2)*(x[1]-2)+x[2]*x[2])));
}
}
void CGAyhDlg::keep_the_best()
{
int mem;
int i;
cur_best = 0; /* stores the index of the best individual */
for (mem = 0; mem < m_size; mem++)
{
if (population[mem].fitness > population[m_size].fitness)
{
cur_best = mem;
population[m_size].fitness = population[mem].fitness;
}
}
/* once the best member in the population is found, copy the genes */
for (i = 0; i < NVARS; i++)
population[m_size].gene[i] = population[cur_best].gene[i];
}
void CGAyhDlg::elitist()
{
int i;
double best, worst; /* best and worst fitness values */
int best_mem, worst_mem; /* indexes of the best and worst member */
best = population[0].fitness;
worst = population[0].fitness;
for (i = 0; i < m_size - 1; ++i)
{
if(population[i].fitness > population[i+1].fitness)
{
if (population[i].fitness >= best)
{
best = population[i].fitness;
best_mem = i;
}
if (population[i+1].fitness <= worst)
{
worst = population[i+1].fitness;
worst_mem = i + 1;
}
}
else
{
if (population[i].fitness <= worst)
{
worst = population[i].fitness;
worst_mem = i;
}
if (population[i+1].fitness >= best)
{
best = population[i+1].fitness;
best_mem = i + 1;
}
}
}
if (best >= population[m_size].fitness)
{
for (i = 0; i < NVARS; i++)
population[m_size].gene[i] = population[best_mem].gene[i];
population[m_size].fitness = population[best_mem].fitness;
}
else
{
for (i = 0; i < NVARS; i++)
population[worst_mem].gene[i] = population[m_size].gene[i];
population[worst_mem].fitness = population[m_size].fitness;
}
}
void CGAyhDlg::select()
{
int mem, i, j;
double sum = 0;
double p;
/* find total fitness of the population */
for (mem = 0; mem < m_size; mem++)
{
sum += population[mem].fitness;
}
/* calculate relative fitness */
for (mem = 0; mem < m_size; mem++)
{
population[mem].rfitness = population[mem].fitness/sum;
}
population[0].cfitness = population[0].rfitness;
/* calculate cumulative fitness */
for (mem = 1; mem < m_size; mem++)
{
population[mem].cfitness = population[mem-1].cfitness +
population[mem].rfitness;
}
/* finally select survivors using cumulative fitness. */
for (i = 0; i < m_size; i++)
{
p = rand()%1000/1000.0;
if (p < population[0].cfitness)
newpopulation[i] = population[0];
else
{
for (j = 0; j < m_size;j++)
if (p >= population[j].cfitness &&
p<population[j+1].cfitness)
newpopulation[i] = population[j+1];
}
}
/* once a new population is created, copy it back */
for (i = 0; i < m_size; i++)
population[i] = newpopulation[i];
}
void CGAyhDlg::across()
{
int mem, one;
int first = 0; /* count of the number of members chosen */
double x;
for (mem = 0; mem < m_size; ++mem)
{
x = rand()%1000/1000.0;
if (x < m_pc)
{
++first;
if (first % 2 == 0)
Xover(one, mem);
else
one = mem;
}
}
}
void CGAyhDlg::Xover(int one, int two)
{
int i;
int point; /* crossover point */
/* select crossover point */
if(NVARS > 1)
{
if(NVARS == 2)
point = 1;
else
point = (rand() % (NVARS - 1)) + 1;
for (i = 0; i < point; i++)
swap(&population[one].gene[i], &population[two].gene[i]);
}
}
void CGAyhDlg::swap(double *x, double *y)
{
double temp;
temp = *x;
*x = *y;
*y = temp;
}
void CGAyhDlg::mutate()
{
int i, j;
double lbound, hbound;
double x;
for (i = 0; i < m_size; i++)
for (j = 0; j < NVARS; j++)
{
x = rand()%1000/1000.0;
if (x < m_pm)
{
/* find the bounds on the variable to be mutated */
lbound = population[i].lower[j];
hbound = population[i].upper[j];
population[i].gene[j] = randval(lbound, hbound);
}
}
}
void CGAyhDlg::report()
{
int i;
double best_val; /* best population fitness */
double avg; /* avg population fitness */
double stddev; /* std. deviation of population fitness */
double sum_square; /* sum of square for std. calc */
double square_sum; /* square of sum for std. calc */
double sum; /* total population fitness */
sum = 0.0;
sum_square = 0.0;
for (i = 0; i < m_size; i++)
{
sum += population[i].fitness;
sum_square += population[i].fitness * population[i].fitness;
}
avg = sum/(double)m_size;
square_sum = avg * avg * m_size;
stddev = sqrt((sum_square - square_sum)/(m_size - 1));
best_val = population[m_size].fitness;
data[generation-1].avefitness=avg;
data[generation-1].bestvalue=best_val;
data[generation-1].xbest=population[m_size].gene[0];
data[generation-1].ybest=population[m_size].gene[1];
}
void CGAyhDlg::InsertItems()
{
m_show.DeleteAllItems();
int i;
LVITEM lvi;
CString strItem;
for(i=1;i<=generation;i++)
{
lvi.mask = LVIF_TEXT;
lvi.iItem = i-1;
strItem.Format(_T("%d"), i);
lvi.iSubItem =0;
lvi.pszText = (LPTSTR)(LPCTSTR)(strItem);
m_show.InsertItem(&lvi);
strItem.Format(_T("%f"), data[i-1].avefitness);
lvi.iSubItem =1;
lvi.pszText = (LPTSTR)(LPCTSTR)(strItem);
m_show.SetItem(&lvi);
strItem.Format(_T("%f"),data[i-1].bestvalue);
lvi.iSubItem =2;
lvi.pszText = (LPTSTR)(LPCTSTR)(strItem);
m_show.SetItem(&lvi);
strItem.Format(_T("%f"), data[i-1].xbest);
lvi.iSubItem =3;
lvi.pszText = (LPTSTR)(LPCTSTR)(strItem);
m_show.SetItem(&lvi);
strItem.Format(_T("%f"), data[i-1].ybest);
lvi.iSubItem =4;
lvi.pszText = (LPTSTR)(LPCTSTR)(strItem);
m_show.SetItem(&lvi);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -