Matlab建立FP-Tree Matlab树结构

本博客的数据和要求是我的数据挖掘课老师提供的,代码是个人原创的。联系方式vx:qczsbwjzjn,如果想要数据可以找我。另外安利一下Matlab用于查询函数用法的官网https://ww2.mathworks.cn/help/matlab/

一、要求

给定2013,2014,2015,2016,2017的福彩双色球数据,共767期数据
(1) 使用一种编程语言实现FP-tree的建树算法,并应用于此数据构建FP-tree;
(2) 统计所建FP-tree中的节点数目,包括根节点;
(3) 通过使用一个算法给出从根到叶子的节点数最多一条路径,并显示其中除根以外每个节点上的支持度计数;
(4) 给出关于根到叶子的节点一条路径,且该路径上所有节点的支持度计数之和最大,显示每个节点上的支持度计数及总和。

二、数据格式

示例:

期号       红球1    红球2    红球3    红球4    红球5    红球6

2013001    6          8           14         15          24         25
2013002    1         16          18         22          28         30
2013003    22       23          26         27          28         33
2013004    6         10          16         20          27         32

三、数据结构

用一个1*n的cell来存放一个节点的信息

cell{1,1}储存当前节点所对应的球编号,cell{1,2}储存当前节点的支持度计数,cell{1,m}(2<m<=n)指向该节点下的子节点

如图所示为根节点的节点信息

四、Matlab代码

main.m 主函数 

clear
%% 主程序
%% 读取数据
ball=importdata('作业01-双色球数据ssq2013_2017.txt');
ball=ball.data(:,2:end);%提取有效数据 得到767*6的矩阵
%% 
f=tabulate(ball(:));
f=sortrows(f,-2);%按支持度降序排列
%项头表,第一列是球编号,第二列是支持度,第三列是占总体的比例
%% 设置支持度阈值
max=f(1,2);%支持度最大值
threshold=max*0.8;%支持度阈值
d=f(f(:,2)<=threshold,1);%提取出支持度低于阈值的球编号至d
f(f(:,2)<=threshold,:)=[];%删去支持度低于阈值的球编号
order=f(:,1);%排列顺序
for i=1:length(ball)
    [~,index]=ismember(ball(i,:),order);
    temp=[ball(i,:);index];
    temp(:,temp(2,:)==0)=NaN;
    temp=sortrows(temp',2)';
    ball(i,:)=temp(1,:);
end
%% 初始化根节点
T{1,1}=NaN;
T{1,2}=0;
%% 建立FP树
for i=1:length(ball)
    temp=ball(i,:);%temp为当第i行数据
    temp=temp(~isnan(temp));%删去NaN
    if ~isempty(temp)%temp不空,向T中插入temp
        T=insertChild(T,temp,1);
    end
end
%% 统计节点数目,包括根节点
Node_number=nodenumber(T);

%% 统计节点最多的路径,并记录其每个节点的支持度
% 第一行为球的编号 第二行为编号对应的支持度
% 编号NaN表示根节点
Node_max=nodemax(T);
%% 节点支持度之和最大的路径
Node_support=supportmax(T);

insertChild.m 【递归】插入子树 

function cell=insertChild(cell,num,k)
    loc=isChild(cell,num(k));
    if loc~=0%该元素是子树
        cell{1,loc}{1,2}=cell{1,loc}{1,2}+1;
        if k~=length(num)
            cell{1,loc}=insertChild(cell{1,loc},num,k+1);
        end
    else %该元素非子树
        if k==length(num)
            child{1,1}=num(k);
            child{1,2}=1;
            cell{1,length(cell)+1}=child;
        else
            len=length(cell);
            cell{1,len+1}{1,1}=num(k);
            cell{1,len+1}{1,2}=1;
            cell{1,len+1}=insertChild(cell{1,len+1},num,k+1);
        end
    end
end

 isChild.m 判断该节点是否是子树,并返回位置

扫描二维码关注公众号,回复: 13328353 查看本文章
function loc=isChild(cell,num)
    %loc表示该元素在cell中的位置
    loc=0;
    if length(cell)>2
        for i=3:length(cell)
            if isempty(cell{1,i})
                break
            elseif cell{1,i}{1,1}==num
                loc=i;
                break;
            end
        end
    end
end

 nodenumber.m文件 【递归】寻找当前树的叶子节点个数

function y=nodenumber(T)
    len=length(T);
    if len==2%当前节点为叶子节点
        y=1;
    else
        y=1;
        for i=3:len
            y=y+nodenumber(T{1,i});
        end
    end
end

 nodemax.m函数  【递归】寻找节点数最多的路径

function y=nodemax(T)
    len=length(T);
    if len==2%当前节点为叶子节点
        y=[T{1,1};T{1,2}];
    else
        k=[T{1,1};T{1,2}];
        max=1;
        for i=3:len
            temp=[k nodemax(T{1,i})];
            if length(temp)>max
                max=length(temp);
                y=temp;
            end
        end
    end
end

supportmax.m函数 【递归】寻找支持度最大的路径

function y=supportmax(T)
    len=length(T);
    if len==2%当前节点为叶子节点
        y=[T{1,1};T{1,2}];
    else
        k=[T{1,1};T{1,2}];
        max=0;
        for i=3:len
            temp=[k supportmax(T{1,i})];
            if sum(temp(2,:))>max
                max=sum(temp(2,:));
                y=temp;
            end
        end
    end
end

demo 简短的方便查看结果的样例代码 

ball=[2 7 5;
      3 6 1;        
      7 5 3;          
      6 2 3;          
      7 4 5];
threshold=2;%支持度阈值
f=tabulate(ball(:));        %编号  支持度
f=sortrows(f,-2);           %  3      3
d=f(f(:,2)<threshold,1);    %  5      3
f(f(:,2)<threshold,:)=[];   %  7      3
order=f(:,1);               %  2      2
                            %  6      2
                            %  1      1    (低于阈值)
                            %  4      1    (低于阈值)
%% 
for i=1:length(ball)                    % 去除支持度低于2的元素后,按支持度对每行ball重排
    [~,index]=ismember(ball(i,:),order);% [5,7,2;
    temp=[ball(i,:);index];             %  3,6,NaN;
    temp(:,temp(2,:)==0)=NaN;           %  3,5,7;
    temp=sortrows(temp',2)';            %  3,2,6;
    ball(i,:)=temp(1,:);                %  5,7,NaN]
end
%% 初始化根节点
T{1,1}=NaN;
T{1,2}=0;
%% 建立FP树                                   %%      所得树
for i=1:length(ball)                              %         NaN
    temp=ball(i,:);%temp为当第i行数据              %        /  \
    temp=temp(~isnan(temp));%删去NaN              %       5    3
    if ~isempty(temp)%temp不空,向T中插入temp      %       |  / | \
        T=insertChild(T,temp,1);                 %       7 6  5  2
    end                                          %       |    |  |
end                                              %       2    7  6
%% 结果输出
%统计节点数目,包括根节点
Node_number=nodenumber(T);
% 统计节点最多的路径,并记录其每个节点的支持度
% 第一行为球的编号 第二行为编号对应的支持度
% 编号NaN表示根节点
Node_max=nodemax(T);
% 节点支持度之和最大的路径
Node_support=supportmax(T);

猜你喜欢

转载自blog.csdn.net/qq_42276781/article/details/103964887