C#,基于密度的噪声应用空间聚类算法(DBSCAN Algorithm)源代码

1 聚类算法

聚类分析或简单聚类基本上是一种无监督的学习方法,它将数据点划分为若干特定的批次或组,使得相同组中的数据点具有相似的属性,而不同组中的数据点在某种意义上具有不同的属性。它包括许多基于差分进化的不同方法。

E、 g.K-均值(点之间的距离)、亲和传播(图距离)、均值偏移(点之间的距离)、DBSCAN(最近点之间的距离)、高斯混合(到中心的马氏距离)、谱聚类(图距离)等。

基本上,所有聚类方法都使用相同的方法,即首先计算相似度,然后使用相似度将数据点聚类为组或批。在这里,我们将重点讨论基于密度的应用程序空间聚类和噪声(DBSCAN)聚类方法。

簇是数据空间中的密集区域,由点密度较低的区域隔开。DBSCAN算法基于"簇"和"噪声"这一直观概念。关键思想是,对于簇的每个点,给定半径的邻域必须至少包含最少数量的点。

2 DBSCAN

DBSCAN全称为**Density-based Spatial Clustering of Applications with Noise。**翻译中文即:基于密度的噪声应用空间聚类(DBSCAN)

基于密度的噪声应用空间聚类是一种基于密度的聚类技术。在基于密度的聚类中,数据按数据点高度集中的区域分组,数据点高度集中的区域被数据点高度集中的区域包围。基本上,该算法会找到数据点密集的地方,并调用这些集群。

DBSCAN是基于密度的聚类的基本算法。它可以从包含噪声和异常值的大量数据中发现不同形状和大小的聚类。DBSCAN集群最吸引人的特性是它对异常值的鲁棒性。该算法只需要两个参数,即minPoints和epsilon。对于一个区域,聚集在一起的最小点数(阈值)是minpoint,其中作为epsilon的是用于在任何点的邻域中定位点的距离度量。DBSCAN围绕每个数据点创建一个epsilon半径的圆,并将其分类为核心点、边界点和噪声。

3 源程序

using System;

using System.Data;

using System.Collections.Generic;

using System.Drawing;

namespace Legalsoft.Truffer.Algorithm

{

public class K_Means_DBSCAN_Algorithm

{

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 void Caverage()

{

afterCluster1.Clear();

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)

{

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);

}

}

}

/// <summary>

/// K-Means-DBSCAN算法

/// </summary>

public void DBSCAN(int radius = 1, int MinPts = 12)

{

double pow = 2.0;

afterCluster1.Clear();

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;

}

}

}

}

}

4 源代码

cs 复制代码
using System;
using System.Data;
using System.Collections.Generic;
using System.Drawing;

namespace Legalsoft.Truffer.Algorithm
{
    public class K_Means_DBSCAN_Algorithm
    {
        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 void Caverage()
        {
            afterCluster1.Clear();
            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)
            {
                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);
                }
            }
        }

        /// <summary>
        /// K-Means-DBSCAN算法
        /// </summary>
        public void DBSCAN(int radius = 1, int MinPts = 12)
        {
            double pow = 2.0;
            afterCluster1.Clear();
            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;
                }
            }
        }
    }
}
相关推荐
掘金安东尼11 分钟前
Amazon Lambda + API Gateway 实战,无服务器架构入门
算法·架构
码流之上1 小时前
【一看就会一写就废 指间算法】设计电子表格 —— 哈希表、字符串处理
javascript·算法
快手技术3 小时前
快手提出端到端生成式搜索框架 OneSearch,让搜索“一步到位”!
算法
CoovallyAIHub1 天前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
NAGNIP1 天前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo1 天前
半开区间和开区间的两个二分模版
算法
moonlifesudo1 天前
300:最长递增子序列
算法
CoovallyAIHub1 天前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
CoovallyAIHub1 天前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
聚客AI2 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm