• 大小: 2KB
    文件类型: .zip
    金币: 1
    下载: 0 次
    发布日期: 2021-05-15
  • 语言: Matlab
  • 标签: matlab  kmeans  cluster  

资源简介

根据网上基于划分法k-means的聚类算法,我做了改进。可以预设一个最大的类数和一个半径,自动划分合适的类。最终将随机三维点云聚类完成后显示为不同颜色。

资源截图

代码片段和文件信息

function [ resXresY resZseedXseedYseedZrecord] = FunK_mean3D( xyzkr)
   while 1
    j = 1;
    seedX = zeros(1k);
    seedY = zeros(1k);
    seedZ = zeros(1k);
    oldSeedX = zeros(1k);
    oldSeedY = zeros(1k);
    oldSeedZ = zeros(1k);
    resX = zeros(klength(x));
    resY = zeros(klength(y));
    resZ = zeros(klength(z));
    record = zeros(1k);  % 用来记录resX中每一行有效元素的个数
    p=2;
  while 1  
    if p == 0
      break;
    end
    for i = 1:k % 产生k个随机种子 注意: 随机种子是来自元素集合
        seedX(i) = x(ceil(rand()*length(resX)));
        seedY(i) = y(ceil(rand()*length(resY)));
        seedZ(i) = z(ceil(rand()*length(resZ)));
    end
   for j=k:-1:2
      p=0;
      for m=j-1:-1:1
          power(seedX(m)-seedX(j)2)+power(seedY(m)-seedY(j)2)+power(seedZ(m)-seedZ(j)2)
         if (power(seedX(m)-seedX(j)2)+power(seedY(m)-seedY(j)2)+power(seedZ(m)-seedZ(j)2))            p=1
            break;
         end
      end
       if p==1
          break;
       end
   end
  end
    while 1
        record(:) = 0; % 重置为零
        resX(:) = 0;
        resY(:) = 0;
        resZ(:) = 0;
        for i = 1:length(x) % 对所有元素遍历
            % 下面是判断本次元素应该归为哪一类,这里我们是根据欧几里得距离进行类别判定
            % k-mean算法认为元素应该归为距离最近的种子代表的类
            distanceMin = 1;
            for j = 2:k
                if (power(x(i)-seedX(distanceMin)2)+power(y(i)-seedY(distanceMin)2)+power(z(i)-seedZ(distanceMin)2))... 
                    > (power(x(i)-seedX(j)2) + power(y(i)-seedY(j)2)+power(z(i)-seedZ(j)2))
                    distanceMin = j;
                end
            end
            % 将本次元素点进行类别归并
            resX(distanceMinrecord(distanceMin) +1) = x(i);
            resY(distanceMinrecord(distanceMin) +1) = y(i);
            resZ(distanceMinrecord(distanceMin) +1) = z(i);
            record(distanceMin) = record(distanceMin) + 1;
        end
        oldSeedX = seedX;
        oldSeedY = seedY;
        oldSeedZ = seedZ;
        % 移动种子至其类中心
        record;
        for i = 1:k
            if record(i) == 0
                continue;
            end
            seedX(i) = sum(resX(i:))/record(i);
            seedY(i) = sum(resY(i:))/record(i);
            seedZ(i) = sum(resZ(i:))/record(i);
        end

    maxPos = max(record);
    resX = resX(:1:maxPos);
    resY = resY(:1:maxPos);
    resZ = resZ(:1:maxPos);

      % 如果本次得到的种子和上次的种子一致,则认为分类完毕。
        if mean([seedX == oldSeedX&seedY == oldSeedY&seedZ == oldSeedZ]) == 1 
            % 这句话所想表达的意思就是 if seedX == oldSeedX && seedY == oldSeedY
            break;
        end
    end        
record( find(record==0))=[];
     if length(record) == k
        break;
     end
  end

end

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----
     文件        1439  2018-07-23 11:08  Untitled2.m
     文件        2915  2018-07-23 11:07  FunK_mean3D.m

评论

共有 条评论