isodata自适应聚类算法——2017年F题(matlab)(待完成)

[Type Sheet Format]=xlsfinfo('现状OD数据及其他数据.xls');
OD=xlsread('现状OD数据及其他数据.xls',Sheet{1});
center_area=xlsread('现状OD数据及其他数据.xls',Sheet{2});
x_pos=center_area(:,4);   %数据第四列为x坐标(米)
y_pos=center_area(:,5);   %数据第五列为y坐标(米)

x=[x_pos,y_pos];
[node_num,feature_num]=size(x);
%z1=x1;
clusterNumber=10;       %初始设置聚类中心个数为3个=>10
leastNumber=5;         %每个聚类中心最少有一个样本
stdvar=1;              %初始标准差设置为1
minmumDistance=10000;      %根据具体问题设置=> 10000,后续修改
maximumCluster=1;      %每次迭代中聚类中心最多合一对
opCount=5;             %设置迭代次数阈值,达到阈值停止算法,后续修改
number=feature_num;       % X特征数
n=node_num;           % x中样本数
%ISODATA算法的Matlab程序 Design by shuijian (shuijian1122@gmail.com)
%相关函数说明见函数定义
%x=样本特征空间
%clusterNumber=预期聚类中心数目
%leastNumber=最小聚类中的样本数,少于此数将不能作为独立的样本
%stdvar=样本距离分布的标准差,随着迭代中结果逐渐优化,标准差应该越来越小才合理。
%minmumDistance=两聚类中心的最小距离,小于此数将两个聚类合并
%maximumCluster=一次运算中可以合并的聚类中心的最大对数
%opCount=迭代运算次数
%n=,x中元素个数
%number=x中元素特征数目
%s=聚类结果
%clusterCenter=聚类中心
%clusterCount = 聚类中心元素数目
function [s,clusterCenter,clusterCount] = isodata1(x,n,number,clusterNumber,leastNumber,stdvar,minmumDistance,maximumCluster,opCount)
K = clusterNumber;     % K=10;  预期聚类中心数目
qn = leastNumber;      % qn=5; 每个聚类中至少有一个样本;否则不构成一个聚类
qs = stdvar;           % qs=1; 与对应聚类中最大标准差分量maxQs(i)对比;如果maxQs(i)>qs,则进行分裂处理
qc = minmumDistance;   % qc=10000; 小于这个最小距离即进行聚类中心的合并
L = maximumCluster;    % L=1;  一次运算中可以合并的最大对数
I = opCount;           % I=20;  统计iteration迭代次数
num = number;          % number=114; n=2;
factor = 0.5;          %分裂计算时标准差的乘积因子
%z = [x(2,:);x(floor(n/3),:);x(n,:)];  %初始聚类中心,随机选择,z=聚类中心
z = x(2,:);           %初始给定聚类中心,只有一个x2
nc = 1;               %初始聚类数目
opTimes = 1;          %迭代运算次数计数器
while(opTimes <= I)   %加%查看一次循环结果:控制迭代次数来结束聚类
count = zeros(1,nc);   %聚类元素数目,[1];[55;[352]
disTocenter = zeros(n,nc);   %创建数组,储存全部样本对各个聚类中心的距离 [n*1];[2*1];[3*1]
ss = zeros(nc,n);            %所有样本分类 [1*n];[1*n];[1*n]
%依据欧氏距离聚类
for m = 1:n                  %n为总样本个数
    for p = 1:nc
        disTocenter(m,p) = distance(x(m,:),z(p,:),num); %计算各个元素距离各聚类中心之间的距离(第一列为各元素z1的距离,第二列为各元素与z2的距离)
    end
    [minValue,index] = min(disTocenter(m,:));  %依据距离归类
    count(index) = count(index) + 1;           %累计每个类的元素个数
    ss(index,m) = m;                           %存储每个类的元素,ss每行为一个类
end

%修正聚类中心,计算元素到中心的平均距离
for i = 1:nc
    [aveD(i),z(i,:)] = avTocenter(x(find(ss(i,:)),:),count(i),num);
end
%计算全部模式样本对应聚类中心的总的平均距离。
aveAllD = allAvDis(aveD,count);

bool = step_judge(opTimes,nc,I,K);
%bool = step_judge(opTimes,nc,I,L); %判断是进行分裂还是合并运算
nct = nc;
if (bool == 1)  %分裂计算(正确) 
    for i = 1:nc
        stdcluster(i,:) = clusterStd(x(find(ss(i,:)),:),z(i,:),count(i),num);
        %计算每个聚类中样本距离的标准差 向量
        [maxQs(i),ind] = max(stdcluster(i,:)); %求每聚类中标准差最大分量
        if(maxQs(i) > qs && (((aveD(i) > aveAllD) && count(i) > 2 * (qn+1)) || nc <= K/2)) %满足条件,分裂聚类中心
            lqs = z(i,ind) +  factor * maxQs(i);      %% 新的聚类中心与旧的聚类中心对比;只有标准差分量最大的特征的值变化;
            hqs = z(i,ind) - factor * maxQs(i);
            temp=[z;z(i,:)];
            temp(nc+1,ind) = lqs;
            temp(i,ind) = hqs;
            z = temp;                    % z1,z2是新的聚类中心
            nct = nct + 1;               % 聚类中心数目
        end
    end
    nc = nct;
elseif (bool == 0)  %合并
    centerD = centerDistance(z,nc,num);   %两个聚类中心的距离
    Zij = centerD < qc; %查找小于设定最小中心距离的中心
    [indrow,indcol] = find(Zij);  %查找两个中心点
    %indrowcol = [indrow indcol];
    for icount = 1:ceil(numel(indrow)/2) %对称矩阵,只计算一半即可,numel返回矩阵元素总个数;ceil向上取整
        if(indrow(icount) == indcol(icount))  %去掉自身距离(为0)
            continue;                         % 跳出一次循环
        else
            newCenter = count(indrow(icount))*z(indrow(icount),:) + count(indcol(icount))*z(indcol(icount),:);
            newCenter = newCenter ./(count(indrow(icount))+count(indcol(icount))); %计算合并后的新的中心
            for zcount = 1:nc
                centerTemp(zcount,:) = z(zcount,:);  %缓存聚类中心
            end
            z = zeros(nc-1,num);
            for zcount = 1:nc-1
                if(zcount == indrow(icount) || zcount == indcol(icount))
                    z(zcount,:) = newCenter;
                else
                    z(zcount,:) = centerTemp(zcount,:);
                end
            end
            nc = nc - 1;  %合并,减少聚类中心数目
        end
    end
else
    qc = 0;
end
    opTimes = opTimes + 1;
s = ss;
clusterCenter = z;
clusterCount = count;
end 
% 假设只有三个聚类中心,可画图如下(待修改)
function [fig1,fig2] = DrawISODATA(s,clusterCenter,x) % s1~sp:p = length(clusterCount); s1 = find(s(1,:)); s2 = find(s(2,:)); s3 = find(s(3,:)); fig1 = figure; x_loc = x(1:10,:); plot(x_loc(:,1),x_loc(:,2),'kx','MarkerSize',8,'LineWidth',2); square = 10; %方形区域的边长 axis([0,square,0,square]); set(gcf, 'Color', 'w'); %白色 fig2 =figure; s1_loc = x(s1,:); %节点坐标 s2_loc = x(s2,:); s3_loc = x(s3,:); cc_loc = clusterCenter(1:3,:); plot(s1_loc(:,1),s1_loc(:,2),'mx','MarkerSize',8,'LineWidth',2); hold on; plot(s2_loc(:,1),s2_loc(:,2),'rx','MarkerSize',8,'LineWidth',2); hold on; plot(s3_loc(:,1),s3_loc(:,2),'bx','MarkerSize',8,'LineWidth',2); hold on; plot(cc_loc(:,1),cc_loc(:,2),'ko','MarkerSize',8,'LineWidth',2); square = 10; %方形区域的边长 axis([0,square,0,square]); set(gcf, 'Color', 'w'); %白色

 

参考资料:
1.代码参考:https://www.cnblogs.com/huadongw/p/4101422.html

 

posted @ 2020-05-28 23:39  Feynmania  阅读(499)  评论(0编辑  收藏  举报