📄 isodataview.cpp
字号:
// IsoDataView.cpp : implementation of the CIsoDataView class
//
#include "stdafx.h"
#include "IsoData.h"
#include "math.h"
#include "IsoDataDoc.h"
#include "IsoDataView.h"
#include "SetDiaglog.h"
#include "Pattern.h"
#include "PatternCenter.h"
#include "MainFrm.h"
#include "Function.h"
#include "ResultDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CIsoDataView
IMPLEMENT_DYNCREATE(CIsoDataView, CView)
BEGIN_MESSAGE_MAP(CIsoDataView, CView)
//{{AFX_MSG_MAP(CIsoDataView)
ON_COMMAND(ID_CLUSTER_INPUT, OnClusterInput)
ON_WM_SIZE()
ON_COMMAND(ID_CLUSTER_ISODATA, OnClusterIsodata)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIsoDataView construction/destruction
CIsoDataView::CIsoDataView()
{
// TODO: add construction code here
m_pGridCtrl = NULL;
}
CIsoDataView::~CIsoDataView()
{
if (m_pGridCtrl)
delete m_pGridCtrl;
}
BOOL CIsoDataView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CIsoDataView drawing
void CIsoDataView::OnDraw(CDC* pDC)
{
CIsoDataDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CIsoDataView printing
BOOL CIsoDataView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CIsoDataView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CIsoDataView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CIsoDataView diagnostics
#ifdef _DEBUG
void CIsoDataView::AssertValid() const
{
CView::AssertValid();
}
void CIsoDataView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CIsoDataDoc* CIsoDataView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIsoDataDoc)));
return (CIsoDataDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CIsoDataView message handlers
void CIsoDataView::OnClusterInput()
{
// TODO: Add your command handler code here
CSetDiaglog dlg;
if (dlg.DoModal()==IDOK)
{
m_iPatternMension = dlg.m_iPatternMension;
m_iPatternMount = dlg.m_iPatternMount;
// TODO: Add your specialized code here and/or call the base class
if (m_pGridCtrl == NULL)
{
// 创建 Gridctrl 对象
m_pGridCtrl = new CGridCtrl;
if (!m_pGridCtrl) return;
// 创建 Gridctrl 窗口
CRect rect;
GetClientRect(rect);
m_pGridCtrl->Create(rect, this, 100);
// 填充数据
m_pGridCtrl->SetEditable(TRUE);
m_pGridCtrl->EnableDragAndDrop(TRUE);
try {
m_pGridCtrl->SetRowCount(m_iPatternMount+1);
m_pGridCtrl->SetColumnCount(m_iPatternMension+1);
m_pGridCtrl->SetFixedRowCount(1);
m_pGridCtrl->SetFixedColumnCount(1);
}
catch (CMemoryException* e)
{
e->ReportError();
e->Delete();
return;
}
// 填充每格数据
for (int row = 0; row <= m_pGridCtrl->GetRowCount(); row++)
for (int col = 0; col <= m_pGridCtrl->GetColumnCount(); col++)
{
GV_ITEM Item;
Item.mask = GVIF_TEXT|GVIF_FORMAT;
Item.row = row;
Item.col = col;
if (row < 1)
{
Item.nFormat = DT_LEFT|DT_WORDBREAK;
if(col==0)
{
Item.szText.Format(_T("分量"));
}
else
Item.szText.Format(_T("分量 %d"),col);
}
else if (col < 1)
{
Item.nFormat = DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS;
Item.szText.Format(_T("X%d"),row);
}
else
{
Item.nFormat = DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS;
Item.szText.Format(_T("%d"),0);
}
m_pGridCtrl->SetItem(&Item);
}
m_pGridCtrl->AutoSize();
m_pGridCtrl->SetRowHeight(0, 3*m_pGridCtrl->GetRowHeight(0)/2);
}
}
}
BOOL CIsoDataView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
// TODO: Add your specialized code here and/or call the base class
if (m_pGridCtrl && IsWindow(m_pGridCtrl->m_hWnd))
if (m_pGridCtrl->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
void CIsoDataView::OnInitialUpdate()
{
CView::OnInitialUpdate();
CMainFrame *pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
pFrame->pCIsoDataView = this;
}
void CIsoDataView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if (m_pGridCtrl->GetSafeHwnd())
{
CRect rect;
GetClientRect(rect);
m_pGridCtrl->MoveWindow(rect);
}
}
void CIsoDataView::OnClusterIsodata()
{
// TODO: Add your command handler code here
int iExecuteCount = 0;//迭代次数
int iSuccess = 0;
CPattern * pPattern;
CCenterDistance * pCenterDistance,* pCenterDistanceTemp;
CObList centerdistanceList;
int i;
//为所有模式分配空间,并把它们组成一个链表
for (i=1;i<=m_iPatternMount;i++)
{
pPattern = new CPattern(m_iPatternMension);
patternList.AddTail(pPattern);
}
//根据输入的数据,将它们读入每个模式中
CString s;
int j;
POSITION pos;
struct PatternElement * ptemp1;
struct PatternElement * ptemp2;
for (i=1;i<=m_iPatternMount;i++)
{
pos = patternList.FindIndex(i-1);
pPattern = (CPattern *)patternList.GetAt(pos);
pPattern->N = m_iPatternMension;
ptemp1 = pPattern->pPatternElementHead;
for(j=1;j<=m_iPatternMension;j++)
{
s = m_pGridCtrl->GetItemText(i,j);
ptemp1->num = j;
ptemp1->Element=0.0;
ptemp1->Element = atof(s);
ptemp1 = ptemp1->next;
}
}
//选定初始聚类中心
CPatternCenter * pPatternCenter, * pPatternCenterTemp;
for (i=1;i<=m_iInitialPaCenMount;i++)
{
pPatternCenter = new CPatternCenter(m_iPatternMension);
patterncenterList.AddTail(pPatternCenter);
pos = patternList.FindIndex(i-1);
pPattern = (CPattern *)patternList.GetAt(pos);
pPatternCenter->N = pPattern->N;
ptemp1 = pPattern->pPatternElementHead;
ptemp2 = pPatternCenter->pPatternElementHead;
for (j=1;j<=m_iPatternMension;j++)
{
ptemp2->num = ptemp1->num;
ptemp2->Element = ptemp1->Element;
ptemp1 = ptemp1->next;
ptemp2 = ptemp2->next;
}
}
//按最小距离原则将模式集中每个模式分到某一类中
step2:
iExecuteCount++;
::Classify(&patternList,&patterncenterList,m_iPatternMount,m_iInitialPaCenMount,m_iPatternMension);
//依据m_iMinPaMount判断合并。
for (i=1;i<=m_iInitialPaCenMount;i++)
{
pos = patterncenterList.FindIndex(i-1);
pPatternCenter = (CPatternCenter *)patterncenterList.GetAt(pos);
if(pPatternCenter->PatternMount < m_iMinPaMount)
{
::CancelPatternCenter(&patterncenterList,i);
m_iInitialPaCenMount = m_iInitialPaCenMount - 1;
goto step2;
}
}
//计算分类后的参数
//各类中心
::CalPatternCenter(&patternList,&patterncenterList,m_iInitialPaCenMount,m_iPatternMount,m_iPatternMension);
//各类中模式到类心的平均距离
::CalAverDisFromPaToCen(&patternList,&patterncenterList,m_iInitialPaCenMount,m_iPatternMount,m_iPatternMension);
//各个模式到其类内中心的总体平均距离
m_dWholeAverDis = 0.0;
for(i=1;i<=m_iInitialPaCenMount;i++)
{
pos = patterncenterList.FindIndex(i-1);
pPatternCenter = (CPatternCenter *)patterncenterList.GetAt(pos);
m_dWholeAverDis= m_dWholeAverDis + pPatternCenter->AverageDistanceFromPatternToCenter * pPatternCenter->PatternMount;
}
m_dWholeAverDis= m_dWholeAverDis/m_iPatternMount;
//根据迭代次数和m_dInitailPaCenMount停止、分裂、合并。
if(iExecuteCount == m_iMaxCount)
{
m_dMinDisPatCen = 0.0;
iSuccess = 1;
goto step9;
}
if(m_iInitialPaCenMount<=(m_iExpectPaCenMount/2))
{
goto step6;
}
if(m_iInitialPaCenMount>=(m_iExpectPaCenMount*2))
{
goto step9;
}
if(m_iInitialPaCenMount>(m_iExpectPaCenMount/2) && m_iInitialPaCenMount<=(m_iExpectPaCenMount*2))
{
if ((iExecuteCount % 2)==0)
{
goto step9;
}
}
//计算各类内距离的标准差矢量,求出最大的分量
step6:
::CalStandardDeviationMax(&patternList,&patterncenterList,m_iPatternMension,m_iInitialPaCenMount,m_iPatternMount);
//根据标准差矢量的最大分量判断分裂
for(i=1;i<=m_iInitialPaCenMount;i++)
{
pos = patterncenterList.FindIndex(i-1);
pPatternCenter = (CPatternCenter *)patterncenterList.GetAt(pos);
if(pPatternCenter->StandardDeviationMax > m_dMaxBZCha)
{
if((pPatternCenter->AverageDistanceFromPatternToCenter > m_dWholeAverDis &&
pPatternCenter->PatternMount > (m_iMinPaMount+1)*2) || m_iInitialPaCenMount <= m_iExpectPaCenMount/2)
{
pPatternCenterTemp = new CPatternCenter(m_iPatternMension);
patterncenterList.AddTail(pPatternCenterTemp);
ptemp1 = pPatternCenterTemp->pPatternElementHead;
ptemp2 = pPatternCenter->pPatternElementHead;
for(j=1;j<=m_iPatternMension;j++)
{
if(pPatternCenter->FlagStaDevMax == j)
{
ptemp1->Element = ptemp2->Element + (pPatternCenter->StandardDeviationMax/2);
}
else
{
ptemp1->Element = ptemp2->Element;
}
ptemp1->num = ptemp2->num;
ptemp1 = ptemp1->next;
ptemp2 = ptemp2->next;
}
pPatternCenterTemp = new CPatternCenter(m_iPatternMension);
patterncenterList.AddTail(pPatternCenterTemp);
ptemp1 = pPatternCenterTemp->pPatternElementHead;
ptemp2 = pPatternCenter->pPatternElementHead;
for(j=1;j<=m_iPatternMension;j++)
{
if(pPatternCenter->FlagStaDevMax == j)
{
ptemp1->Element = ptemp2->Element - (pPatternCenter->StandardDeviationMax/2);
}
else
{
ptemp1->Element = ptemp2->Element;
}
ptemp1->num = ptemp2->num;
ptemp1 = ptemp1->next;
ptemp2 = ptemp2->next;
}
::CancelPatternCenter(&patterncenterList,i);
m_iInitialPaCenMount = m_iInitialPaCenMount + 1;
goto step2;
}
}
}
//计算各类对中心间的距离
step9:
bool bFlag = true;
int iCount=0;
if(m_iInitialPaCenMount < 2)
{
goto end;
}
::CalSortDisPaCenter(&patterncenterList,¢erdistanceList,m_iMaxUniteMount,m_dMinDisPatCen,m_iInitialPaCenMount,m_iPatternMension);
//依据两类间最小距离合并
for(i=1;i<=centerdistanceList.GetCount();i++)
{
pos = centerdistanceList.FindIndex(i-1);
pCenterDistance = (CCenterDistance *)centerdistanceList.GetAt(pos);
for(j=1;j<i;j++)
{
pos = centerdistanceList.FindIndex(j-1);
pCenterDistanceTemp = (CCenterDistance *)centerdistanceList.GetAt(pos);
if((pCenterDistance->Center1 == pCenterDistanceTemp->Center1)||
(pCenterDistance->Center1 == pCenterDistanceTemp->Center2)||
(pCenterDistance->Center2 == pCenterDistanceTemp->Center1)||
(pCenterDistance->Center2 == pCenterDistanceTemp->Center2))
{
bFlag = true;
}
}
if(bFlag)
{
if(iSuccess==1)
{
iSuccess=2;
}
pCenterDistance->isUnite = 1;
pos = patterncenterList.FindIndex(pCenterDistance->Center1 - 1);
pPatternCenter = (CPatternCenter *)patterncenterList.GetAt(pos);
pos = patterncenterList.FindIndex(pCenterDistance->Center2 - 1);
pPatternCenterTemp = (CPatternCenter *)patterncenterList.GetAt(pos);
ptemp1 = pPatternCenterTemp->pPatternElementHead;
ptemp2 = pPatternCenter->pPatternElementHead;
for(j=1;j<=m_iPatternMension;j++)
{
ptemp1->Element=((pPatternCenterTemp->PatternMount * ptemp1->Element) +
(pPatternCenter->PatternMount * ptemp2->Element))/
(pPatternCenterTemp->PatternMount + pPatternCenter->PatternMount);
ptemp1 = ptemp1->next;
ptemp2 = ptemp2->next;
}
pPatternCenter = new CPatternCenter(m_iPatternMension);
patterncenterList.AddTail(pPatternCenter);
ptemp1 = pPatternCenterTemp->pPatternElementHead;
ptemp2 = pPatternCenter->pPatternElementHead;
for(j=1;j<=m_iPatternMension;j++)
{
ptemp2->Element = ptemp1 ->Element;
ptemp2->num = ptemp1->num;
ptemp1 = ptemp1->next;
ptemp2 = ptemp2->next;
}
bFlag = false;
}
else
{
pCenterDistance->isUnite = 0;
}
}
for(i=1;i<=centerdistanceList.GetCount();i++)
{
pos = centerdistanceList.FindIndex(i-1);
pCenterDistance = (CCenterDistance *)centerdistanceList.GetAt(pos);
if(pCenterDistance->isUnite==1)
{
::CancelPatternCenter(&patterncenterList,pCenterDistance->Center1);
::CancelPatternCenter(&patterncenterList,pCenterDistance->Center2);
iCount ++;
}
}
m_iInitialPaCenMount = m_iInitialPaCenMount - iCount;
//如果迭代次数已满或已经收敛则结束,否则转step2
if(iExecuteCount < m_iMaxCount)
{
goto step2;
}
if(iSuccess != 2)
{
CResultDialog dlg;
dlg.DoModal();
}
if(iSuccess == 2)
{
end:
::AfxMessageBox("对不起,迭代不成功!");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -