📄 ourworkdlg.cpp
字号:
//////////////////////////////////
///删除两个类中最后的一个并将前面的那个的值修改/////////
CString strTemp=_T("");
strTemp.Format(_T("%0.3f"),fCenterX);
m_strArrayCenterX.RemoveAt(nIndex2);
m_strArrayCenterX.SetAt(nIndex1,strTemp);
strTemp.Format(_T("%0.3f"),fCenterY);
m_strArrayCenterY.RemoveAt(nIndex2);
m_strArrayCenterY.SetAt(nIndex1,strTemp);
m_nCenterNum--;
if(m_nCenterNum==0)
return;
///////////////////////////////////////////////////////
nTemp1=nIndex1;
nTemp2=nIndex2;
nCountOfMerg++;
}
/////////////////////////////////////////////
/////如果是最后一次迭代,那么要看该次迭代是否成功/////
if(ISODataCountNewCenter(m_nCenterNum))
//ISODataCountNewCenter(m_nCenterNum,&m_strArrayCenterX,&m_strArrayCenterY);
{///如果已经迭带成功
strTemp.Format(_T("ISODATA算法,迭代次数为%d,共分成了%d类"),m_nCountOfDieDai,m_nCenterNum);
SetDlgItemText(IDC_STATIC_INFO,strTemp);
m_bIsFinish=TRUE;
}
//////////////////////////////////////////////////////////
}
void COurWorkDlg::ISODataSplitter(int &nType)
{
CEachGroupInfo *pEachGroupInfo=(CEachGroupInfo*)m_ObArrayEachInfo.GetAt(nType-1);
CString strTemp=_T("");
float fAver=pEachGroupInfo->fEachAver;
int nCount=pEachGroupInfo->nCount;
if(m_fMaxSiLiang>m_fUpper)
{
if(fAver>m_fAllAver&&nCount>2*(m_nLeastNum+1)&&m_nCenterNum<=m_nType/2)
{///如果条件满足,则分裂该类//////////////
m_strArrayCenterX.RemoveAt(nType);
m_strArrayCenterY.RemoveAt(nType);
m_nCenterNum++;
////计算新的中心//////////////////
float fPianCha=(float)0.5*m_fMaxSiLiang;
float fTemp=pEachGroupInfo->fCenterX+fPianCha;
strTemp.Format(_T("%0.3f"),fTemp);
m_strArrayCenterX.Add(strTemp);
fTemp=pEachGroupInfo->fCenterY+fPianCha;
strTemp.Format(_T("%0.3f"),fTemp);
m_strArrayCenterY.Add(strTemp);
fTemp=pEachGroupInfo->fCenterX-fPianCha;
strTemp.Format(_T("%0.3f"),fTemp);
m_strArrayCenterX.Add(strTemp);
fTemp=pEachGroupInfo->fCenterY-fPianCha;
strTemp.Format(_T("%0.3f"),fTemp);
m_strArrayCenterY.Add(strTemp);
//m_nCountOfDieDai++;
m_bIsSplitter=TRUE;
///////////////////////////////////////
}
}
}
void COurWorkDlg::DrawISODataOrder()
{
CClientDC dc(this);
dc.SetBkColor(GetSysColor(COLOR_3DFACE));
///绘制横坐标//////////////////
dc.MoveTo(YUANDIAN_X1,YUANDIAN_Y1);
dc.LineTo(XEND_X1,XEND_Y1);
///////////////////////////////
///绘制纵坐标//////////////////
dc.MoveTo(YUANDIAN_X1,YUANDIAN_Y1);
dc.LineTo(YEND_X1,YEND_Y1);
///////////////////////////////
///绘制横坐标箭头//////////////////
dc.MoveTo(XEND_X1,XEND_Y1);
dc.LineTo(XEND_X1-14,XEND_Y1-5);
dc.MoveTo(XEND_X1,XEND_Y1);
dc.LineTo(XEND_X1-14,XEND_Y1+5);
dc.TextOut(XEND_X1-5,XEND_Y1+5,_T("X"));
///////////////////////////////
///绘制纵坐标箭头//////////////////
dc.MoveTo(YEND_X1,YEND_Y1);
dc.LineTo(YEND_X1-5,YEND_Y1+14);
dc.MoveTo(YEND_X1,YEND_Y1);
dc.LineTo(YEND_X1+5,YEND_Y1+14);
dc.TextOut(YEND_X1-5,YEND_Y1-20,_T("Y"));
///////原点////////////////////
CString strTemp=_T("0");
dc.TextOut(YUANDIAN_X1,YUANDIAN_Y1+2,strTemp);
///////////////////////////////
///////绘制X刻度////////////////
dc.MoveTo(XEND_X1-30-9,XEND_Y1+2);
dc.LineTo(XEND_X1-30-9,XEND_Y1-5);
dc.TextOut(XEND_X1-30-9,XEND_Y1+2+2,_T("10"));
for(int k=1;k<=9;k++)
{
CString strTemp=_T("");
strTemp.Format(_T("%d"),k);
dc.TextOut((XEND_X1-30-YUANDIAN_X1-9)/10*k+YUANDIAN_X1,XEND_Y1+2+2,strTemp);
dc.MoveTo((XEND_X1-30-YUANDIAN_X1-9)/10*k+YUANDIAN_X1,XEND_Y1+2);
dc.LineTo((XEND_X1-30-YUANDIAN_X1-9)/10*k+YUANDIAN_X1,XEND_Y1-5);
}
///////////////////////////////
///////绘制y刻度////////////////
strTemp=_T("10");
dc.TextOut(YEND_X1-20,YEND_Y1+30,strTemp);
dc.MoveTo(YEND_X1,YEND_Y1+30);
dc.LineTo(YEND_X1+5,YEND_Y1+30);
for(int n=1;n<=9;n++)
{
strTemp=_T("");
strTemp.Format(_T("%d"),n);
dc.TextOut(YEND_X1-20,YUANDIAN_Y1-(YUANDIAN_Y1-YEND_Y1-30)/10*n,strTemp);
dc.MoveTo(YEND_X1,YUANDIAN_Y1-(YUANDIAN_Y1-YEND_Y1-30)/10*n);
dc.LineTo(YEND_X1+5,YUANDIAN_Y1-(YUANDIAN_Y1-YEND_Y1-30)/10*n);
}
///////////////////////////////
}
void COurWorkDlg::ShowISODataDot()
{
CPaintDC dc(this);
CPen NewPen(PS_SOLID,1,RGB(255,0,0));
CPen *pOldPen=dc.SelectObject(&NewPen);
CBrush *pOldBrush;
float fY=float((float(YUANDIAN_Y1)-float(YEND_Y1+30))/float(10000));//实际将坐标分成了10000分,该计算得出每分的长度
float fX=float((float(XEND_X1-30-9)-float(YUANDIAN_X1))/float(10000));
for(int n=0;n<NCOUNT;n++)
{
int nX=(int )(m_fX[n]*1000);
int nY=(int )(m_fY[n]*1000);
int nTempX=(int)(YUANDIAN_X1+fX*nX);
int nTempY=(int)(YUANDIAN_Y1-fY*nY);
CBrush brush;
brush.CreateSolidBrush(RGB(255,0,0));
pOldBrush=dc.SelectObject(&brush);
dc.Ellipse(nTempX-2,nTempY-2,nTempX+2,nTempY+2);
}
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);
//Invalidate(NULL);
}
void COurWorkDlg::EnableControlC(BOOL bIsEnable)
{
CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_NUMC);
pEdit->EnableWindow(bIsEnable);
CButton *pButton=(CButton*)GetDlgItem(IDC_BUTTON_MODIFYC);
pButton->EnableWindow(!bIsEnable);
pButton=(CButton*)GetDlgItem(IDC_BUTTON_OKC);
pButton->EnableWindow(bIsEnable);
pButton=(CButton*)GetDlgItem(IDC_BUTTON_CANCELC);
pButton->EnableWindow(bIsEnable);
}
void COurWorkDlg::EnableControlISOData(BOOL bIsEnable)
{
CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_TPYENUM);
pEdit->EnableWindow(bIsEnable);
pEdit=(CEdit*)GetDlgItem(IDC_EDIT_CENTERNUMMODIFY);
pEdit->EnableWindow(bIsEnable);
pEdit=(CEdit*)GetDlgItem(IDC_EDIT_UPPERMODIFY);
pEdit->EnableWindow(bIsEnable);
pEdit=(CEdit*)GetDlgItem(IDC_EDIT_LEASTNUMMODIFY);
pEdit->EnableWindow(bIsEnable);
pEdit=(CEdit*)GetDlgItem(IDC_EDIT_BOTTOMMODIFY);
pEdit->EnableWindow(bIsEnable);
pEdit=(CEdit*)GetDlgItem(IDC_EDIT_MOSTPAIRMODIFY);
pEdit->EnableWindow(bIsEnable);
pEdit=(CEdit*)GetDlgItem(IDC_EDIT_MOSTCOUNTNUMMODIFY);
pEdit->EnableWindow(bIsEnable);
CButton *pButton=(CButton*)GetDlgItem(IDC_BUTTON_MODIFYISODATA);
pButton->EnableWindow(!bIsEnable);
pButton=(CButton*)GetDlgItem(IDC_BUTTON_OKISODATA);
pButton->EnableWindow(bIsEnable);
pButton=(CButton*)GetDlgItem(IDC_BUTTON_CANCELISODATA);
pButton->EnableWindow(bIsEnable);
}
void COurWorkDlg::OnButtonModifyc()
{
EnableControlC(TRUE);
CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_NUMC);
pEdit->SetFocus();
}
void COurWorkDlg::OnButtonCancelc()
{
EnableControlC(FALSE);
SetDlgItemText(IDC_EDIT_NUMC,m_strGroupCount);
}
void COurWorkDlg::OnButtonOkc()
{
UpdateData(TRUE);
CString strTemp=_T("");
GetDlgItemText(IDC_EDIT_NUMC,m_strGroupCount);
GetDlgItemText(IDC_EDIT_NUMC,strTemp);
if(strTemp.IsEmpty())
{
MessageBox(_T("请输入分组数目!"),_T("友情提示"));
CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_NUMC);
pEdit->SetFocus();
return;
}
m_bIsC=TRUE;
int nCount=0;
m_nGroupCount=(int)atoi(m_strGroupCount);
if(m_nGroupCount>NCOUNT)
{
MessageBox(_T("分类的数目大于了总的样本数目,请输入正确的分类数目!"),_T("友情提示"));
return;
}
m_nType=1;
ClearArray();////清空所有的数组
for(int n=0;n<m_nGroupCount;n++)
{
strTemp.Format(_T("%0.3f"),m_fX[n]);
m_strArrayCenterX.Add(strTemp);
strTemp.Format(_T("%0.3f"),m_fY[n]);
m_strArrayCenterY.Add(strTemp);
}
while(!m_bFlag)
{
CountDistance(&m_strArrayCenterX,&m_strArrayCenterY,m_nGroupCount);
if(CountNewCenter())
{///如果返回TURE,表示已经分类完成
m_bFlag=TRUE;
break;
}
nCount++;
}
m_bIsType=TRUE;
Invalidate(TRUE);////窗口重绘并擦除原来的背景
DrawOrder();
DrawPic();
strTemp=_T("");
strTemp.Format(_T("C均值法,迭代次数%d,共分成%d类"),nCount,m_nGroupCount);
/////显示提示信息//////////////////////
CStatic *pStatic=(CStatic*)GetDlgItem(IDC_STATIC_INFO);
SetDlgItemText(IDC_STATIC_INFO,strTemp);
EnableControlC(FALSE);
}
void COurWorkDlg::OnButtonModifyisodata()
{
EnableControlISOData(TRUE);
CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_TPYENUM);
pEdit->SetFocus();
}
void COurWorkDlg::OnButtonCancelisodata()
{
EnableControlISOData(FALSE);
SetISODataInfo();
}
void COurWorkDlg::OnButtonOkisodata()
{
m_nType=2;
m_bIsFinish=FALSE;
m_bIsIsoData=TRUE;
m_nCountOfDieDai=0;
CString strTemp=_T("");
int nCount=0;//迭代次数
ClearArray();///清空所有数组
GetDlgItemText(IDC_EDIT_TPYENUM,m_strTypeNum);
GetDlgItemText(IDC_EDIT_CENTERNUMMODIFY,m_strCenterNum);
GetDlgItemText(IDC_EDIT_UPPERMODIFY,m_strUpper);
GetDlgItemText(IDC_EDIT_LEASTNUMMODIFY,m_strLeastNum);
GetDlgItemText(IDC_EDIT_BOTTOMMODIFY,m_strBottom);
GetDlgItemText(IDC_EDIT_MOSTPAIRMODIFY,m_strMostPair);
GetDlgItemText(IDC_EDIT_MOSTCOUNTNUMMODIFY,m_strMostCountNum);
m_fBottom =(float) atof(m_strBottom);
m_nCenterNum =(int) atoi(m_strCenterNum);
m_nLeastNum = (int) atoi(m_strLeastNum);
m_nMostCountNum = (int) atoi(m_strMostCountNum);
m_nMostPair = (int) atoi(m_strMostPair);
m_nTypeNum = (int) atoi(m_strTypeNum);
m_fUpper = (float) atof(m_strUpper);
for(int n=0;n<m_nCenterNum;n++)
{
strTemp.Format(_T("%0.3f"),m_fX[n]);
m_strArrayCenterX.Add(strTemp);
strTemp.Format(_T("%0.3f"),m_fY[n]);
m_strArrayCenterY.Add(strTemp);
}
///////////////////////////////////////
///开始迭代////////////////////////////////////////
while(m_nCountOfDieDai<=m_nMostCountNum)
//while(1)
{
m_nCountOfDieDai++;
m_bIsSplitter=FALSE;
///清空数组////////////
m_nArrayEachNum.RemoveAll();
/*for(int n=0;n<m_ObjArray.GetSize();n++)
delete (CTypeAndData*)m_ObjArray.GetAt(n);
m_ObjArray.RemoveAll();*/
for( n=0;n<m_ObjArrayISOData.GetSize();n++)
delete (CTypeAndData*)m_ObjArrayISOData.GetAt(n);
m_ObjArrayISOData.RemoveAll();
for( n=0;n<m_ObArrayEachInfo.GetSize();n++)
delete (CEachGroupInfo*)m_ObArrayEachInfo.GetAt(n);
m_ObArrayEachInfo.RemoveAll();
/////////////////////////
/////按最小距离原则分类并记录下每个模式属于哪一类和该模式特征的/////////////////////
CountDistance(&m_strArrayCenterX,&m_strArrayCenterY,m_nCenterNum);
int nIndex=0;//用来记录是哪个组的个数小于了预设值
while(IsCancelCenter(nIndex))
{///当检测到有一组小于预设值的时候,将该组中心去掉,在重新分类,直到所有的分组的个数都大于预设值
m_nCenterNum=m_nCenterNum-1;
/*for(int n=0;n<m_ObjArray.GetSize();n++)
delete (CTypeAndData*)m_ObjArray.GetAt(n);
m_ObjArray.RemoveAll();*/
for( n=0;n<m_ObArrayEachInfo.GetSize();n++)
delete (CEachGroupInfo*)m_ObArrayEachInfo.GetAt(n);
m_ObArrayEachInfo.RemoveAll();
if(m_nCenterNum==0)
return;
if(m_strArrayCenterX.GetSize()>=1)
{
m_strArrayCenterX.RemoveAt(nIndex);
}
else
return;
if(m_strArrayCenterY.GetSize()>=1)
{
m_strArrayCenterY.RemoveAt(nIndex);
}
else
return;
CountDistance(&m_strArrayCenterX,&m_strArrayCenterY,m_nCenterNum);
}
/////////////////////////////////////////////////////////////
/////计算各类的中心/////////////////////////
if(ISODataCountNewCenter(m_nCenterNum))
//ISODataCountNewCenter(m_nCenterNum,&m_strArrayCenterX,&m_strArrayCenterY);
{///如果已经迭带成功
strTemp.Format(_T("ISODATA算法,迭代次数为%d,共分成了%d类"),m_nCountOfDieDai,m_nCenterNum);
SetDlgItemText(IDC_STATIC_INFO,strTemp);
m_bIsFinish=TRUE;
break;
}
////////////////////////////////////////////
/////计算各类中模式到类心的平均距离和各个模式到其类心的总体平均距离///////////
for( n=0;n<m_ObArrayEachInfo.GetSize();n++)
delete (CEachGroupInfo*)m_ObArrayEachInfo.GetAt(n);
m_ObArrayEachInfo.RemoveAll();
int nType=1;///记录最大的分量是属于第几类
ISODataCountAverDistance(nType);
/////////////////////////////////////////////
if(m_nCountOfDieDai==m_nMostCountNum)
{///如果达到迭代次数,跳转到第9步
ISODataCountDistanceBetweenClass();
if(!m_bIsFinish)
{///如果次数已经达到,但还没有收敛,那么提示//
MessageBox(_T("已经达到迭代次数,但尚未收敛!"),_T(";友情提示"));
strTemp.Format(_T("ISODATA算法,迭代次数为%d,但尚未收敛!"),m_nCountOfDieDai,m_nCenterNum);
SetDlgItemText(IDC_STATIC_INFO,strTemp);
m_fBottom=0.000f;
}
continue;
}
if((m_nCenterNum<=m_nTypeNum/2)&&(m_nCountOfDieDai< m_nMostCountNum))
{//转到第六步
ISODataSplitter(nType);
if(m_bIsSplitter)
continue;
ISODataCountDistanceBetweenClass();
}
else if((m_nCenterNum>2*m_nTypeNum)&&(m_nCountOfDieDai< m_nMostCountNum))
{//转至第九步,计算类间距离
ISODataCountDistanceBetweenClass();
}
else if(m_nCenterNum>m_nTypeNum/2&&m_nCenterNum<2*m_nTypeNum&&m_nCountOfDieDai< m_nMostCountNum)
{
if(m_nCountOfDieDai>0&&m_nCountOfDieDai%2==0)
{//转第九步
ISODataCountDistanceBetweenClass();
}
else if(m_nCountOfDieDai>0&&m_nCountOfDieDai%2==1)
{//转第六步
ISODataSplitter(nType);
if(m_bIsSplitter)
continue;
ISODataCountDistanceBetweenClass();
}
}
if(m_nCountOfDieDai==m_nMostCountNum)
{
MessageBox(_T("已经迭代完成,但尚未收敛!"),_T("友情提示"));
}
}
m_bIsType=TRUE;
Invalidate(TRUE);////窗口重绘并擦除原来的背景
DrawOrder();
DrawPic();
EnableControlISOData(FALSE);
}
void COurWorkDlg::SetISODataInfo()
{
SetDlgItemText(IDC_EDIT_TPYENUM,m_strTypeNum);
SetDlgItemText(IDC_EDIT_CENTERNUMMODIFY,m_strCenterNum);
SetDlgItemText(IDC_EDIT_UPPERMODIFY,m_strUpper);
SetDlgItemText(IDC_EDIT_LEASTNUMMODIFY,m_strLeastNum);
SetDlgItemText(IDC_EDIT_BOTTOMMODIFY,m_strBottom);
SetDlgItemText(IDC_EDIT_MOSTPAIRMODIFY,m_strMostPair);
SetDlgItemText(IDC_EDIT_MOSTCOUNTNUMMODIFY,m_strMostCountNum);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -