目录
nodenumber.m文件 【递归】寻找当前树的叶子节点个数
安利一下Matlab用于查询函数用法的官网MATLABDocumentation- MathWorks 中国
一、要求
给定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 判断该节点是否是子树,并返回位置
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);
五、数据和代码获取
关注公众号,回复“FP树”即可获取数据和全部代码。