最大最小距离算法(K-MEANS K-medoids )聚类算法的结合运用



聚类算法通常会得到一种分类,将n个点聚合成k类,同一聚类(即插槽簇)中的对象相似度较高;而不同类中的对象相似度较小。
聚类算法的基本流程如下:
(1)从n个节点中选择 k 个节点作为初始聚类中心。(2)将剩余节点根据它们与这k个聚类中心的代价大小,分别将它们分配给与其代价最小的(聚类中心所代表的)聚类。(3)更新聚类的聚类中心。不断重复(2)(3)这一过程将剩下其它节点分配完毕。(4)排序,将各聚类按照聚类间节点代价和高低降序排列。
         下面详细解释上述步骤。
(1)从n个节点中选择 k 个节点作为初始聚类中心
由于K-MEANS算法(一种典型的聚类算法,随机确定k个聚类中心)有缺点:产生类的大小相差不会很大,对于脏数据很敏感。所以采用最大最小距离算法确定这k个聚类中心。最大最小距离算法是识别领域中的一种试探性算法。思想是取尽可能离得远的对象作为聚类中心,以避免聚类中心过于邻近。
步骤如下:
1.计算各节点到其他节点的最大代价总和,取满足最大的点i(可理解为距其他节点最远)为聚类1的中心点。
2.计算其他节点到点的最大代价,取满足最大的i点为聚类2的中心点。
3. 计算其他节点到、点的最大代价,取满足最大的i点为聚类3的中心点。
4. 计算其他节点到、、点的最大代价,取满足最大的i点为聚类4的中心点。
以此类推直到找到k个聚类中心点。
 
(2)将剩余节点根据它们与这些聚类中心的代价大小,分别将它们分配给与其代价最小的(聚类中心所代表的)聚类
依次将不是聚类中心点的节点分配到k个聚类中去。若某类中已经有两个节点,则在分配进入该节点之后还要进行更新聚类中心点的操作(见后(3)详解)。
 
(3)更新聚类的聚类中心
当某个聚类中存在3个或3个以上节点时需要更新此聚类中心点。采用K-medoids算法中的更新聚类中心方式。在 K-medoids算法中,我们将从当前聚类中选取这样一个点——它到其他所有(当前聚类中)点的代价之和最小——作为中心点。
 
(4)排序,将各聚类按照聚类间代价高低降序排列。
[cpp] view plain copy
#include <stdio.h>  
#include <stdlib.h>  
#include <iostream>  
#include <math.h>  
#include "CLSlotClustering.h"  
#include "CLZone.h"  
#include "CLVMMinKCut.h"  
  
using namespace std;  
  
CLSlotClustering::CLSlotClustering()  
{  
}  
  
CLSlotClustering::~CLSlotClustering()  
{  
}  
  
int CLSlotClustering::Find(int i)  
{  
    int j;  
    if (m_Parent[i]==i)  
    {  
        return  i;  
    }  
    j=m_Parent[i];  
    Find(j);  
    return 0;  
}  
  
CLZone CLSlotClustering::SlotClustering(int C[][MAXNUMBER],int n,int k,int flag)  
{  
    m_VexOfMaxCost=0;                               //初始化  
    m_Flag=0;  
    m_Number=(-1);  
    for (int i = 0; i < MAXNUMBER; i++)  
    {  
        m_Parent[i]=i;  
        m_VexOfCostSum[i]=0;  
        for (int j = 0; j < MAXNUMBER; j++)            
        {  
            m_C[i][j]=0;  
        }  
    }  
    m_k=k;  
    m_n=n;  
    //cout<<"m_C:"<<endl;  
    for (int i = 0; i < n; i++)  
    {  
        for (int j = 0; j < n; j++)  
        {  
            m_C[i][j]=C[i][j];                      //读入代价矩阵  
            //cout<<m_C[i][j]<<"\t";  
        }  
        //cout<<"\n";  
    }  
    //Sleep(3000);  
  
    FindCenter();  
    if (!flag)  
    {  
        Clusting();  
    }  
    Sort();  
    return **m_MyZone;  
}  
int CLSlotClustering::FindCenter()              //找k个聚合类的中心点  
{  
    for (int i = 0; i < m_n; i++)  
    {  
        for (int j = 0; j < m_n; j++)  
        {  
            m_VexOfCostSum[i]+=m_C[i][j];  
        }  
        if (m_VexOfCostSum[i]>m_Flag)  
        {  
            m_VexOfMaxCost=i;  
            m_Flag=m_VexOfCostSum[i];  
        }  
    }  
    m_MyZone[0]= new CLZone;  
    m_MyZone[0]->m_Center=m_VexOfMaxCost;        //第一个中心点  
    m_MyZone[0]->m_Size=1;  
    m_MyZone[0]->m_Member[0]=m_MyZone[0]->m_Center;  
    m_Flag=0;                                 
    m_VexOfMaxCost=0;         
    for (int l = 1; l < m_k; l++)                //找其余中心点  
    {  
        for (int k = 0; k < m_n; k++)  
        {  
            if (l>1)  
            {  
                if (l==2)  
                {  
                    m_Cost[k]=m_C[m_MyZone[0]->m_Center][k];  
                }  
                m_Cost[k]=min(m_C[m_MyZone[l-1]->m_Center][k],m_Cost[k]);    //min(Dl(l-1),Dl(l-2))  
                if (m_Flag<m_Cost[k])                                        //max(min(Dl(l-1),Dl(l-2)))  
                {  
                    m_Flag=m_Cost[k];  
                    m_VexOfMaxCost=k;  
                }  
            }  
            else                                                //第二个节点,只需要maxDl1,不需要min(Dl1,Dl2)  
            {  
                if (m_Flag<m_C[m_MyZone[0]->m_Center][k])  
                {  
                    m_Flag=m_C[m_MyZone[0]->m_Center][k];  
                    m_VexOfMaxCost=k;  
                }  
            }  
        }     
        m_MyZone[l]=new CLZone;  
        m_MyZone[l]->m_Center=m_VexOfMaxCost;                    //各类中心点  
        m_MyZone[l]->m_Size=1;  
        m_MyZone[l]->m_Member[0]=m_MyZone[l]->m_Center;  
        m_Flag=0;  
    }  
    return 0;  
}  
  
int CLSlotClustering::Clusting()  
{  
      
    m_VexOfCostSum[m_n-1]=10000;                    //临时变量  
    for (int i = 0; i < m_n; i++)  
    {  
        m_Flag=10000;  
        m_Flag_IsCenter=0;  
        for (int j = 0; j < m_k; j++)      
        {  
            if (i==m_MyZone[j]->m_Member[0])     //验证是否是首个中心点,如果是则不进行聚合操作  
            {  
                m_Parent[i]=i;  
                m_Flag_IsCenter=1;  
                break;  
            }  
            if (m_Flag>m_C[i][m_MyZone[j]->m_Center]&&m_C[i][m_MyZone[j]->m_Center]!=0)        //记录i点离某个中心最近  
            {  
                m_Flag=m_C[i][m_MyZone[j]->m_Center];  
                m_Parent[i]=Find(m_MyZone[j]->m_Center);  
                m_Number=j;  
            }  
        }  
        if (m_Flag_IsCenter==0&&m_Number!=(-1))                             //将i点聚合  
        {  
            m_MyZone[m_Number]->m_Member[m_MyZone[m_Number]->m_Size]=i;  
            (m_MyZone[m_Number]->m_Size)++;  
            if (m_MyZone[m_Number]->m_Size>2)                             //当某聚合类中数量大于2时需要检验是否要改变聚合类中心  
            {  
                for (int k = 0; k < m_MyZone[m_Number]->m_Size; k++)  
                {  
                    m_VexOfCostSum[k]=0;  
                    for (int l = 0; l < m_MyZone[m_Number]->m_Size; l++)  
                    {  
                        m_VexOfCostSum[k]+=m_C[m_MyZone[m_Number]->m_Member[k]][m_MyZone[m_Number]->m_Member[l]];  
                    }  
                    if (m_VexOfCostSum[k]<m_VexOfCostSum[m_n-1])  
                    {  
                        m_VexOfCostSum[m_n-1]=m_VexOfCostSum[k];  
                        m_MyZone[m_Number]->m_Center=m_MyZone[m_Number]->m_Member[k];  
                    }  
                }  
                //cout<<"changed--m_MyZone["<<m_Number<<"]->m_Center:"<<m_MyZone[m_Number]->m_Center<<endl;  
            }  
        }  
        m_Number=(-1);  
    }  
    return 0;  
}  
  
int CLSlotClustering::Sort()  
{  
    m_Flag=0;  
    for (int i = 0; i < m_n; i++)                        //得到各点到其他聚合类的代价和  
    {  
        m_VexOfCostSum[i]=0;  
        for (int j = 0; j < m_n; j++)                      
        {  
            if (m_Parent[i]==m_Parent[j])               //若i,j为同一个集合,则查看下一个点  
            {  
                continue;  
            }  
            else  
            {  
                m_VexOfCostSum[i]+=m_C[i][j];  
            }                             
        }  
    }  
    m_MyZone[m_k]=new CLZone;  
    for (int k = 0; k < m_k; k++)                                    //得到各类到其他类的代价和  
    {  
        m_MyZone[k]->m_SumOfCost=0;  
        for (int l = 0; l < m_MyZone[k]->m_Size; l++)  
        {  
            m_MyZone[k]->m_SumOfCost+=m_VexOfCostSum[m_MyZone[k]->m_Member[l]];             
        }  
    }  
    for (int i = 0; i < m_k; i++)                                        //各聚合类降序排序  
    {  
        for (int j = i+1; j < m_k; j++)  
        {  
            if (m_MyZone[i]->m_SumOfCost<m_MyZone[j]->m_SumOfCost)  
            {  
                m_MyZone[m_k]=m_MyZone[i];  
                m_MyZone[i]=m_MyZone[j];  
                m_MyZone[j]=m_MyZone[m_k];  
            }  
        }  
    }  
    /*for (int i = 0; i < m_k; i++) 
    { 
        cout<<"m_MyZone["<<i<<"]->m_Center:"<<m_MyZone[i]->m_Center<<"\t"<<"m_MyZone["<<i<<"]->Size:"<<m_MyZone[i]->m_Size<<"\t"<<"m_MyZone["<<i<<"]->Member:\n"; 
        for (int j = 0; j < m_MyZone[i]->m_Size; j++) 
        { 
            cout<<m_MyZone[i]->m_Member[j]<<"\t"; 
        } 
        cout<<endl; 
    }*/  
    return 0;  
}  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510372.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 EasyCV Mask2Former 轻松实现图像分割

导言 图像分割(Image Segmentation)是指对图片进行像素级的分类&#xff0c;根据分类粒度的不同可以分为语义分割(Semantic Segmentation)、实例分割(Instance Segmentation)、全景分割(Panoptic Segmentation)三类。图像分割是计算机视觉中的主要研究方向之一&#xff0c;在医…

八皇后问题详解(最短代码)

八皇后问题算法分析&#xff1a; 分析1&#xff1a;八皇后由一个64格的方块组成&#xff0c;那么把八个皇后放入不考虑其他情况利用穷举法&#xff0c;有8^64种 可能。 分析2&#xff1a;显然任意一行有且仅有1个皇后&#xff0c;使用数组queen[0->7]表示第i行的皇后位于哪一…

5个编写技巧,有效提高单元测试实践

1. 什么是单元测试 “在计算机编程中&#xff0c;单元测试又称为模块测试&#xff0c;是针对程序模块来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中&#xff0c;一个单元就是单个程序、函数、过程等&#xff1b;对于面向对象编程&#xff0c;最…

谈谈我工作中的23个设计模式

序 从基础的角度看&#xff0c;设计模式是研究类本身或者类与类之间的协作模式&#xff0c;是进行抽象归纳的一个很好的速成思路。后面阅读设计模式后&#xff0c;为了加深理解&#xff0c;对相关图片进行了描绘和微调。 从技术的角度已经有很多好的总结&#xff0c;本文会换…

三种方法求最长子序列问题

#include<iostream> #include<algorithm> using namespace std; int maxsum(int a[],int x,int y) {int v,l,r;if(y-x1)//只有一个元素&#xff0c;直接返回 return a[x];int mx(y-x)/2;//分治法第一步&#xff0c;划分成[x,m)和[m,y)int maxsmax(maxsum(a,x,m),ma…

OpenSergo 流量路由:从场景到标准化的探索

流量路由&#xff0c;顾名思义就是将具有某些属性特征的流量&#xff0c;路由到指定的目标。流量路由是流量治理中重要的一环&#xff0c;多个路由如同流水线一样&#xff0c;形成一条路由链&#xff0c;从所有的地址表中筛选出最终目的地址集合&#xff0c;再通过负载均衡策略…

传统 Web 框架部署与迁移

与其说 Serverless 架构是一个新的概念&#xff0c;不如说它是一种全新的思路&#xff0c;一种新的编程范式。 但是原生的 Serverless 开发框架却非常少。以 Web 框架为例&#xff0c;目前主流的 Web 框架“均不支持 Serverless 模式部署”&#xff0c;因此我们一方面要尝试接…

归并排序(视频+详解+代码)

归并排序 概述&#xff1a;归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使…

三款“非主流”日志查询分析产品初探

前言 近些年在开源领域&#xff0c;用于构建日志系统的软件有两类典型&#xff1a; Elasticsearch&#xff1a;基于 Lucene 构建倒排索引提供搜索功能&#xff0c;DocValue 存储支持了其统计分析能力。Clickhouse&#xff1a;列式存储是其优秀 OLAP 性能的保障。 这里把上述系…

C++ Set常用用法

set集合容器&#xff1a;实现了红黑树的平衡二叉检索树的数据结构&#xff0c;插入元素时&#xff0c;它会自动调整二叉树的排列&#xff0c;把元素放到适当的位置&#xff0c;以保证每个子树根节点键值大于左子树所有节点的键值&#xff0c;小于右子树所有节点的键值&#xff…

CIPU落地专有云:是“小众需求”还是“机会之门”?

引言&#xff1a;2022年11月&#xff0c;云栖大会主论坛&#xff0c;阿里巴巴集团副总裁、阿里云智能基础产品事业部负责人蒋江伟分享了阿里云专有云的一项新进展 —— CIPU落地飞天企业版。在分析师峰会上&#xff0c;阿里巴巴集团研究员、阿里云专有云总经理刘国华也向分析师…

基于开源 PolarDB-X 打造中正智能身份认证业务数据基座

一、公司及业务介绍 中正智能是全球领先的生物识别和身份认证公司之一。我们曾负责公安部指纹算法国家标准的起草、编写&#xff0c;具备从算法、终端、平台、设计、生产、交付全域自研的能力&#xff0c;拥有多项自主知识产权的产品&#xff0c;并积极与高校合作开展基础研发。…

如何开发一个标准的云原生应用?

从几个数字开始说 IDC 预计到 2024 年&#xff0c;由于采用了微服务、容器、动态编排和 DevOps 等技术&#xff0c;新增的生产级云原生应用在新应用的占比将从 2020 年的 10% 增加到 60%&#xff0c;其中微服务的 workload 在企业内将超过 80% 。上面的四点是云原生时代所代表…

Higress实战: 30行代码写一个Wasm Go插件

前言 在11月15号的直播 《Higress 开源背后的发展历程和上手 Demo 演示》中&#xff0c;为大家演示了 Higress 的 Wasm 插件如何面向 Ingress 资源进行配置生效&#xff0c;本文对当天的 Demo 进行一个回顾&#xff0c;并说明背后的原理机制。 本文中 Demo 运行的前提&#x…

Serverless 的前世今生

从云计算到 Serverless 架构 大家好&#xff0c;我是阿里云 Serverless 产品经理刘宇&#xff0c;很高兴可以和大家一起探索 Serverless 架构的前世今生。 从云计算到云原生再到 Serverless 架构&#xff0c;技术飞速发展的轨迹都有一定规律可循&#xff0c;那么 Serverless 架…

eunomia-bpf 项目重磅开源!eBPF 轻量级开发框架来了

近日&#xff0c;在 2022 云栖大会龙蜥峰会 eBPF & Linux 稳定性专场上&#xff0c;来自 eBPF 技术探索 SIG Maintainer 、浙江大学的郑昱笙分享了《eunomia-bpf&#xff1a;eBPF 轻量级开发框架》技术演讲&#xff0c;以下为本次演讲内容&#xff1a; 大家好&#xff01;…

一文看懂分布式链路监控系统

背景 传统的大型单体系统随着业务体量的增大已经很难满足市场对技术的需求&#xff0c;通过对将整块业务系统拆分为多个互联依赖的子系统并针对子系统进行独立优化&#xff0c;能够有效提升整个系统的吞吐量。在进行系统拆分之后&#xff0c;完整的业务事务逻辑所对应的功能会…

深度 | 新兴软件研发范式崛起,云计算全面走向 Serverless 化

11月3日&#xff0c;2022 杭州 云栖大会上&#xff0c;阿里云智能总裁张建锋表示&#xff0c;以云为核心的新型计算体系正在形成&#xff0c;软件研发范式正在发生新的变革&#xff0c;Serverless 是其中最重要的趋势之一&#xff0c;阿里云将坚定推进核心产品全面 Serverless…

适用场景全新升级!扩展 Dragonfly2 作为分布式缓存系统架构

Dragonfly2 简介 Dragonfly 作为龙蜥社区的镜像加速标准解决方案&#xff0c;是一款基于 P2P 的智能镜像和文件分发工具。它旨在提高大规模文件传输的效率和速率&#xff0c;最大限度地利用网络带宽。在应用分发、缓存分发、日志分发和镜像分发等领域被大规模使用。 现阶段 D…

sdut1197约瑟夫问题

#include <stdio.h> int main( void ) {int n, i 0, m, p,ans;scanf("%d%d", &n, &m); //n总人数&#xff0c;m步长while( i < n ){p i * m;while (p > n)p p - n (p - n - 1)/(m - 1);// printf("%d\n", p);ansp;}printf("…