www.pudn.com > julei.rar > juleiView.cpp


// juleiView.cpp : implementation of the CJuleiView class 
// 
 
#include "stdafx.h" 
#include "julei.h" 
#include "math.h" 
#include "juleiDoc.h" 
#include "juleiView.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CJuleiView 
 
IMPLEMENT_DYNCREATE(CJuleiView, CView) 
 
BEGIN_MESSAGE_MAP(CJuleiView, CView) 
	//{{AFX_MSG_MAP(CJuleiView) 
	ON_COMMAND(IDM_JULEI, OnJulei) 
	//}}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() 
 
///////////////////////////////////////////////////////////////////////////// 
// CJuleiView construction/destruction 
 
CJuleiView::CJuleiView() 
{ 
	// TODO: add construction code here 
	for (int i=0;i<21;i++) 
	{ 
		for (int j=0;j<9;j++) 
		{ 
			pt[i][j]=0; 
			m_pt[i][j]=0; 
			//m_juli[i][j]=0; 
		} 
	} 
	for (i=0;i<21;i++) 
	{ 
		for (int j=0;j<21;j++) 
		{ 
			m_juli[i][j]=0; 
		} 
	} 
	for (i=0;i<9;i++) 
	{ 
		m_p1[i]=0; 
		m_p2[i]=0; 
	} 
	m_pTreeRoot = NULL; 
	nodes = NULL; 
} 
 
CJuleiView::~CJuleiView() 
{ 
} 
 
BOOL CJuleiView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CJuleiView drawing 
 
void CJuleiView::OnDraw(CDC* pDC) 
{ 
	CJuleiDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
	if(m_pTreeRoot == NULL) 
		return; 
	t = 30; 
	CPoint RootPos = huizhi(m_pTreeRoot,pDC); 
 
	CSize sizeTotal; 
	sizeTotal.cx = RootPos.x + 55; 
	sizeTotal.cy = t; 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CJuleiView printing 
 
BOOL CJuleiView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CJuleiView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CJuleiView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CJuleiView diagnostics 
 
#ifdef _DEBUG 
void CJuleiView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CJuleiView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CJuleiDoc* CJuleiView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CJuleiDoc))); 
	return (CJuleiDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CJuleiView message handlers 
 
void CJuleiView::OnJulei()  
{ 
	// TODO: Add your command handler code here 
	FILE *in; 
	int i,j=0; 
	in=fopen("data.txt","r"); 
	for (i=0;i<21;i++) 
	{ 
		for (j=0;j<9;j++) 
		{ 
			fscanf(in,"%f",&pt[i][j]); 
		} 
	} 
	fclose(in); 
 
	for (i=0;i<9;i++) 
	{ 
		for (j=0;j<21;j++) 
		{ 
			m_p1[i]+=pt[j][i]; 
		} 
		m_p1[i]=m_p1[i]/21; 
	} 
	for (i=0;i<9;i++) 
	{ 
		for (j=0;j<21;j++) 
		{ 
			m_p2[i]+=( pt[j][i]-m_p1[i] ) * ( pt[j][i]-m_p1[i] ); 
		} 
		m_p2[i]=(float)sqrt(m_p2[i]/21); 
	} 
	for (i=0;i<9;i++) 
	{ 
		for (j=0;j<21;j++) 
		{ 
			m_pt[j][i]=(pt[j][i]-m_p1[i])/m_p2[i]; 
		} 
	} 
	FILE* fp = fopen("result.txt","w"); 
	fprintf(fp,"标准化后的聚类要素:\n"); 
	for (i=0;i<21;i++) 
	{ 
		for (j=0;j<9;j++) 
		{ 
			if (j==8) 
			{ 
				fprintf(fp,"%10.6f\n",m_pt[i][j]); 
			} 
			else fprintf(fp,"%10.6f",m_pt[i][j]); 
		} 
	} 
 
	int k; 
	float s; 
	for (i=0;i<21;i++) 
	{ 
		for (j=0;j<21;j++) 
		{ 
			s=0; 
			for (k=0;k<9;k++) 
			{ 
				m_juli[i][j] +=((m_pt[i][k]-m_pt[j][k] ) * (m_pt[i][k]-m_pt[j][k] )); 
			} 
				m_juli[i][j]=(float)sqrt(m_juli[i][j]);//欧式距离矩阵 
		} 
	} 
	//fclose(fp); 
	//fp = fopen("result.txt","a"); 
	fprintf(fp,"Distance:\n"); 
	for (i=0;i<21;i++) 
	{ 
		for (j=0;j<21;j++) 
		{ 
			if (j==20) 
			{ 
				fprintf(fp,"%10.6f\n",m_juli[i][j]); 
			} 
			else fprintf(fp,"%10.6f",m_juli[i][j]); 
		} 
	} 
 
	int size=41,count=21; 
	float* pDis = new float[size * size]; 
	memset(pDis,0,size * size * sizeof(float)); 
	for (i=0;i<21;i++) 
	{ 
		for (j=0;j<21;j++) 
		{ 
			pDis[i * 41 + j] = pDis[j * 41 + i] = m_juli[i][j]; 
		} 
	} 
 
	delete[] nodes; 
	nodes = new Node[41]; 
	for(i = 0; i < 41; i++) 
	{ 
		nodes[i].id = i; 
		nodes[i].dis = 0; 
		nodes[i].lchild = NULL; 
		nodes[i].rchild = NULL; 
	} 
	 
	bool* bValid = new bool[size]; 
	for(i = 0; i < 21; i++) 
	{ 
		bValid[i] = true; 
	} 
	for(;i < 41; i++) 
	{ 
		bValid[i] = false; 
	} 
 
	int* leishu = new int[size]; 
	for(i = 0; i < 21; i++) 
	{ 
		leishu[i] = 1; 
	} 
	for(; i < 41; i++) 
	{ 
		leishu[i] = 0; 
	} 
 
	//聚类 
	int lei = 21; 
	int sum =21; 
	while(lei > 1) 
	{ 
		int i,j; 
 
		//输出 
		fprintf(fp,"距离矩阵:\n"); 
		fprintf(fp,"存在%d类时的距离矩阵\n",lei); 
		for(i = 0; i < size; i++) 
		{ 
			if(bValid[i]) 
			{ 
				fprintf(fp,"第%d类:\t",i+1); 
				for(j = 0; j < size; j++) 
				{ 
					if(bValid[j]) 
						fprintf(fp,"%8.4f",pDis[i * size + j]); 
				} 
				fprintf(fp,"\n"); 
			} 
		} 
 
		//找出当前最小距离 
 		double min = 10000; 
		int min1,min2; 
		for(i = 0; i < size; i++) 
		{ 
			if(!(bValid[i])) 
				continue; 
			for(j = 0; j <= i; j++) 
			{ 
				if(i == j) 
					continue; 
				if(!(bValid[j])) 
					continue; 
				if(pDis[i * size + j] < min) 
				{ 
					min2 = i; 
					min1 = j; 
					min = pDis[i * size + j]; 
				} 
			} 
		} 
	 
		nodes[sum].lchild = nodes + min1; 
		nodes[sum].rchild = nodes + min2; 
		nodes[sum].dis = min; 
 
		leishu[sum] = leishu[min1] + leishu[min2]; 
		bValid[min1] = false; 
		bValid[min2] = false; 
		bValid[sum] = true; 
 
		fprintf(fp,"第%d类(有%d个对象)+第%d类(有%d个对象)=第%d类(有%d个对象),距离=%f\n\n", 
			min1+1,leishu[min1],min2+1,leishu[min2],sum+1,leishu[sum],min); 
 
 
		//计算新的距离,放入第nodeCount行列 
		for(i = 0; i < size; i++) 
		{ 
			if(i == min1) 
				continue; 
			if(i == min2) 
				continue; 
			float newDis =(float)sqrt(  ( pDis[i * size + min1] * pDis[i * size + min1] * leishu[min1] 
								+ pDis[i * size + min2] * pDis[i * size + min2] * leishu[min2] )   
				                /leishu[sum] ); 
			pDis[i * size + sum] = newDis; 
			pDis[sum * size + i] = newDis; 
		} 
 
		sum++; 
		lei--; 
	} 
 
	m_pTreeRoot = &nodes[size-1]; 
	fclose(fp); 
	delete[] pDis; 
	Invalidate(); 
 
 
} 
 
 
CPoint CJuleiView::huizhi(Node *pBoot, CDC *pDC) 
{ 
	CPoint lPt,rPt,mPt; 
	if(pBoot->lchild != NULL && pBoot->rchild != NULL) 
	{ 
 
		lPt = huizhi(pBoot->lchild,pDC); 
		rPt = huizhi(pBoot->rchild,pDC); 
		mPt.y = (lPt.y + rPt.y) / 2; 
		mPt.x = (pBoot->id - 21) * 45 + 60; 
		pDC->MoveTo(lPt); 
		pDC->LineTo(mPt.x,lPt.y); 
		pDC->LineTo(mPt.x,rPt.y); 
		pDC->LineTo(rPt); 
		CString str; 
		str.Format("%.4f",pBoot->dis); 
		pDC->TextOut(mPt.x+1,mPt.y,str); 
	} 
	else 
	{ 
		CString str; 
		str.Format("%d",pBoot->id+1); 
		pDC->TextOut(5,t-8,str); 
		pDC->Ellipse(22,t-4,30,t+4); 
		mPt = CPoint(30,t); 
		t += 30; 
	} 
	return mPt; 
}