📄 fcmdlg.cpp
字号:
// FCMDlg.cpp : implementation file
//
#include "stdafx.h"
#include "FCM.h"
#include "FCMDlg.h"
#include <time.h>
#include <math.h>
#include <stdlib.h>
//#include <stdio.h>
#include <string.h>
#include <memory.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//const MAX_NUM=5000;
const MAX_RAND=0x7fff;
//const double PI=3.1415926;
//const MAX_PATTERN=1000;
//const MAX_CATA=10;
//const MAX_DIMENSION=10;
const SIZE1=10;
#define FILE_PARAMS_IN "paramOut.txt";
#define FILE_DATA_IN "datain.txt";
#define FILE_MATRIX "matrix.txt";
#define FILE_CENTER "center.txt";
#define FILE_PARAMS_OUT "process.txt";
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
double objectfun(double *,double *,double *,int,int,int,float);
inline double distance(double v1[],double v2[],double dimension)
//这个函数计算欧氏距离
{
int i;
double result;
result=0;
for(i=0;i<dimension;i++){
result+=(v1[i]-v2[i])*(v1[i]-v2[i]);
}
result=sqrt(result);
return result;
}
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()
/////////////////////////////////////////////////////////////////////////////
// CFCMDlg dialog
CFCMDlg::CFCMDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFCMDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CFCMDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
nProcess=0;
dDelta=1000;
}
void CFCMDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFCMDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFCMDlg, CDialog)
//{{AFX_MSG_MAP(CFCMDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFCMDlg message handlers
BOOL CFCMDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetTimer(1,100,NULL);
BeginFCM();
KillTimer(1);
// 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
CDialog::OnOK();
return TRUE; // return TRUE unless you set the focus to a control
}
void CFCMDlg::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 CFCMDlg::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();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CFCMDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
int CFCMDlg::funfcm(double adi_pattern[],int n_dimension,int n_numpattern,int n_catacount,float f_weightm,int n_maxcycle,double d_threshold,double ado_matrixu[],double ado_center[],double d_funj)
// 本函数完成FCM聚类算法
//参数分为三组:基本聚类样本的信息、算法的参数信息、算法控制信息、输出信息。
//其中:
//adi_pattern[]为样本点向量 指标为:样本指标*维数+维数指标
//n_dimension是每个样本的维数
//n_numpattern是样本的个数
//***************关于上面三个参数的说明***********
//adi_pattern[]为一维数组,它的数目由n_dimension*n_numpattern确定
//************************************************
//n_catacount是要分类的数目
//f_weightm是fcm的重要控制参数m
//n_maxcycle是最大循环次数
//d_threshold为算法结束迭代的阈值
//ado_matrixu[]为输出的划分矩阵 指标为:聚类指标*样本数+样本指标
//ado_center[]为输出的样本的聚类中心向量 指标为:据类指标*维数+维数指标
//d_funj为目标函数的值
{
int j,i,k,t,count;
int n_cycle;
int n_selnum;
int flagtemp;
double f_temp,lastv,delta,t_temp;
double v1[SIZE1];
double v2[SIZE1];
double min_dis=0.001;//距离的最小值
//验证输入参数的有效性:
if(n_catacount>=n_numpattern||f_weightm<=1){
return 1;
}
srand( (unsigned)time( NULL ) );
//随机的选取初始迭代点作为初始的聚类中心。
for(j=0;j<n_catacount;j++){
t_temp=rand();
t_temp/=MAX_RAND;
//ado_center[j]=t_temp;
n_selnum=int(rand()*n_numpattern/(n_catacount*MAX_RAND)+j*int(n_numpattern/n_catacount));
n_selnum=j*int(n_numpattern/n_catacount);
while(n_selnum*n_dimension>n_numpattern*n_dimension){
n_selnum-=n_numpattern;
}
for(i=0;i<n_dimension;i++){
ado_center[j*n_dimension+i]=adi_pattern[n_selnum*n_dimension+i];
}
}
//ado_center[0]=0;ado_center[1]=1;
//ado_center[2]=2;ado_center[3]=2;
//开始主循环
n_cycle=0;
lastv=0;
do{
//计算划分矩阵
for(i=0;i<n_numpattern;i++){
flagtemp=0;
count=0;
for(j=0;j<n_catacount;j++){
f_temp=0;
for(t=0;t<n_catacount;t++){
for(k=0;k<n_dimension;k++){
v1[k]=adi_pattern[i*n_dimension+k];
v2[k]=ado_center[t*n_dimension+k];
}
if (distance(v1,v2,n_dimension)>min_dis){
f_temp+=pow(distance(v1,v2,n_dimension),-2/(f_weightm-1));
}else{
flagtemp=1;
}
}
for(k=0;k<n_dimension;k++){
v1[k]=adi_pattern[i*n_dimension+k];
v2[k]=ado_center[j*n_dimension+k];
}
if(flagtemp==1){
ado_matrixu[j*n_numpattern+i]=0;
flagtemp=0;
}
//如果存在使得||Xk-Vi||=0的点置标志-1
if(distance(v1,v2,n_dimension)>min_dis){
double shit1=distance(v1,v2,n_dimension);
double shit2=pow(shit1,-2/(f_weightm-1))/f_temp;
int shit3=j*n_numpattern+i;
ado_matrixu[shit3]=shit2;
}else{
count++;
ado_matrixu[j*n_numpattern+i]=-1;
}
}//end for j
// 如果存在使得||Xk-Vi||=0就让所有的与Xk不为零的类的隶属度为零。
if(count>0){
for(j=0;j<n_catacount;j++){
if(ado_matrixu[j*n_numpattern+i]==-1){
ado_matrixu[j*n_numpattern+i]=1/double(count);
}else{
ado_matrixu[j*n_numpattern+i]=0;
}
}
}
}//end for i
f_temp=objectfun(ado_matrixu,ado_center,adi_pattern,n_catacount,n_numpattern,n_dimension,f_weightm);
delta=fabs(f_temp-lastv);
lastv=f_temp;
//计算聚类中心的坐标
for(i=0;i<n_catacount;i++){
for(j=0;j<n_dimension;j++){
f_temp=0;
for(k=0;k<n_numpattern;k++){
f_temp+=pow(ado_matrixu[i*n_numpattern+k],f_weightm)*adi_pattern[k*n_dimension+j];
}
ado_center[i*n_dimension+j]=f_temp;
f_temp=0;
for(k=0;k<n_numpattern;k++){
f_temp+=pow(ado_matrixu[i*n_numpattern+k],f_weightm);
}
ado_center[i*n_dimension+j]/=f_temp;
}
}
n_cycle++;
nProcess=n_cycle;
dDelta=delta;
}while(n_cycle<n_maxcycle&&delta>d_threshold);
return 0;
}
double objectfun(double u[],double v[],double x[],int c,int pattern,int dimension,float m){
//此函数计算优化的目标函数
int i,j,k;
double v1[SIZE1];
double v2[SIZE1];
double object;
object=0;
for(i=0;i<c;i++){
for(j=0;j<pattern;j++){
for(k=0;k<dimension;k++){
v1[k]=x[j*dimension+k];
v2[k]=v[i*dimension+k];
}
object+=pow(u[i*pattern+j],m)*distance(v1,v2,dimension)*distance(v1,v2,dimension);
}
}
return object;
}
void CFCMDlg::BeginFCM()
{
double result=0;
double * pattern;
float m,limit;
int numpattern,dimension,cata,maxcycle;
float readdata;
FILE * stream;
FILE * parafile;
double* umatrix;
double* rescenter;
//获得程序的当前路径
char strCurPath[200];
//memset(pattern,0,MAX_PATTERN*MAX_DIMENSION);
//memset(umatrix,0,MAX_CATA*MAX_DIMENSION);
DWORD dwSize = ::GetModuleFileName(AfxGetApp()->m_hInstance,strCurPath,200);
strCurPath[dwSize] = 0;
char* p = strrchr(strCurPath,'\\');
*p = 0;
sCurPath=CString(strCurPath);
//设定参数的初值
numpattern=0; //样本点个数
dimension=0; //每个样本点的维数
cata=8; //要聚类的数目
maxcycle=1000; //最大的跌代次数
m=2; //参数m
limit=float(0.1); //误差限
//从参数文件中读取参数的值
CString filePath=CString(strCurPath)+"\\"+FILE_PARAMS_IN;
char read[20];
if((parafile=fopen(filePath,"r"))!=NULL){
fscanf(parafile,"%s\n",&read);
numpattern=atoi(read);
fscanf(parafile,"%s\n",&read);
dimension=atoi(read);
fscanf(parafile,"%s\n",&read);
cata=atoi(read);
fscanf(parafile,"%s\n",&read);
m=float(atof(read));
fscanf(parafile,"%s\n",&read);
maxcycle=atoi(read);
fscanf(parafile,"%s\n",&read);
limit=float(atof(read));
fclose(parafile);
}
pattern=new double[numpattern*dimension];
umatrix=new double[numpattern*cata];
rescenter=new double[cata*dimension];
if(pattern==0||umatrix==0||rescenter==0){
return;
}
//从文件中读出原始数据pattern为样本点的坐标
filePath=CString(strCurPath)+"\\"+FILE_DATA_IN;
int t;
if((stream=fopen(filePath,"r"))!=NULL){
fseek(stream,0L,SEEK_SET);
for(t=0;t<numpattern*dimension;t++){
fscanf(stream,"%f,",&readdata);
//printf("%f\n",readdata);
pattern[t]=readdata;
}
fclose(stream);
}
funfcm(pattern,dimension,numpattern,cata,m,maxcycle,limit,umatrix,rescenter,result);
delete [numpattern*dimension] pattern;
filePath=CString(strCurPath)+"\\"+FILE_MATRIX;
if((stream=fopen(filePath,"w"))!=NULL){
for(int j=0;j<numpattern;j++){
for(int i=0;i<cata;i++){
fprintf(stream,"%4f,",umatrix[i*numpattern+j]);
}
fprintf(stream,"\n");
}
fclose(stream);
}
filePath=CString(strCurPath)+"\\"+FILE_CENTER;
if((stream=fopen(filePath,"w"))!=NULL){
for(int i=0;i<cata;i++){
for(int j=0;j<dimension;j++){
fprintf(stream,"%4f,",rescenter[i*dimension+j]);
}
fprintf(stream,"\n");
}
fclose(stream);
}
}
//DEL int CFCMDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
//DEL {
//DEL if (CDialog::OnCreate(lpCreateStruct) == -1)
//DEL return -1;
//DEL
//DEL // TODO: Add your specialized creation code here
//DEL return 0;
//DEL }
void CFCMDlg::OnOK()
{
// TODO: Add extra validation here
CDialog::OnOK();
}
void CFCMDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
FILE *stream;
CString filePath=sCurPath+"\\"+FILE_PARAMS_OUT;
if((stream=fopen(filePath,"w"))!=NULL){
fprintf(stream,"%i\n",nProcess);
fprintf(stream,"%4f\n",dDelta);
fclose(stream);
}
CDialog::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -