您的位置:首页 > 编程语言 > MATLAB

k-Mediods算法Matlab实现

2016-03-25 16:01 507 查看
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=3;

%临时存放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     

           length(cluster{i}) 

           for j=1:length(cluster{i})      

               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
abfa
))+(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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息