winform的界面搭建比较简单,首先在界面上的左边产生两堆特征值为 0-100的二维样本。通过 c均值聚类及DBSCAN聚类将聚类结果显示在右边。样本点有x和y值,用List<Point>存储一个类。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Text;namespace PatternRecon
{public partial class Form1 : Form{public List<Point> Cluster1=new List<Point>();public List<Point> Cluster2=new List<Point>();public List<Point> afterCluster1 = new List<Point>();public List<Point> afterCluster2 = new List<Point>();public Form1(){InitializeComponent();InitCombo();}public void InitCombo(){this.comboBox1.Items.Add("c均值");this.comboBox1.Items.Add("DBSCAN");//设置默认值this.textBox1.Text = "1";this.textBox2.Text = "12";//设置背景afterCluster1.Clear();afterCluster2.Clear();this.pictureBox1.Image = (DrawCluster(afterCluster1, afterCluster2, false));this.pictureBox2.Image = (DrawCluster(afterCluster1, afterCluster2, false));}//产生随机数种子public static int GetRandomSeed(){byte[] bytes = new byte[4];System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();rng.GetBytes(bytes);return BitConverter.ToInt32(bytes, 0);}//产生标准正太分布public static double[] NormalDistribution(){Random rand = new Random(GetRandomSeed());double[] y;double u1, u2, v1=0, v2=0, s = 0, z1=0, z2=0;while (s > 1 || s == 0){u1 = rand.NextDouble();u2 = rand.NextDouble();v1 = 2 * u1 - 1;v2 = 2 * u2 - 1;s = v1 * v1 + v2 * v2;}z1 = Math.Sqrt(-2 * Math.Log(s) / s) * v1;z2 = Math.Sqrt(-2 * Math.Log(s) / s) * v2;y = new double[] { z1, z2 };return y; //返回两个服从正态分布N(0,1)的随机数z0 和 z1}//确定private void button1_Click(object sender, EventArgs e){if (this.comboBox1.Text == "c均值"){//调用c均值Caverage();this.pictureBox2.Image = (DrawCluster(afterCluster1, afterCluster2,false));}else if (this.comboBox1.Text == "DBSCAN"){//调用DBSCANif (this.textBox1.Text == "" || this.textBox2.Text == ""){MessageBox.Show("请输入DBSCAN值");}else{DBSCAN();this.pictureBox2.Image = (DrawCluster(afterCluster1, afterCluster2, false));}}else{MessageBox.Show("请选择聚类方法!");}}//绘图public Bitmap DrawCluster(List<Point> m1,List<Point> m2,bool flag){Bitmap bmp = new Bitmap(405, 405);Graphics g = Graphics.FromImage(bmp);Pen p = new Pen(Color.Black, 2);Pen linep = new Pen(Color.FromArgb(30, Color.Black), 2);Pen pm1;Pen pm2;if (flag==true){pm1 = new Pen(Color.Red, 2);pm2 = new Pen(Color.Green, 2);}else {pm1 = new Pen(Color.Brown, 2);pm2 = new Pen(Color.Blue, 2);}Point p1 = new Point(400, 0);Point p2 = new Point(400, 400);Point p3 = new Point(0, 400);Point p4 = new Point(400, 400);try{//画线g.Clear(Color.White);g.DrawLine(p, p1, p2);g.DrawLine(p, p3, p4);g.DrawLine(p,new Point(0,0), p1);g.DrawLine(p, new Point(0, 0), p3);g.DrawString("高斯分布随机产生100个样品,特征值取值为0-10", new Font("宋体", 10), new SolidBrush(Color.Black), new PointF(10, 10));for (int i = 1; i <= 9; i++){g.DrawLine(linep, new Point(i * 40, 400), new Point(i * 40, 0));g.DrawLine(linep, new Point(400, i * 40), new Point(0, i * 40));g.DrawString(i.ToString(), new Font("宋体", 10), new SolidBrush(Color.Blue), new PointF(i * 40, 400 - 15));g.DrawString(i.ToString(), new Font("宋体", 10), new SolidBrush(Color.Blue), new PointF(400 - 15, i * 40));}//画点foreach(Point m1Point in m1){g.DrawEllipse(pm1, m1Point.X, m1Point.Y, 2, 2);}foreach (Point m1Point in m2){g.DrawEllipse(pm2, m1Point.X, m1Point.Y, 2, 2);}}catch (Exception ex){MessageBox.Show(ex.Message);}finally{g.Dispose();p.Dispose();pm1.Dispose();pm2.Dispose();linep.Dispose();}return bmp;//描点}//用于产生两个均值public int count = 0;private void pictureBox1_MouseClick(object sender, MouseEventArgs e){count++;// MessageBox.Show(count.ToString());if (count==1){for (int i = 0; i < 50;i++ ){double[] point = NormalDistribution();double x = point[0] +e.X/40;double y = point[1] +e.Y/40;int x1 = (int)(x * 40);int x2 = (int)(y * 40);Cluster1.Add(new Point(x1,x2));}}if (count == 2){for (int i = 0; i < 50; i++){double[] point = NormalDistribution();double x = point[0] + e.X / 40;double y = point[1] + e.Y / 40;int x1 = (int)(x * 40);int x2 = (int)(y * 40);Cluster2.Add(new Point(x1, x2));}this.pictureBox1.Image=(DrawCluster(Cluster1,Cluster2,true));}}//c均值,按照PPT上的步骤写的public void Caverage(){this.afterCluster1.Clear();this.afterCluster2.Clear();//初始化聚类中心List<Point> Cluster=new List<Point>();foreach(Point m1Point in Cluster1){Cluster.Add(m1Point);}foreach(Point m2Point in Cluster2){Cluster.Add(m2Point);}Point C1=Cluster[0];Point C2=Cluster[1];bool flag= true;//判断聚类中心是否相等while (flag){// MessageBox.Show("聚类中心1:" + C1.X.ToString() + " " + C1.Y.ToString() + "聚类中心2:" + C2.X.ToString() + " " + C2.Y.ToString());int N1 = 0;int N2 = 0;int C1x = 0;int C2x = 0;int C1y = 0;int C2y = 0;foreach (Point point in Cluster){int s1 = Math.Abs(point.X - C1.X) + Math.Abs(point.Y - C1.Y);int s2 = Math.Abs(point.X - C2.X) + Math.Abs(point.Y - C2.Y);if(s1<s2){N1++;C1x += point.X;C1y += point.Y;}else{N2++;C2x += point.X;C2y += point.Y;  }}if(C1x/N1==C1.X&&C2.X==C2x/N2&& C1.Y==C1y/N1&& C2.Y==C2y/N2){flag = false;}C1.X=C1x/N1;C2.X=C2x/N2;C1.Y=C1y/N1;C2.Y=C2y/N2;}foreach (Point point in Cluster){int s1 = Math.Abs(point.X - C1.X) + Math.Abs(point.Y - C1.Y);int s2 = Math.Abs(point.X - C2.X) + Math.Abs(point.Y - C2.Y);if (s1 < s2){afterCluster1.Add(point);}else{afterCluster2.Add(point);}}}//DBSCANpublic void DBSCAN(){try{double pow = 2.0;int radius = int.Parse(this.textBox1.Text) * 40;int MinPts = int.Parse(this.textBox2.Text);this.afterCluster1.Clear();this.afterCluster2.Clear();List<Point> Cluster = new List<Point>();List<Point> temp1 = new List<Point>();List<Point> temp2 = new List<Point>();foreach (Point m1Point in Cluster1){Cluster.Add(m1Point);}foreach (Point m2Point in Cluster2){Cluster.Add(m2Point);}Point C1;Point C2;bool isC1Get = false;bool isC2Get = false;foreach (Point mm in Cluster){if (isC1Get == false){int count = 0;//记数temp1.Clear();foreach (Point mm1 in Cluster){double banjing = Math.Sqrt(Math.Pow(mm1.X - mm.X, pow) + Math.Pow(mm1.Y - mm.Y, pow));if (banjing < radius){count++;temp1.Add(mm1);}}if (count >= MinPts){C1 = mm;isC1Get = true;foreach (Point mm2 in temp1){foreach (Point mm3 in Cluster){double banjing = Math.Sqrt(Math.Pow(mm3.X - mm2.X, pow) + Math.Pow(mm3.Y - mm2.Y, pow));if (banjing < radius && (afterCluster1.Contains(mm3) == false)){afterCluster1.Add(mm3);}}}}}else if (isC2Get == false){if (afterCluster1.Contains(mm) == false){int count = 0;//记数temp2.Clear();foreach (Point mm1 in Cluster){double banjing = Math.Sqrt(Math.Pow(mm1.X - mm.X, pow) + Math.Pow(mm1.Y - mm.Y, pow));if (banjing < radius){count++;temp2.Add(mm1);}}if (count >= MinPts){C2 = mm;isC2Get = true;foreach (Point mm2 in temp2){foreach (Point mm3 in Cluster){double banjing = Math.Sqrt(Math.Pow(mm3.X - mm2.X, pow) + Math.Pow(mm3.Y - mm2.Y, pow));if (banjing < radius && (afterCluster1.Contains(mm3) == false) && afterCluster2.Contains(mm3) == false){afterCluster2.Add(mm3);}}}}}else{continue;}}else{break;}}}catch(Exception ex){MessageBox.Show(ex.Message);}}//清除private void button2_Click(object sender, EventArgs e){this.Cluster1.Clear();this.Cluster2.Clear();this.afterCluster1.Clear();this.afterCluster2.Clear();count = 0;Bitmap bmp = new Bitmap(405, 405);Graphics g = Graphics.FromImage(bmp);g.Clear(Color.White);g.Dispose();this.pictureBox1.Image = (DrawCluster(afterCluster1, afterCluster2, false));this.pictureBox2.Image = (DrawCluster(afterCluster1, afterCluster2, false));}//圈出不同,圈的之后注意比较一下中心private void button3_Click(object sender, EventArgs e){Bitmap bmp = (Bitmap)this.pictureBox2.Image;Graphics g = Graphics.FromImage(bmp);Pen p = new Pen(Color.Black,2);int count1 = 0;int count2 = 0;List<Point> belongCluster1;List<Point> belongCluster2;foreach (Point m1Point in Cluster1){if (afterCluster1.Contains(m1Point))count1++;if (afterCluster2.Contains(m1Point))count2++;}if (count1 > count2){belongCluster1 = afterCluster1;belongCluster2 = afterCluster2;}else{belongCluster1 = afterCluster2;belongCluster2 = afterCluster1;}//画出不同的地方foreach (Point m1Point in Cluster1){if (belongCluster1.Contains(m1Point) == false){g.DrawEllipse(p, m1Point.X, m1Point.Y, 6, 6);}}foreach (Point m1Point in Cluster2){if (belongCluster2.Contains(m1Point) == false){g.DrawRectangle(p, m1Point.X, m1Point.Y, 6, 6);}}g.Dispose();p.Dispose();this.pictureBox2.Image = bmp;}}
}

最终的聚类结果:

demo下载:https://download.csdn.net/download/cc_fys/10770325

github demo下载:https://github.com/ccessl/cluster

c# c均值聚类及DBSCAN聚类相关推荐

  1. 学习笔记1 三大聚类方法:K-means聚类、层次聚类、DBSCAN聚类

    学习笔记1:三大聚类方法:K-means聚类.层次聚类.DBSCAN聚类 文章目录 前言 一.K-means聚类 操作过程 二.层次聚类 操作过程 三.DBSCAN聚类 操作过程 总结 前言 在样本数 ...

  2. Python计算机视觉编程第六章——图像聚类(K-means聚类,DBSCAN聚类,层次聚类,谱聚类,PCA主成分分析)

    Python计算机视觉编程 图像聚类 (一)K-means 聚类 1.1 SciPy 聚类包 1.2 图像聚类 1.1 在主成分上可视化图像 1.1 像素聚类 (二)层次聚类 (三)谱聚类 图像聚类 ...

  3. dbscan聚类算法_一种视频人群流的轨迹聚类方法

    tags: KLT光流法,K-means聚类算法,DBSCAN聚类算法 方法简介 运动轨迹是一种在视频场景中捕捉复杂时间动态的有效方法.因此,我们将人流分割问题转化为一个轨迹提取和聚类任务.该方法分为 ...

  4. DBSCAN聚类︱scikit-learn中一种基于密度的聚类方式

    文章目录 @[toc] 一.DBSCAN聚类概述 1.伪代码 2.优点: 3.缺点: 4.与其他聚类算法比较 二.sklearn中的DBSCAN聚类算法 1.主要函数介绍: 最重要的两个参数: 其他主 ...

  5. Python实现经纬度空间点DBSCAN聚类

    写在前面 博主前期科研工作中,涉及到要对某个地区的一些空间点进行聚类分析,想到读研期间,曾经用DBSCAN聚类算法实现了四线激光雷达扫描的三维点云数据聚类(论文题目:基于改进DBSCAN算法的激光雷达 ...

  6. 聚类 之 DBSCAN

    文章目录 DBSCAN 聚类基本原理 DBSCAN 聚类流程简述 实例演示 DBSCAN 聚类简易应用示例 总结 前面介绍的 KMeans 和 MeanShift 算法对于球状类的数据,聚类效果较好. ...

  7. 【机器学习】聚类【Ⅴ】密度聚类与层次聚类

    主要来自周志华<机器学习>一书,数学推导主要来自简书博主"形式运算"的原创博客,包含自己的理解. 有任何的书写错误.排版错误.概念错误等,希望大家包含指正. 由于字数限 ...

  8. K均值与DBSCAN聚类效果

    K均值与DBSCAN聚类效果 K均值的发展状况 K-means算法(Lloyod,1982)是简单而又有效的统计聚类算法,使机器能够将具有相同属性的样本归置到一块儿.K-均值算法的理论研究主要包括三块 ...

  9. K均值聚类和DBSCAN介绍

    K均值(K-means)聚类 问题定义:给定数据$\vec{x}_1,\vec{x}_2,\cdots,\vec{x}_n$,将它们分到不同的$K$个簇(cluster)中.定义$\vec{c}=(c ...

最新文章

  1. C++_pthread read-write lock_读写锁_visual studio 2015下配置
  2. 学习css3的弹性盒模型
  3. docker supervisor管理进程
  4. fis pure开发php,50个精品网站鉴赏
  5. COM、COM+和DCOM的定义和区别
  6. HTML列表内容自动排序,JS实现HTML表格排序功能
  7. 亲历!不要痴迷蓝牙耳机了,出门选这个准没错,99W+人的选择
  8. p10可以适配鸿蒙吗,鸿蒙系统支持旧机型吗
  9. XML-RPC技术在WP上研究(一)
  10. java 截取两个字符之间的字符串_java里面如何截取两个关键字中间的字符串?
  11. 数据结构c语言描述第课后答案李学刚,数据结构(C语言描述)(第2版)
  12. Vagrant:将装在C盘的虚拟机移动到别的目录
  13. 国内经典BI系统架构分析
  14. 如何将STVP的option bytes的配置移植到另外的电脑
  15. 2019个人目标——计划未来
  16. “All in 2B”,信用算力是认真的?
  17. 绕开JS验证的方法汇总
  18. USB class总结
  19. 学历对于程序员找工作重要吗?我来分享一下看法
  20. 高考数学90分能学好计算机,高中数学,如何从90分以下突破120分?你必须做好这两个方面!...

热门文章

  1. eclipse生成boolean型变量的getter是is开头
  2. Java 8 新增lambda表达式(-)
  3. Git学习教程(二):配置和初始化
  4. runtime—新手必学
  5. Exchaneg 2013 集成OWAS
  6. shareSDK 提示#warning:尚未配置[新浪微博]URL Scheme:sinaweibosso.或wb
  7. 思科设备debug命令的使用
  8. 为USB网卡(水星MW150US)编译树莓派上的驱动
  9. 解决Firefox访问EBS时提示激活Java插件的问题
  10. linux的free命令详解-内存是拿来用的不是拿来看的