kmean是常用的聚类算法之一主要步骤为:
1.读如点数据,随机选取k个点成为最后要聚的类数目;
2.求剩下的点到这k个点的距离,取最小值,按点的距离聚成一类;
3算同一类中点的质心坐标,即x,y的平均值作为中心点,
4求个点到这中心点的距离,按距离再进行聚类;
5迭代求中心,再聚类;
6当中心点变化在相邻两次迭代的变化数值小与某一范围时停止迭代
7用OpenGL,VTK等可视化软件显示点的分布;
#include<stdio.h> #include<stdlib.h> #include<math.h> #include <time.h> #include "vtkSphereSource.h" #include "vtkPolyDataMapper.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkCamera.h" #include "vtkActor.h" #include "vtkRenderer.h" #include "vtkPolyData.h" #include "vtkBoxWidget.h" #include "vtkCardinalSpline.h" #include "vtkPoints.h" #include "stdio.h" #include <time.h> #include <vtkGlyph3D.h> #include <vtkProperty.h> #include <vtkCellArray.h> #include <vtkTubeFilter.h> #include <vtkPolyLine.h> class dian///点类 { public: double x; double y; }; dian dianji[150]; dian zhongxin[3]; int findmin(double *juli)//找最小距离 { int minnum=0; if (juli[0] > juli[1]) { minnum = 1; if (juli[1] > juli[2]) { minnum = 2; } } else { if (juli[0] > juli[2]) { minnum = 2; } } return minnum; } int findminkguancha(int *kguanchadian,dian shuru)//算距离 { double juli[3]; int kdiannum; juli[0] = abs(shuru.x*shuru.x + shuru.y*shuru.y - dianji[kguanchadian[0]].x*dianji[kguanchadian[0]].x - dianji[kguanchadian[0]].y*dianji[kguanchadian[0]].y); juli[1] = abs(shuru.x*shuru.x + shuru.y*shuru.y - dianji[kguanchadian[1]].x*dianji[kguanchadian[1]].x - dianji[kguanchadian[1]].y*dianji[kguanchadian[1]].y); juli[2] = abs(shuru.x*shuru.x + shuru.y*shuru.y - dianji[kguanchadian[2]].x*dianji[kguanchadian[2]].x - dianji[kguanchadian[2]].y*dianji[kguanchadian[2]].y); kdiannum = findmin(juli); return kdiannum; } void findzhongxin(int* juleibaochun, int leidianshu,int k)//找中心点 { double zhongxinX,zhongxinY ; double zhongX, zhongY; zhongX = zhongY = zhongxinY = zhongxinX = 0; for (int i = 0; i < leidianshu; i++) { zhongX = zhongX + dianji[juleibaochun[i]].x; zhongY = zhongY + dianji[juleibaochun[i]].y; } zhongxinX = zhongX / leidianshu; zhongxinY = zhongY / leidianshu; zhongxin[k].x = zhongxinX; zhongxin[k].y = zhongxinY; } int findminkguancha2( dian shuru)//找中心点 { double juli[3]; int kdiannum; juli[0] = abs(shuru.x*shuru.x + shuru.y*shuru.y - zhongxin[0].x*zhongxin[0].x - zhongxin[0].y*zhongxin[0].y); juli[1] = abs(shuru.x*shuru.x + shuru.y*shuru.y - zhongxin[1].x*zhongxin[1].x - zhongxin[1].y*zhongxin[1].y); juli[2] = abs(shuru.x*shuru.x + shuru.y*shuru.y - zhongxin[2].x*zhongxin[2].x - zhongxin[2].y*zhongxin[2].y); kdiannum = findmin(juli); return kdiannum; } void main() { int kguanchadian[3]; int juleibaochun[3][150]; int leidianshu[3] = {
0}; for (int i1 = 0; i1 < 150; i1++) { dianji[i1].x = rand() % 150; dianji[i1].y = rand() % 150; } for (int i2 = 0; i2 < 3; i2++) { kguanchadian[i2] = rand() % 150; } for (int i3 = 0; i3 < 150; i3++) { int temp; temp = findminkguancha(kguanchadian, dianji[i3]); juleibaochun[temp][leidianshu[temp]] = i3; leidianshu[temp]++; } findzhongxin(juleibaochun[0], leidianshu[0], 0); findzhongxin(juleibaochun[1], leidianshu[1], 1); findzhongxin(juleibaochun[2], leidianshu[2], 2); printf("第1次点集中心\n"); for (int i4 = 0; i4 < 3; i4++) { printf("点集%d中心\n",i4+1); printf("x:%lf,y:%lf\n", zhongxin[i4].x, zhongxin[i4].y); } for (int i5 = 0; i5 <20 ; i5++) { int juleibaochun2[3][150]; int leidianshu2[3] = { 0 }; for (int j = 0; j < 150; j++) { int temp; temp = findminkguancha2(dianji[j]); juleibaochun2[temp][leidianshu2[temp]] = j; leidianshu2[temp]++; } findzhongxin(juleibaochun2[0], leidianshu2[0], 0); findzhongxin(juleibaochun2[1], leidianshu2[1], 1); findzhongxin(juleibaochun2[2], leidianshu2[2], 2); printf("第%d次点集中心\n",i5+2); for (int p = 0; p < 3; p++) { printf("点集%d中心\n", p+1); printf("x:%lf,y:%lf\n", zhongxin[p].x, zhongxin[p].y); } if (i5 == 19) { //hwnd = GetConsoleWindow(); //hdc = GetDC(hwnd); printf("点集一包含的元素\n"); for (int q = 0; q < leidianshu2[0]; q++) { printf("元素%d,x:%lf,y:%lf\n", q+1, dianji[juleibaochun2[0][q]].x, dianji[juleibaochun2[0][q]].y); //SetPixel(hdc, dianji[juleibaochun2[0][q]].x, dianji[juleibaochun2[0][q]].y, 1);; } printf("\n"); printf("\n"); printf("点集二包含的元素\n"); for (int q1 = 0; q1 < leidianshu2[1]; q1++) { printf("元素%d,x:%lf,y:%lf\n", q1+1, dianji[juleibaochun2[1][q1]].x, dianji[juleibaochun2[1][q1]].y); } printf("\n"); printf("\n"); printf("点集三包含的元素\n"); for (int q2 = 0; q2 < leidianshu2[2]; q2++) { printf("元素%d,x:%lf,y:%lf\n", q2 + 1, dianji[juleibaochun2[2][q2]].x, dianji[juleibaochun2[2][q2]].y); } ////////////////////////下面主要是画图 vtkRenderer *ren = vtkRenderer::New(); vtkRenderWindow *renWindow = vtkRenderWindow::New(); renWindow->AddRenderer(ren); renWindow->SetSize(600, 600); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); iren->SetRenderWindow(renWindow); vtkPoints *inputPoints0 = vtkPoints::New(); for (int q4 = 0; q4 < leidianshu2[0]; q4++) { inputPoints0->InsertPoint(q4, dianji[juleibaochun2[0][q4]].x, dianji[juleibaochun2[0][q4]].y, 0); } vtkPolyData *inputData0 = vtkPolyData::New(); inputData0->SetPoints(inputPoints0); vtkSphereSource *balls0 = vtkSphereSource::New(); balls0->SetRadius(1); balls0->SetPhiResolution(10); balls0->SetThetaResolution(10); vtkGlyph3D *glyphPoints0 = vtkGlyph3D::New(); glyphPoints0->SetInput(inputData0); glyphPoints0->SetSource(balls0->GetOutput()); vtkPolyDataMapper *glyphMapper0 = vtkPolyDataMapper::New(); glyphMapper0->SetInputConnection(glyphPoints0->GetOutputPort()); vtkActor *glyph0 = vtkActor::New(); glyph0->SetMapper(glyphMapper0); glyph0->GetProperty()->SetDiffuseColor(1, 0, 0); glyph0->GetProperty()->SetSpecular(3); glyph0->GetProperty()->SetSpecularPower(30); /////////////////////////////////////////////////////// vtkPoints *inputPoints1 = vtkPoints::New(); for (int q5 = 0; q5 < leidianshu2[1]; q5++) { inputPoints1->InsertPoint(q5, dianji[juleibaochun2[1][q5]].x, dianji[juleibaochun2[1][q5]].y, 0); } vtkPolyData *inputData1 = vtkPolyData::New(); inputData1->SetPoints(inputPoints1); vtkSphereSource *balls1 = vtkSphereSource::New(); balls1->SetRadius(1); balls1->SetPhiResolution(10); balls1->SetThetaResolution(10); vtkGlyph3D *glyphPoints1 = vtkGlyph3D::New(); glyphPoints1->SetInput(inputData1); glyphPoints1->SetSource(balls1->GetOutput()); vtkPolyDataMapper *glyphMapper1 = vtkPolyDataMapper::New(); glyphMapper1->SetInputConnection(glyphPoints1->GetOutputPort()); vtkActor *glyph1 = vtkActor::New(); glyph1->SetMapper(glyphMapper1); glyph1->GetProperty()->SetDiffuseColor(0, 1, 0); glyph1->GetProperty()->SetSpecular(3); glyph1->GetProperty()->SetSpecularPower(30); //////////////////////////////////////////// vtkPoints *inputPoints2 = vtkPoints::New(); for (int q6 = 0; q6 < leidianshu2[2]; q6++) { inputPoints2->InsertPoint(q6, dianji[juleibaochun2[2][q6]].x, dianji[juleibaochun2[2][q6]].y, 0); } vtkPolyData *inputData2 = vtkPolyData::New(); inputData2->SetPoints(inputPoints2); vtkSphereSource *balls2 = vtkSphereSource::New(); balls2->SetRadius(1); balls2->SetPhiResolution(10); balls2->SetThetaResolution(10); vtkGlyph3D *glyphPoints2 = vtkGlyph3D::New(); glyphPoints2->SetInput(inputData2); glyphPoints2->SetSource(balls2->GetOutput()); vtkPolyDataMapper *glyphMapper2 = vtkPolyDataMapper::New(); glyphMapper2->SetInputConnection(glyphPoints2->GetOutputPort()); vtkActor *glyph2 = vtkActor::New(); glyph2->SetMapper(glyphMapper2); glyph2->GetProperty()->SetDiffuseColor(0, 0, 2); glyph2->GetProperty()->SetSpecular(3); glyph2->GetProperty()->SetSpecularPower(30); //////////////////////////////////////////// ren->AddActor(glyph0); ren->AddActor(glyph1); ren->AddActor(glyph2); iren->Initialize(); renWindow->Render(); iren->Start(); } } }
讯享网
这里主要用了vtk来显示结果;
结果为

讯享网


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/125009.html