📄 k均值算法dlg.cpp
字号:
// K均值算法Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "K均值算法.h"
#include "K均值算法Dlg.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()
/////////////////////////////////////////////////////////////////////////////
// CKDlg dialog
CKDlg::CKDlg(CWnd* pParent /*=NULL*/)
: CDialog(CKDlg::IDD, pParent)
{
filename="";
check1=false;
//{{AFX_DATA_INIT(CKDlg)
m_K = 2;
m_Yang_Num = 1;
m_Wei_Num = 1;
m_f = 10.0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CKDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CKDlg)
DDX_Text(pDX, IDC_EDIT1, m_K);
DDV_MinMaxInt(pDX, m_K, 1, 999999);
DDX_Text(pDX, IDC_EDIT2, m_Yang_Num);
DDV_MinMaxInt(pDX, m_Yang_Num, 1, 999999);
DDX_Text(pDX, IDC_EDIT3, m_Wei_Num);
DDV_MinMaxInt(pDX, m_Wei_Num, 1, 99999);
DDX_Text(pDX, IDC_EDIT4, m_f);
DDV_MinMaxDouble(pDX, m_f, 1.e-009, 999999999.);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CKDlg, CDialog)
//{{AFX_MSG_MAP(CKDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CKDlg message handlers
BOOL CKDlg::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
return TRUE; // return TRUE unless you set the focus to a control
}
void CKDlg::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 CKDlg::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();
}
if (check1==true)
{
////////////////////////////////////////////////////////
CStatic *out=((CStatic*)GetDlgItem(IDC_STATIC_MAP));
CDC *pDC=out->GetDC();
CRect rect;
out->GetClientRect(&rect);
CBrush *pOldBrush;
CBrush brFill;
brFill.CreateSolidBrush(RGB(255,255,255));
pOldBrush=pDC->SelectObject(&brFill);
out->GetClientRect(&rect);
pDC->FillRect(rect,&brFill);
COLORREF color;
//////////////////////////////////////////////////////////
if (m_Wei_Num==2)
{
for(int c=0;c<m_Yang_Num*m_Wei_Num;c+=2)
{
if (master[c/2]%3<=0)
{
color=RGB(114*master[c/2]%256,148*master[c/2]%256,0);
}
else if (master[c/2]%3<=1)
{
color=RGB(135*master[c/2]%256,0,110*master[c/2]%256);
}
else if (master[c/2]%3<=2)
{
color=RGB(88*master[c/2]%256,164*master[c/2]%256,0);
}
for(int e=-2;e<=2;e++)
{
for(int f=-2;f<=2;f++)
{
pDC->SetPixel(swatch[c]*m_f+rect.Width()/2+f,(-swatch[c+1]*m_f+rect.Height()/2)+e,color);
}
}
}
CPen *Blackpen;
Blackpen=new CPen(PS_SOLID,1,RGB(0,0,0));
pDC->SelectObject(Blackpen);
pDC->MoveTo(0,rect.Height()/2);
pDC->LineTo(rect.Width(),rect.Height()/2);
pDC->MoveTo(rect.Width()/2,0);
pDC->LineTo(rect.Width()/2,rect.Height());
pDC->SetBkMode(TRANSPARENT);
pDC->TextOut(rect.Width()/2,0,"Y");
pDC->TextOut(rect.Width(),rect.Height()/2,"X");
}
else
{
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor((0,0,255));
pDC->TextOut(rect.Width()/2-30,rect.Height()/2,"注 意");
pDC->TextOut(rect.Width()/2-50,rect.Height()/2+20,"程序只提供2维的图形");
}
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CKDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CKDlg::OnButton1()
{
// TODO: Add your control notification handler code here
UpdateData(true);
CFileDialog filedialog(true);
FILE *file;
if (filedialog.DoModal()==IDOK)
{
filename=filedialog.GetPathName();
}
if (filename!="")
{
check1=true;
file=fopen(filename,"r");
fscanf(file,"%d,",&m_Yang_Num);
fscanf(file,"%d,",&m_Wei_Num);
swatch=new double [m_Yang_Num*m_Wei_Num];
K=new double[m_K*m_Wei_Num];
master=new int[m_Yang_Num];
for(int a=0;a<m_Yang_Num;a++)
{
for(int b=0;b<m_Wei_Num;b++)
{
fscanf(file,"%lf,",&swatch[a*m_Wei_Num+b]);
}
fscanf(file,"\n");
}
fclose(file);
UpdateData(false);
// CKDlg::OnPaint();
}
else
return;
}
void CKDlg::OnOK()
{
// TODO: Add extra validation here
if (filename!="")
{
UpdateData(true);
double m1,m2,*K2,*K3;
int a,b,c;
bool check;
CString str;
if (m_K>m_Yang_Num)
{
MessageBox("K值大于样本数!!");
return;
}
check=true;
check1=true;
K2=new double[m_K*m_Wei_Num];
K3=new double[m_K];
for(a=0;a<m_Yang_Num;a++)
master[a]=0;
for(a=0;a<m_K;a++)
for(b=0;b<m_Wei_Num;b++)
{
K[a*m_Wei_Num+b]=swatch[a*m_Wei_Num+b];
K2[a*m_Wei_Num+b]=0;
}
//////////////////////////////////////////////////
while (check==true)
{
for(a=0;a<m_K;a++)
{
K3[a]=0;
}
for(a=0;a<m_Yang_Num;a++)
{
m1=0;
master[a]=0;
for(c=0;c<m_Wei_Num;c++)
{
m1+=(K[c]-swatch[a*m_Wei_Num+c])*(K[c]-swatch[a*m_Wei_Num+c]);
}
for(b=1;b<m_K;b++)
{
m2=0;
for(c=0;c<m_Wei_Num;c++)
{
m2+=(K[b*m_Wei_Num+c]-swatch[a*m_Wei_Num+c])*(K[b*m_Wei_Num+c]-swatch[a*m_Wei_Num+c]);
}
if (m2<=m1)
{
master[a]=b;
m1=m2;
}
}
}
for(a=0;a<m_Yang_Num;a++)
{
for(b=0;b<m_Wei_Num;b++)
{
K2[master[a]*m_Wei_Num+b]+=swatch[a*m_Wei_Num+b];
}
K3[master[a]]++;
}
for(a=0;a<m_K;a++)
{
for(b=0;b<m_Wei_Num;b++)
{
K2[a*m_Wei_Num+b]/=(K3[a]*1.0);
}
}
check=false;
for(a=0;a<m_K&&check==false;a++)
{
for(b=0;b<m_Wei_Num;b++)
if (K[a*m_Wei_Num+b]!=K2[a*m_Wei_Num+b])
{
check=true;
break;
}
else
check=false;
}
if (check==true)
{
for(a=0;a<m_K;a++)
{
for(b=0;b<m_Wei_Num;b++)
{
if (K3[a]!=0)
K[a*m_Wei_Num+b]=K2[a*m_Wei_Num+b];
K2[a*m_Wei_Num+b]=0;
}
}
}
}
/////////////将计算的结果写入文件中/////////////
FILE *filewrite;
filewrite=fopen("result.txt","w");
for(a=0;a<m_K;a++)
{
str.Format("第 %d 类的聚类中心为:",a+1);
fprintf(filewrite,str);
for(int i=0;i<m_Wei_Num;i++)
{
str.Format("%f ",K[a*m_Wei_Num+i]);
fprintf(filewrite,str);
}
fprintf(filewrite,"成员为:");
fprintf(filewrite,"\n");
for(b=0;b<m_Yang_Num;b++)
{
if (master[b]==a)
{
str.Format("第 %d 号样本:",b+1);
fprintf(filewrite,str);
for(c=0;c<m_Wei_Num;c++)
{
str.Format("%f ",swatch[b*m_Wei_Num+c]);
fprintf(filewrite,str);
}
fprintf(filewrite,"\n");
}
}
}
fclose(filewrite);
delete K2;
delete K3;
}
else
MessageBox("样本还没有载入!!!");
CKDlg::OnPaint();
}
void CKDlg::OnButton2()
{
if (filename!="")
{
::ShellExecute(NULL,"open","C:\\windows\\Notepad.exe","result.txt",NULL,SW_SHOWNORMAL);
}
else if (filename=="")
{
MessageBox("样本还没有载入!!!");
}
CKDlg::OnPaint();
}
void CKDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
if(filename!=""&&check1==true&&AfxMessageBox("保存计算结果吗?",MB_YESNO)==IDYES)
{
FILE *filewrite;
CFileDialog filedialog(false);
CString str;
if (filedialog.DoModal()==IDOK)
{
str=filedialog.GetFileName();
}
if (str=="")
{
return;
}
filewrite=fopen(str+".txt","w");
for(int a=0;a<m_K;a++)
{
str.Format("第 %d 类的聚类中心为:",a+1);
fprintf(filewrite,str);
for(int i=0;i<m_Wei_Num;i++)
{
str.Format("%f ",K[a*m_Wei_Num+i]);
fprintf(filewrite,str);
}
fprintf(filewrite,"成员为:");
fprintf(filewrite,"\n");
for(int b=0;b<m_Yang_Num;b++)
{
if (master[b]==a)
{
str.Format("第 %d 号样本:",b+1);
fprintf(filewrite,str);
for(int c=0;c<m_Wei_Num;c++)
{
str.Format("%f ",swatch[b*m_Wei_Num+c]);
fprintf(filewrite,str);
}
fprintf(filewrite,"\n");
}
}
}
fclose(filewrite);
}
CDialog::OnClose();
}
void CKDlg::OnButton3()
{
// TODO: Add your control notification handler code here
if (filename!="")
{
::ShellExecute(NULL,"open","C:\\windows\\Notepad.exe",filename,NULL,SW_SHOWNORMAL);
CKDlg::OnPaint();
}
else
MessageBox("请先载入样本!");
CKDlg::OnPaint();
}
void CKDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CKDlg::OnPaint();
CDialog::OnMouseMove(nFlags, point);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -