MFC对话框实现模糊c均值聚类算法
来源:互联网 发布:java extends super 编辑:程序博客网 时间:2024/06/05 17:16
程序非常简单,作为当初我的第一个MFC程序,有纪念意义。程序最终界面:
一、问题:在MFC对话框界面输入任意类别和任意数目的样本进行C分类,并进行显示。
二、c均值聚类算法
1、c—平均算法
对一批没有标明类别及类数的模式样本集,根据模式间的相似程度,按照物以类聚、人以群分的思想,将相似的模式分为一类,不相似的分为另一类。c均值聚类算法根据欧式距离把最短距离的样本分为1类。
动态聚类框图
① 先选定某种距离作为样本间的相似性的度量;
② 确定评价聚类结果的准则函数;
③ 给出某种初始分类,用迭代法找出使准则函数取极值的最好的聚类结果。
2、算法步骤
① 根据输入的分类数和样本总数,生成坐标范围内的随机数
② 初始聚类中心
③ 根据欧式距离进行一次分类
④ 根据新分成的两建立新的聚类中心
⑤ 新旧聚类中心不等则转回③,相等结束计算
⑥ 绘图显示结果
三、动态存储点坐标的数据结构
由于要求输入任意类别和任意数目样本,所以存放数据不能放在一般的数组(因为必须进行初始化,不然编译不过)。而每个样本数据有几个特征,所以它实际是一个第一维未知、第二维已知(如这里的x,y坐标)的动态数组。有几种方法:
① 用new[]定义一个一维动态数组指针(结构体对象指针),在程序运行时按界面输入样本多少分配内存。第二维的样本特征可以用个结构体,如:
struct mypoint
{
int x;
int y;
int myclass;//类别
};
mypoint* ptr=new mypoint[num];
②用自带的cpoint类自己定义一个坐标对象,用new[]定义一个相应对象的一维数组指针
③容器。我另一个程序的一部分:
class CModel
{
public:
CModel();
virtual ~CModel();
int class_num; //样本数目
int value[3]; //第二维样本特征
};
struct sq
{
int xclass;
int ysq;
};
vector<sq>vec_p(classnum+2);
vector<CModel> vec_point(num);
vector<CModel>::size_type vector_size=num;
for (vector<CModel>::size_type it = (v-1)*num/classnum; it != v*num/classnum; ++it)
{……}
④定义个动态二维数组,第二维已知。比如我们一般的用法:
char (*a)[N];//指向数组的指针
a = new char[m][N];
delete[] a;
四、程序实现
① cmathDlg.h
#pragma once#include <vector>// CcmathDlg 对话框class CcmathDlg : public CDialog{// 构造public:CcmathDlg(CWnd* pParent = NULL);// 标准构造函数void DrawOnMem();double random(double start, double end);// 对话框数据enum { IDD = IDD_CMATH_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持// 实现protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()public:afx_msg void OnBnClickedOk();int num;int classnum;vector<int> vec_point;};struct mypoint{int x;int y;int myclass;};struct myxy{int x;int y;int k;};
②cmathDlg.cpp
// cmathDlg.cpp : 实现文件//#include "stdafx.h"#include "cmath.h"#include "cmathDlg.h"#include "Resource.h"#include"time.h"#include "math.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// CcmathDlg 对话框CcmathDlg::CcmathDlg(CWnd* pParent /*=NULL*/): CDialog(CcmathDlg::IDD, pParent), num(0), classnum(0){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CcmathDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);DDX_Text(pDX, IDC_EDIT1, num);DDV_MinMaxInt(pDX, num, 2, 100);DDX_Text(pDX, IDC_EDIT2, classnum);DDV_MinMaxInt(pDX, classnum, 2, 100);}BEGIN_MESSAGE_MAP(CcmathDlg, CDialog)ON_WM_PAINT()ON_WM_QUERYDRAGICON()//}}AFX_MSG_MAPON_BN_CLICKED(IDOK, &CcmathDlg::OnBnClickedOk)END_MESSAGE_MAP()// CcmathDlg 消息处理程序BOOL CcmathDlg::OnInitDialog(){CDialog::OnInitDialog();// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动// 执行此操作SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标// TODO: 在此添加额外的初始化代码return TRUE; // 除非将焦点设置到控件,否则返回 TRUE}// 如果向对话框添加最小化按钮,则需要下面的代码// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,// 这将由框架自动完成。void CcmathDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中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;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}DrawOnMem();}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CcmathDlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}void CcmathDlg::OnBnClickedOk(){InvalidateRect(NULL,TRUE);UpdateWindow();UpdateData(TRUE);CClientDC dc(this); int x1,x2,y1,y2,m;int p=0;intlg=30; bool f; mypoint* ptr=new mypoint[num];myxy* double_ptr=new myxy[classnum]; myxy* double_ptr1=new myxy[classnum];srand(unsigned(time(0)));ptr[0].x=int(random(0,11));ptr[0].y=int(random(0,11)); ptr[0].myclass=0; for(int icnt = 1; icnt != num; icnt++){ do { f=true; ptr[icnt].x=int(random(0,11)); ptr[icnt].y=int(random(0,11)); for(int j=0;j<icnt;j++) { if(ptr[icnt].x!=ptr[j].x||ptr[icnt].y!=ptr[j].y)continue; if(j=icnt-1) f=false; } }while(f==false); ptr[icnt].myclass=0;} //第一步 for(int icnt = 0; icnt != classnum; icnt++) { double_ptr[icnt].x=ptr[icnt].x; double_ptr[icnt].y=ptr[icnt].y; } double_ptr1=double_ptr; //第二步 do { double_ptr1=double_ptr; for(int icnt = 0; icnt != classnum; icnt++) {double_ptr[icnt].k=0; } for(int i = 0; i!= num; i++) { for(int j = 0; j!= classnum; j++) { m= ptr[i].myclass; ptr[i].myclass=(sqrt((double)((ptr[i].x-double_ptr[m].x)*(ptr[i].x-double_ptr[m].x)+(ptr[i].y-double_ptr[m].y)*(ptr[i].y-double_ptr[m].y)))>sqrt(((double)(ptr[i].x-double_ptr[j].x)*(ptr[i].x-double_ptr[j].x)+(ptr[i].y-double_ptr[j].y)*(ptr[i].y-double_ptr[j].y))))?j:m; } } //第三步 for(int i = 0; i!= num; i++) { for(int j = 0; j!= classnum; j++) { if(ptr[i].myclass==j){ double_ptr[j].x+=ptr[i].x; double_ptr[j].y+=ptr[i].y; double_ptr[j].k++; } } } for(int j = 0; j!= classnum; j++) { if(double_ptr[j].k!=0) {double_ptr[j].x=double_ptr[j].x/double_ptr[j].k; double_ptr[j].y=double_ptr[j].y/double_ptr[j].k; } else { double_ptr[j].x=0; double_ptr[j].y=0; } } ++p; }while(double_ptr1!=double_ptr); for(int i=0; i< num; i++) { x1=20+ptr[i].x*lg-6; x2=20+ptr[i].x*lg+6; y1=360-ptr[i].y*lg+6; y2=360-ptr[i].y*lg-6; switch(ptr[i].myclass) { case 0: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(0,0,255)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } case 1: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(0,255,0)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } case 2: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(255,0,0)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } case 3: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(0,255,255)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } case 4: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(255,0,255)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } case 5: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(255,255,0)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } case 6: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(0,0,0)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } case 7: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(125,125,125)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } case 8: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(125,0,255)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } case 9: { CBrush brush,*oldbrush; brush.CreateSolidBrush(RGB(125,125,255)); oldbrush=dc.SelectObject(&brush); dc.Ellipse(x1,y1,x2,y2); dc.SelectObject(oldbrush); break; } } }}void CcmathDlg::DrawOnMem(){ CString str; int i; CClientDC dc(this); CPen pen(PS_SOLID, 1, RGB(255, 0, 0)); CPen* pOldPen=dc.SelectObject(&pen); dc.MoveTo(20, 20); dc.LineTo(20, 360); dc.LineTo(360, 360); for(i = 0; i <= 10; i ++) { str.Format("%d", i); dc.TextOut(17 + 30 * i, 365, str); dc.MoveTo(i * 30 + 20, 360); dc.LineTo(i * 30 + 20, 355); } str="x轴"; dc.TextOut(350,340,str); for(i = 1; i <= 10; i ++) { str.Format("%d", i); dc.TextOut(2, 360 - 30 * i - 5, str); dc.MoveTo(25, 360 - 30 * i); dc.LineTo(20, 360 - 30 * i); } str="y轴"; dc.TextOut(30,20,str); dc.MoveTo(350, 357); dc.LineTo(360, 360); dc.LineTo(350, 363); dc.MoveTo(17, 30); dc.LineTo(20, 20); dc.LineTo(23, 30); dc.SelectObject(pOldPen);}double CcmathDlg::random(double start, double end){ return start+(end-start)*rand()/(RAND_MAX + 1.0);}
- MFC对话框实现模糊c均值聚类算法
- 模糊C均值聚类算法及实现
- 模糊C均值聚类算法的实现
- FCM 模糊C均值聚类算法
- 模糊C均值聚类算法
- 模糊C均值聚类算法
- python实现 模糊C均值聚类算法(Fuzzy-C-Means)-基于iris数据集
- FCM聚类算法(模糊C均值算法)
- 模糊C均值聚类
- 模糊C均值聚类
- 模糊c均值聚类
- 模糊C均值聚类
- 模糊C均值聚类
- 模糊C均值聚类
- 模糊C均值聚类以及C实现
- 模糊C均值聚类算法(FCM) --…
- 模糊C均值聚类算法(原理+Matlab代码)
- 多核模糊C均值聚类
- Spring+Ibatis集成开发实例
- Servlet 3.0笔记之超方便的文件上传支持
- HBase flush
- SQL中UNION使用实例
- Eclipse 编辑器字体设置(Java/C/C++等均适用)
- MFC对话框实现模糊c均值聚类算法
- git_vs_github入门
- 国嵌——内核驱动——第二天(总线-驱动-设备模型)
- (转)Android Bander设计与实现 - 设计篇
- 【第二弹】OpenGL深入学习之缓冲区
- Java中堆内存和栈内存详解
- 【算法导论】动态规划之矩阵链乘法
- ZOJ 3726 Alice's Print Service 二分+rmq
- 用户/服务器进程概念及v$session/V$PROCESS视图简介