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;
}