k-Mediods算法Matlab实现

先前的代码存在细节上的问题,改动如下:

以下为更改后的代码:

clc;
clear;
%读取数据文件,生成点矩阵
fileID = fopen('D:\matlabFile\data.txt');
 C=textscan(fileID,'%f %f');
 fclose(fileID);
 %显示数组结果
%celldisp(C);
 %将cell类型转换为矩阵类型,这里只假设原数据为二维属性,且是二维的坐标点
 CC_init=cat(2,C{1},C{2});%用来保存初始加载的值
 CC=CC_init;
  %获得对象的数量
 num=length(C{1});
 %显示初始分布图
 %scatter(C{1},C{2},'filled');
 %%设置任意k个簇
k=10;
%临时存放k个中心点的数组
C_temp=zeros(k,2);
%判断所设置的k值是否小于对象的数量
if k<num
    %产生随机的k个整数
   randC=randperm(num);
   randC=randC(1:k);
   %从原数组中提出这三个点   
   for i=1:k
       C_temp(i,:)=CC(randC(1,i),:);
   end
   %将原数组中的这三个点清空
    for j=1:k
       CC(randC(1,j),:)=zeros(1,2);
    end  
    idZero=find(CC(:,1)==0);
    %删除为零的行
    [i1,j1]=find(CC==0);
    row=unique(i1);
    CC(row,:)=[];
   %分配k个二维数组,用来存放聚类点
   %分配行为k的存储单元
   cluster=cell(k,1,1); 
    %将剔除的三个点加入到对应的三个存储单元,每个单元的第一行置为0,为了存储相对应的簇中心
   for m=1:k
       cluster{m}=C_temp(m,:);
   end  
   %计算其他点到这k个点的距离,然后分配这些点,第一次遍历
   for i=1:num-k
       %分别计算到三个点的距离       
       minValue=1000000;%最小值,要根据实际情况设定该值
       minNum=-1;%最小值序号
       for j=1:k
           if minValue>sqrt((CC(i,1)-C_temp(j,1))*(CC(i,1)-C_temp(j,1))+(CC(i,2)-C_temp(j,2))*(CC(i,2)-C_temp(j,2)))
               minValue=sqrt((CC(i,1)-C_temp(j,1))*(CC(i,1)-C_temp(j,1))+(CC(i,2)-C_temp(j,2))*(CC(i,2)-C_temp(j,2)));
               minNum=j;
           end
       end
       cluster{minNum}=cat(1,cluster{minNum},CC(i,:));       
   end
   %随机选择p点
   flag=1;
   count=0;
   while flag==1
       randC=randperm(num-k);
       randC=randC(1:1);  
       o_random=CC(randC,:);
       %找出该随机点所在的簇
       recordN=0;
       for i=1:k      
           for j=1:size(cluster{i},1)      
               cc=cluster{i}(j,:);
               cc=cc-o_random;
               if cc==0
                   recordN=i;
                   break;
               end
           end
       end
       %将选择的随机点从点集中删除
       CC(randC,:)=[];
       %计算替换代价
       o=cluster{recordN}(1,:);
       o_rand_sum=0;
       o_sum=0;
       for i=1:length(CC)
           o_rand_sum=o_rand_sum+sqrt((CC(i,1)-o_random(1,1))*(CC(i,1)-o_random(1,1))+(CC(i,2)-o_random(1,2))*(CC(i,2)-o_random(1,2)));
           o_sum=o_sum+sqrt((CC(i,1)-o(1,1))*(CC(i,1)-o(1,1))+(CC(i,2)-o(1,2))*(CC(i,2)-o(1,2)));
       end
       %如果随机选择的点的代价小于原始代表点的代价,则替换该代表点,然后重新聚类
       if o_rand_sum<o_sum
           cluster{recordN}(1,:)=o_random;
           %将代表点放入对象集
           CC=cat(1,CC,o);
           %对所有对象重新进行聚类
           %将cluster除第一行之外的数据全部清空
           for i=1:k
               c=cluster{i}(1,:);
               cluster{i}=[];
               cluster{i}=c;
           end 
           %重新聚类
           for i=1:num-k
               %分别计算到三个点的距离       
               minValue=1000000;%最小值,要根据实际情况设定该值
               minNum=-1;%最小值序号
               for j=1:k
                   if minValue>sqrt((CC(i,1)-C_temp(j,1))*(CC(i,1)-C_temp(j,1))+(CC(i,2)-C_temp(j,2))*(CC(i,2)-C_temp(j,2)))
                       minValue=sqrt((CC(i,1)-C_temp(j,1))*(CC(i,1)-C_temp(j,1))+(CC(i,2)-C_temp(j,2))*(CC(i,2)-C_temp(j,2)));
                       minNum=j;
                   end
               end
               cluster{minNum}=cat(1,cluster{minNum},CC(i,:));       
           end           
       else
           %将随机点重新放入对象集
           CC=cat(1,CC,o_random);
           %终止循环
           flag=0;
       end
       count=count+1;
   end   
   %绘制聚类结果
   for i=1:k
       scatter(cluster{i}(:,1),cluster{i}(:,2),'filled');
       hold on
   end   
end

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 67
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 67
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值