📄 dbscan from zealotdlg.cpp
字号:
// dbscan from zealotDlg.cpp : implementation file
//
///////////////////////
///////////////////////
#include "stdafx.h"
#include "dbscan from zealot.h"
#include "dbscan from zealotDlg.h"
#include "finalPaint.h"
#include "finalPaint2.h"
#include <list>//跟queue有关
#include <iostream>
#include <queue>
#include <deque>
#include <stdlib.h>
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App Abou
////////////////
using namespace std ;//不熟悉,可能会有问题,跟queue有关
class Time
{
private :
int Initialized;
__int64 Frequency;
__int64 BeginTime;
public :
Time()
{
Initialized = QueryPerformanceFrequency( (LARGE_INTEGER *)&Frequency );
}
BOOL Begin()
{
if( ! Initialized )
return 0;
return QueryPerformanceCounter( (LARGE_INTEGER *)&BeginTime );
}
double End()
{
if( ! Initialized )
return 0.0;
__int64 endtime;
QueryPerformanceCounter( (LARGE_INTEGER *)&endtime );
__int64 elapsed = endtime - BeginTime;
return (double)elapsed / (double)Frequency;
}
BOOL Available()
{ return Initialized; }
__int64 GetFreq()
{ return Frequency; }
};
typedef struct {
int x;
int y;
}point;
// Using queue with list
typedef list<int > INTLIST;
typedef queue<int> INTQUEUE;
/////////////////////////////////////////////函数原型定义
void expand(int,int);
//void create(basicNode **) ;//引用参数传递,无法写成void create(basicNode &),可能会有错!
int downfind(linkNode **);
//basicNode * getnext(void);//类内定义
void entag(int,int);
//void paint(int,int,int);
basicNode *crNode(int,int);
float distance(int,int);
//////////////////////////////////////////////////////////////
Time timer;/////
double timerUsed;
basicNode graphTable[TOTAL];
int i;
int j;
int count1=-1;
int id1=0;
int TOTALr=TOTAL;
basicNode *seed;
FILE *f;
long colorArray[20]={0x550000,0xff0000,0x005500,0x000055,0x0000ff,0x00ff00,0x0000aa,0xaa0000,0x00aa00,0x000000,
0xffa000,0xffff00,0x00ffff,0xff00ff,0x555500,0x005555,0x550055,0x88ff33,0x3493af,0x9f6526
};
//////////////////////////////////////////////////////////////
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()
/////////////////////////////////////////////////////////////////////////////
// CDbscanfromzealotDlg dialog
CDbscanfromzealotDlg::CDbscanfromzealotDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDbscanfromzealotDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDbscanfromzealotDlg)
// 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);
}
void CDbscanfromzealotDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDbscanfromzealotDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDbscanfromzealotDlg, CDialog)
//{{AFX_MSG_MAP(CDbscanfromzealotDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDCrun, OnCrun)
ON_BN_CLICKED(IDpaint, Onpaint)
ON_BN_CLICKED(IDquit, Onquit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDbscanfromzealotDlg message handlers
BOOL CDbscanfromzealotDlg::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
///////////////////////////////////
m_strConnection=_T("Provider=MSDASQL;Data Source=sxdb");
m_ctrCmdText=_T("select * from Table1");
m_pRs=NULL;
m_piAdoRecordBinding=NULL;
::CoInitialize(NULL);
m_pRs.CreateInstance(__uuidof(Recordset));
//Recordset->没有自动提示,可能问题
m_pRs->Open((LPCTSTR)m_ctrCmdText,(LPCTSTR)m_strConnection,adOpenDynamic,adLockOptimistic,adCmdUnknown);
m_pRs->QueryInterface(__uuidof(IADORecordBinding),(LPVOID *)&m_piAdoRecordBinding);
m_piAdoRecordBinding->BindToRecordset(&m_rsRecSet);//m_piAdoRecordBinding->没有自动提示,可能问题
//有两行代码未加上,可能问题
m_pRs->MoveFirst();
///////////////////////////////////
return TRUE; // return TRUE unless you set the focus to a control
}
void CDbscanfromzealotDlg::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 CDbscanfromzealotDlg::OnPaint()
{/////////////////////画图的初始化代码写在以下
int x1,y1;
CClientDC paintDC(this);
for(x1=300;x1<400;x1++) paintDC.SetPixel(x1,300,0x000000);//画出两条坐标轴
for(y1=300;y1>200;y1--) paintDC.SetPixel(300,y1,0x000000);
for(x1=900;x1<1000;x1++) paintDC.SetPixel(x1,300,0x000000);//画出两条坐标轴
for(y1=300;y1>200;y1--) paintDC.SetPixel(900,y1,0x000000);
m_pRs->MoveFirst();
int tempx,tempy;
for(i=0;i<=(TOTAL-1);i++)
{ tempx=m_rsRecSet.m_x;
tempy=m_rsRecSet.m_y;
m_pRs->MoveNext();
paintDC.SetPixel(300+tempx,300-tempy,0x000000);//画出原点阵,黑色
paintDC.SetPixel(300+tempx+1,300-tempy,0x000000);
paintDC.SetPixel(300+tempx,300-tempy+1,0x000000);
paintDC.SetPixel(300+tempx-1,300-tempy,0x000000);
paintDC.SetPixel(300+tempx,300-tempy-1,0x000000);
}
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 CDbscanfromzealotDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CDbscanfromzealotDlg::OnCrun() //相当于原来的main函数
{timer.Begin();
CClientDC paintDC(this);
basicNode *temp;
basicNode *ttp=graphTable;
basicNode **tttp=&ttp;
create(tttp);
for(i=0;i<=(TOTAL-1);i++)
{if(graphTable[i].coretag==1&&graphTable[i].usedtag==0)
{graphTable[i].original=TRUE;
expand(i,++id1);
}
} //????????????
//可能还有非核心点的id没有标明
for(i=0;i<=(TOTAL-1);i++)
{if(graphTable[i].usedtag==UNDECIDED)
{id1++;
graphTable[i].usedtag=1;
graphTable[i].id=id1;
graphTable[i].original=2;//........画大十字
}
}
timerUsed =timer.End();
CString msg;
msg.Format("%s%f%s","The time is: ",timerUsed,"s");
AfxMessageBox(msg);
}
void CDbscanfromzealotDlg::Onpaint() //在run之后画出聚类后的点阵
{
finalPaint2 newd;
//newd=new finalPaint(this);
int nRet=newd.DoModal();
}
///////////////自定义子函数如下
//////////////////////////////////////////////////////////////
void expand(int seed,int id)
{int temp2=seed;
linkNode *temp3p;
int size_q;
INTQUEUE q;//队列在此定义
entag(seed,id);//seed is int!
graphTable[seed].usedtag=1;
//linkNode **pp;
temp3p=graphTable[temp2].next;
temp2=temp3p->pointIndex;//一般情况下此temp2值会被冲掉
while(temp3p!=NULL)
{//pp=&temp3p;
temp2=downfind(&temp3p); //类似引用参数传递
if(temp2==-1) break;//这里不能将-1换为FALSE
graphTable[temp2].usedtag=1;
q.push(temp2); //
/* q.push(10);
int test=q.front();
q.pop();
test=q.front();
*/
temp3p=temp3p->next;
}
//解决在某核心点k周围的非核心点未被标为k的id的问题,应该在push完核心点后再做处理
int temp5;
for(linkNode *tempp5=graphTable[seed].next;tempp5!=NULL;tempp5=tempp5->next)
{temp5=tempp5->pointIndex;
entag(temp5,id);
graphTable[temp5].usedtag=1;
}
///////////////////////
while(q.empty()!=TRUE)
{temp2=q.front();
q.pop();
expand(temp2,id); //??
}
}
//////////////////////////////////////////////////////////////
void CDbscanfromzealotDlg::create(basicNode **GT) //??????
//这个函数主要用于判断点是否为核心点,先计算点和其他点之间的距离,如果小于eps
//的话,压入栈,到最后计算栈中记录的数目,如果大于minpts,则为核心点
{basicNode *temp;
linkNode *tempNode,*tail;
m_pRs->MoveFirst();
for(i=0;i<=TOTAL-1;i++)
{temp=getnext();
(*GT)[i].coretag=temp->coretag;
(*GT)[i].id=temp->id;
(*GT)[i].nearNum=temp->nearNum;
(*GT)[i].next=temp->next;
(*GT)[i].usedtag=temp->usedtag;
(*GT)[i].x=temp->x;
(*GT)[i].y=temp->y;
}
for(i=0;i<=(TOTAL-1);i++)
{(*GT)[i].nearNum=0;
int check=TRUE;
//tail=&(*GT)[i];
for(j=1;j<=(TOTAL-1);j++) //由于不需把自己链入,故j从1开始
{float tempd=distance(i,j);
if(tempd<=EPS)
{tempNode=(linkNode *)malloc(sizeof(linkNode));;//可能会有问题
tempNode->pointIndex=j;
tempNode->next=NULL;
//int check=TRUE;
if(check==TRUE) //确保tail初始化只进行一次
{(*GT)[i].next=tempNode;//此时(*GT)[i].next为tail
tail=tempNode;
check=FALSE;
}
else
{tail->next=tempNode;//??
tail=tempNode;
}
(*GT)[i].nearNum++;
//int test=(*GT)[i].nearNum++;
}//if()
if((*GT)[i].nearNum>=MinPts)
(*GT)[i].coretag=true;
}
}
}
//////////////////////////////////////////////////////////////
int downfind(linkNode **temp4p)
{int temp;
if((*temp4p)==NULL) return(-1);
temp=(*temp4p)->pointIndex;
while(graphTable[temp].coretag==0||graphTable[temp].usedtag==1)
{(*temp4p)=(*temp4p)->next;
if((*temp4p)==NULL) return(-1);
temp=(*temp4p)->pointIndex;
}
return(temp);
}
basicNode * CDbscanfromzealotDlg::getnext(void)//类内定义
{basicNode *temp;
int tempx,tempy;
count1++;
//试数据库tempx=array[count1].x;
//试数据库tempy=array[count1].y;
tempx=m_rsRecSet.m_x;
tempy=m_rsRecSet.m_y;
m_pRs->MoveNext();
temp=crNode(tempx,tempy);
return (temp);
}
void entag(int temp5,int q)
{graphTable[temp5].id=q;
}
basicNode *crNode(int tempx,int tempy)
{basicNode *tempp;
tempp=(basicNode *)malloc(sizeof(basicNode));;//对否?
tempp->x=tempx;
tempp->y=tempy;
tempp->id=UNDECIDED;//??????id?1??
tempp->nearNum=UNDECIDED;tempp->coretag=UNDECIDED;
tempp->usedtag=UNDECIDED;tempp->next=NULL;
tempp->original=UNDECIDED;//.....
return(tempp);
};//???????
float distance(int i3,int j3)
{int tempi3x,tempi3y,tempj3x,tempj3y;
float d3;
tempi3x=graphTable[i3].x;
tempi3y=graphTable[i3].y;
tempj3x=graphTable[j3].x;
tempj3y=graphTable[j3].y;
d3=sqrt((tempj3x-tempi3x)*(tempj3x-tempi3x)+(tempj3y-tempi3y)*(tempj3y-tempi3y));
return(d3);
}
void CDbscanfromzealotDlg::Onquit()
{
// TODO: Add your control notification handler code here
}
BEGIN_EVENTSINK_MAP(CDbscanfromzealotDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CDbscanfromzealotDlg)
ON_EVENT(CDbscanfromzealotDlg, IDC_ADODC1, 200 /* WillMove */, OnWillMoveAdodc1, VTS_I4 VTS_PI4 VTS_DISPATCH)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
void CDbscanfromzealotDlg::OnWillMoveAdodc1(long adReason, long FAR* adStatus, LPDISPATCH pRecordset)
{
// TODO: Add your control notification handler code here
}
CDataRecord * CDbscanfromzealotDlg::GetRecSet()
{return &m_rsRecSet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -