聚类算法程序
Ⅰ 如何编写求K-均值聚类算法的Matlab程序
在聚类分析中,K-均值聚类算法(k-means
algorithm)是无监督分类中的一种基本方法,其也称为C-均值算法,其基本思想是:通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
假设要把样本集分为c个类别,算法如下:
(1)适当选择c个类的初始中心;
(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类,
(3)利用均值等方法更新该类的中心值;
(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代。
下面介绍作者编写的一个分两类的程序,可以把其作为函数调用。
%%
function
[samp1,samp2]=kmeans(samp);
作为调用函数时去掉注释符
samp=[11.1506
6.7222
2.3139
5.9018
11.0827
5.7459
13.2174
13.8243
4.8005
0.9370
12.3576];
%样本集
[l0
l]=size(samp);
%%利用均值把样本分为两类,再将每类的均值作为聚类中心
th0=mean(samp);n1=0;n2=0;c1=0.0;c1=double(c1);c2=c1;for
i=1:lif
samp(i)<th0
c1=c1+samp(i);n1=n1+1;elsec2=c2+samp(i);n2=n2+1;endendc1=c1/n1;c2=c2/n2;
%初始聚类中心t=0;cl1=c1;cl2=c2;
c11=c1;c22=c2;
%聚类中心while
t==0samp1=zeros(1,l);
samp2=samp1;n1=1;n2=1;for
i=1:lif
abs(samp(i)-c11)<abs(samp(i)-c22)
samp1(n1)=samp(i);
cl1=cl1+samp(i);n1=n1+1;
c11=cl1/n1;elsesamp2(n2)=samp(i);
cl2=cl2+samp(i);n2=n2+1;
c22=cl2/n2;endendif
c11==c1
&&
c22==c2t=1;endcl1=c11;cl2=c22;
c1=c11;c2=c22;
end
%samp1,samp2为聚类的结果。
初始中心值这里采用均值的办法,也可以根据问题的性质,用经验的方法来确定,或者将样本集随机分成c类,计算每类的均值。
k-均值算法需要事先知道分类的数量,这是其不足之处。
Ⅱ 用python K值聚类识别图片主要颜色的程序,算法python代码已经有了
难得被人求助一次, 这个必须回答一下. 不过你的需求确实没有写得太清楚. 根据k值算法出来的是主要颜色有三个, 所以我把三个颜色都打在记事本里了. 如果和你的需求有误, 请自行解决吧.
另外这里需要用到numpy的库, 希望你装了, 如果没装, 这个直接安装也比较麻烦, 可以看一下portablepython的绿色版。
代码如下:
#-*-coding:utf-8-*-
importImage
importrandom
importnumpy
classCluster(object):
def__init__(self):
self.pixels=[]
self.centroid=None
defaddPoint(self,pixel):
self.pixels.append(pixel)
defsetNewCentroid(self):
R=[colour[0]forcolourinself.pixels]
G=[colour[1]forcolourinself.pixels]
B=[colour[2]forcolourinself.pixels]
R=sum(R)/len(R)
G=sum(G)/len(G)
B=sum(B)/len(B)
self.centroid=(R,G,B)
self.pixels=[]
returnself.centroid
classKmeans(object):
def__init__(self,k=3,max_iterations=5,min_distance=5.0,size=200):
self.k=k
self.max_iterations=max_iterations
self.min_distance=min_distance
self.size=(size,size)
defrun(self,image):
self.image=image
self.image.thumbnail(self.size)
self.pixels=numpy.array(image.getdata(),dtype=numpy.uint8)
self.clusters=[Noneforiinrange(self.k)]
self.oldClusters=None
randomPixels=random.sample(self.pixels,self.k)
foridxinrange(self.k):
self.clusters[idx]=Cluster()
self.clusters[idx].centroid=randomPixels[idx]
iterations=0
whileself.shouldExit(iterations)isFalse:
self.oldClusters=[cluster.centroidforclusterinself.clusters]
printiterations
forpixelinself.pixels:
self.assignClusters(pixel)
forclusterinself.clusters:
cluster.setNewCentroid()
iterations+=1
return[cluster.centroidforclusterinself.clusters]
defassignClusters(self,pixel):
shortest=float('Inf')
forclusterinself.clusters:
distance=self.calcDistance(cluster.centroid,pixel)
ifdistance<shortest:
shortest=distance
nearest=cluster
nearest.addPoint(pixel)
defcalcDistance(self,a,b):
result=numpy.sqrt(sum((a-b)**2))
returnresult
defshouldExit(self,iterations):
ifself.oldClustersisNone:
returnFalse
foridxinrange(self.k):
dist=self.calcDistance(
numpy.array(self.clusters[idx].centroid),
numpy.array(self.oldClusters[idx])
)
ifdist<self.min_distance:
returnTrue
ifiterations<=self.max_iterations:
returnFalse
returnTrue
#############################################
#
defshowImage(self):
self.image.show()
defshowCentroidColours(self):
forclusterinself.clusters:
image=Image.new("RGB",(200,200),cluster.centroid)
image.show()
defshowClustering(self):
localPixels=[None]*len(self.image.getdata())
foridx,pixelinenumerate(self.pixels):
shortest=float('Inf')
forclusterinself.clusters:
distance=self.calcDistance(
cluster.centroid,
pixel
)
ifdistance<shortest:
shortest=distance
nearest=cluster
localPixels[idx]=nearest.centroid
w,h=self.image.size
localPixels=numpy.asarray(localPixels)
.astype('uint8')
.reshape((h,w,3))
colourMap=Image.fromarray(localPixels)
colourMap.show()
if__name__=="__main__":
fromPILimportImage
importos
k_image=Kmeans()
path=r'.\pics\'
fp=open('file_color.txt','w')
forfilenameinos.listdir(path):
printpath+filename
try:
color=k_image.run(Image.open(path+filename))
fp.write('Thecolorof'+filename+'is'+str(color)+' ')
except:
print"Thisfileformatisnotsupport"
fp.close()
Ⅲ 使用K-Means 算法进行聚类分析程序
你这是四维数据,我这是一维数据kmeans,你试试吧
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
int N; //数据个数
int K; //集合个数
int *CenterIndex; //质心索引集合,即属于第几个参考点
double *Center; //质心集合
double *CenterCopy;
double *DataSet;
double **Cluster;
int *Top;
/*算法描述:
C-Fuzzy均值聚类算法采用的是给定类的个数K,将N个元素(对象)分配到K个类中去使得类内对象之间的相似性最大,而类之间的相似性最小 */
//函数声明部分
void InitData();
void InitCenter();
void CreateRandomArray(int n,int k,int *centerIndex);
void CopyCenter();
void UpdateCluster();
void UpdateCenter();
int GetIndex(double value,double *centerIndex);
void AddtoCluster(int index,double value);
void print();
bool IsEqual(double *center,double *center);
int main()
{
int Flag=1;
InitData();
while(Flag)//无限次循环
{
UpdateCluster();
UpdateCenter();
if(IsEqual(Center,CenterCopy))
{
Flag=0;
}
else
{
CopyCenter();
}
}
print();
getchar();
system("pause");
}
void InitData()
{
int i=0;
int a;
cout<<"请输入数据元素的个数: ";
cin>>N;
cout<<"请输入分类数: ";
cin>>K;
if(K>N)
{
return;
}
CenterIndex =new int [sizeof(int)];
Center =new double [sizeof(double)*K];
CenterCopy =new double [sizeof(double)*K];
DataSet =new double [sizeof(double)*N];
Cluster =new double* [sizeof(double*)*K];
Top =new int [sizeof(int)*K];
//初始化K个类的集合
for(i=0;i<K;i++)
{
Cluster[i]=new double [sizeof(double)*N];
Top[i]=0;
}
cout<<"请输入数据"<<endl;
for(i=0;i<N;i++)
{
cin>>a;
DataSet[i]=a;
}
//初始化质心集合
InitCenter();
UpdateCluster();
}
void InitCenter()//初始化中心点(参照点)
{
int i=0;
//产生随即的K个<N的不同的序列
CreateRandomArray(N,K,CenterIndex);
for(i=0;i<K;i++)
{
Center[i]=DataSet[CenterIndex[i]];
}
CopyCenter();
}
void CreateRandomArray(int n,int k,int *centerIndex)//产生可以随输出控制的 k与n (可舍弃)
{
int i=0,j=0;
for(i=0;i<K;i++)
{
int a=rand()%n;
for(j=0;j<i;j++)
{
if(centerIndex[j]==a)
break;
}
if(j>=i)
{
centerIndex[i]=a;
}
else
{
i--;
}
}
}
void CopyCenter()//将旧的中心点保留以作比较
{
int i=0;
for(i=0;i<K;i++)
{
CenterCopy[i]=Center[i];
}
}
void UpdateCluster()//
{
int i=0;
int tindex;
for(;i<K;i++)
{
Top[i]=0;
}
for(i=0;i<N;i++)
{
tindex=GetIndex(DataSet[i],Center);
AddtoCluster(tindex,DataSet[i]);
}
}
int GetIndex(double value,double *center)//判断属于哪个参照点
{
int i=0;
int index=i;
double min=fabs(value-center[i]);
for(i=0;i<K;i++)
{
if(fabs(value-center[i])<min)
{
index=i;
min=fabs(value-center[i]);
}
}
return index;
}
void AddtoCluster(int index,double value)//统计每组个数(用于均值法求新的参照点)
{
Cluster[index][Top[index]]=value;
Top[index]++;
}
void UpdateCenter()//更新参照点
{
int i=0,j=0;
double sum;
for(i=0;i<K;i++)
{
sum=0.0;
for(j=0;j<Top[i];j++)
{
sum+=Cluster[i][j];
}
if(Top[i]>0)
{
Center[i]=sum/Top[i];
}
}
}
bool IsEqual(double *center,double*center)//
{
int i;
for(i=0;i<K;i++)
{
if(fabs(center[i]!=center[i]))
return 0;
}
return 1;
}
void print()//
{
int i,j;
cout<<"===================================="<<endl;
for(i=0;i<K;i++)
{
cout<<"第"<<i<<"组:质心为:"<<Center[i]<<endl;
cout<<"数据元素为:\n";
for(j=0;j<Top[i];j++)
{
cout<<Cluster[i][j]<<'\t';
}
cout<<endl;
}
}
Ⅳ MATLAB建模方法有哪些
首先,Matlab是一个工具,它不是一个方法。
其次,我给你推荐一本书
《MATLAB 在数学建模中的应用(第2版)》
然后它的目录可以回答你的问题:
第1章 数学建模常规方法及其MATLAB实现
1.1 MATLAB与数据文件的交互
1.1.1 MATLAB与Excel的交互
1.1.2 MATLAB与TXT交互
1.1.3 MATLAB界面导入数据的方法
1.2 数据拟合方法
1.2.1 多项式拟合
1.2.2 指定函数拟合
1.2.3 曲线拟合工具箱
1.3 数据拟合应用实例
1.3.1 人口预测模型
1.3.2 薄膜渗透率的测定
1.4 数据的可视化
1.4.1 地形地貌图形的绘制
1.4.2 车灯光源投影区域的绘制(CUMCM2002A)
1.5 层次分析法(AHP)
1.5.1 层次分析法的应用场景
1.5.2 AHPMATLAB程序设计
第2章 规划问题的MATLAB求解
2.1 线性规划
2.1.1 线性规划的实例与定义
2.1.2 线性规划的MATLAB标准形式
2.1.3 线性规划问题解的概念
2.1.4 求解线性规划的MATLAB解法
2.2 非线性规划
2.2.1 非线性规划的实例与定义
2.2.2 非线性规划的MATLAB解法
2.2.3 二次规划
2.3 整数规划
2.3.1 整数规划的定义
2.3.2 01整数规划
2.3.3 随机取样计算法
第3章 数据建模及MATLAB实现
3.1 云模型
3.1.1 云模型基础知识
3.1.2 云模型的MATLAB程序设计
3.2 Logistic回归
3.2.1 Logistic模型
3.2.2 Logistic回归MATLAB程序设计
3.3 主成分分析
3.3.1 PCA基本思想
3.3.2 PCA步骤
3.3.3 主成分分析MATLAB程序设计
3.4 支持向量机(SVM)
3.4.1 SVM基本思想
3.4.2 理论基础
3.4.3 支持向量机MATLAB程序设计
3.5 K均值(KMeans)
3.5.1 KMeans原理、步骤和特点
3.5.2 KMeans聚类MATLAB程序设计
3.6 朴素贝叶斯判别法
3.6.1 朴素贝叶斯判别模型
3.6.2 朴素贝叶斯判别法MATLAB设计
3.7 数据建模综合应用
参考文献
第4章 灰色预测及其MATLAB实现
4.1 灰色系统基本理论
4.1.1 灰色关联度矩阵
4.1.2 经典灰色模型GM(1,1)
4.1.3 灰色Verhulst模型
4.2 灰色系统的程序设计
4.2.1 灰色关联度矩阵的程序设计
4.2.2 GM(1,1)的程序设计
4.2.3 灰色Verhulst模型的程序设计
4.3 灰色预测的MATLAB程序
4.3.1 典型程序结构
4.3.2 灰色预测程序说明
4.4 灰色预测应用实例
4.4.1 实例一长江水质的预测(CUMCM2005A)
4.4.2 实例二预测与会代表人数(CUMCM2009D)
4.5 小结
参考文献
第5章 遗传算法及其MATLAB实现
5.1 遗传算法基本原理
5.1.1 人工智能算法概述
5.1.2 遗传算法生物学基础
5.1.3 遗传算法的实现步骤
5.1.4 遗传算法的拓展
5.2 遗传算法的MATLAB程序设计
5.2.1 程序设计流程及参数选取
5.2.2 MATLAB遗传算法工具箱
5.3 遗传算法应用案例
5.3.1 案例一:无约束目标函数最大值遗传算法求解策略
5.3.2 案例二:CUMCM中多约束非线性规划问题的求解
5.3.3 案例三:BEATbx遗传算法工具箱的应用——电子商务中转化率影响因素研究
参考文献
第6章 模拟退火算法及其MATLAB实现
6.1 算法的基本理论
6.1.1 算法概述
6.1.2 基本思想
6.1.3 其他一些参数的说明
6.1.4 算法基本步骤
6.1.5 几点说明
6.2 算法的MATLAB实现
6.2.1 算法设计步骤
6.2.2 典型程序结构
6.3 应用实例:背包问题的求解
6.3.1 问题的描述
6.3.2 问题的求解
6.4 模拟退火程序包ASA简介
6.4.1 ASA的优化实例
6.4.2 ASA的编译
6.4.3 MATLAB版ASA的安装与使用
6.5 小结
6.6 延伸阅读
参考文献
第7章 人工神经网络及其MATLAB实现
7.1 人工神经网络基本理论
7.1.1 人工神经网络模型拓扑结构
7.1.2 常用激励函数
7.1.3 常见神经网络理论
7.2 BP神经网络的结构设计
7.2.1 鲨鱼嗅闻血腥味与BP神经网络训练
7.2.2 透视神经网络的学习步骤
7.2.3 BP神经网络的动态拟合过程
7.3 RBF神经网络的结构设计
7.3.1 梯度训练法RBF神经网络的结构设计
7.3.2 RBF神经网络的性能
7.4 应用实例
7.4.1 基于MATLAB源程序公路运量预测
7.4.2 基于MATLAB工具箱公路运量预测
7.4.3 艾滋病治疗最佳停药时间的确定(CUMCM2006B)
7.4.4 RBF神经网络预测新客户流失概率
7.5 延伸阅读
7.5.1 从金融分析中的小数定理谈神经网络的训练样本遴选规则
7.5.2 小议BP神经网络的衍生机理
参考文献
第8章粒子群算法及其MATLAB实现
8.1 PSO算法相关知识
8.1.1 初识PSO算法
8.1.2 PSO算法的基本理论
8.1.3 PSO算法的约束优化
8.1.4 PSO算法的优缺点
8.2 PSO算法程序设计
8.2.1 程序设计流程
8.2.2 PSO算法的参数选取
8.2.3 PSO算法MATLAB源程序范例
8.3 应用案例:基于PSO算法和BP算法训练神经网络
8.3.1 如何评价网络的性能
8.3.2 BP算法能够搜索到极值的原理
8.3.3 PSOBP神经网络的设计指导原则
8.3.4 PSO算法优化神经网络结构
8.3.5 PSOBP神经网络的实现
参考文献
第9章 蚁群算法及其MATLAB实现
9.1 蚁群算法原理
9.1.1 蚁群算法基本思想
9.1.2 蚁群算法数学模型
9.1.3 蚁群算法流程
9.2 蚁群算法的MATLAB实现
9.2.1 实例背景
9.2.2 算法设计步骤
9.2.3 MATLAB程序实现
9.2.4 程序执行结果与分析
9.3 算法关键参数的设定
9.3.1 参数设定的准则
9.3.2 蚂蚁数量
9.3.3 信息素因子
9.3.4 启发函数因子
9.3.5 信息素挥发因子
9.3.6 信息素常数
9.3.7 最大迭代次数
9.3.8 组合参数设计策略
9.4 应用实例:最佳旅游方案(苏北赛2011B)
9.4.1 问题描述
9.4.2 问题的求解和结果
9.5 本章小结
参考文献
第10章 小波分析及其MATLAB实现
10.1 小波分析基本理论
10.1.1 傅里叶变换的局限性
10.1.2 伸缩平移和小波变换
10.1.3 小波变换入门和多尺度分析
10.1.4 小波窗函数自适应分析
10.2 小波分析MATLAB程序设计
10.2.1 小波分析工具箱函数指令
10.2.2 小波分析程序设计综合案例
10.3 小波分析应用案例
10.3.1 案例一:融合拓扑结构的小波神经网络
10.3.2 案例二:血管重建引出的图像数字水印
参考文献
第11章 计算机虚拟及其MATLAB实现
11.1 计算机虚拟基本知识
11.1.1 从3G移动互联网协议WCDMA谈MATLAB虚拟
11.1.2 计算机虚拟与数学建模
11.1.3 数值模拟与经济效益博弈
11.2 数值模拟MATLAB程序设计
11.2.1 微分方程组模拟
11.2.2 服从概率分布的随机模拟
11.2.3 蒙特卡罗模拟
11.3 动态仿真MATLAB程序设计
11.3.1 MATLAB音频处理
11.3.2 MATLAB常规动画实现
11.4 应用案例:四维水质模型
11.4.1 问题的提出
11.4.2 问题的分析
11.4.3 四维水质模型准备
11.4.4 条件假设与符号约定
11.4.5 四维水质模型的组建
11.4.6 模型求解
11.4.7 计算机模拟情境
参考文献
下篇 真题演习
第12章 彩票中的数学(CUMCM2002B)
12.1 问题的提出
12.2 模型的建立
12.2.1 模型假设与符号说明
12.2.2 模型的准备
12.2.3 模型的建立
12.3 模型的求解
12.3.1 求解的思路
12.3.2 MATLAB程序
12.3.3 程序结果
12.4 技巧点评
参考文献
第13章 露天矿卡车调度问题(CUMCM2003B)
13.1 问题的提出
13.2 基本假设与符号说明
13.2.1 基本假设
13.2.2 符号说明
13.3 问题分析及模型准备
13.4 原则①:数学模型(模型1)的建立与求解
13.4.1 模型的建立
13.4.2 模型求解
13.5 原则②:数学模型(模型2)的建立与求解
13.6 技巧点评
参考文献
第14章 奥运会商圈规划问题(CUMCM2004A)
14.1 问题的描述
14.2 基本假设、名词约定及符号说明
14.2.1 基本假设
14.2.2 符号说明
14.2.3 名词约定
14.3 问题分析与模型准备
14.3.1 基本思路
14.3.2 基本数学表达式的构建
14.4 设置MS网点数学模型的建立与求解
14.4.1 模型建立
14.4.2 模型求解
14.5 设置MS网点理论体系的建立
14.6 商区布局规划的数学模型
14.6.1 模型建立
14.6.2 模型求解
14.7 模型的评价及使用说明
14.7.1 模型的优点
14.7.2 模型的缺点
14.8 技巧点评
参考文献
第15章 交巡警服务平台的设置与调度(CUMCM2011B)
15.1 问题的提出
15.2 问题的分析
15.3 基本假设
15.4 问题1模型的建立与求解
15.4.1 交巡警服务平台管辖范围分配
15.4.2 交巡警的调度
15.4.3 最佳新增服务平台设置
15.5 问题2模型的建立和求解
15.5.1 全市服务平台的合理性分析问题的模型与求解
15.5.2 搜捕嫌疑犯实例的模型与求解
15.6 模型的评价与改进
15.6.1 模型优点
15.6.2 模型缺点
15.7 技巧点评
参考文献
第16章 葡萄酒的评价(CUMCM2012A)
16.1 问题的提出
16.2 基本假设
16.3 问题①模型的建立和求解
16.3.1 问题①的分析
16.3.2 模型的建立和求解
16.4 问题②模型的建立和求解
16.4.1 问题②的基本假设和分析
16.4.2 模型的建立和求解
16.5 问题③模型的建立和求解
16.5.1 问题③的分析
16.5.2 模型的建立和求解
16.6 问题④模型的建立和求解
16.6.1 问题④的分析
16.6.2 模型的建立和求解
16.7 论文点评
参考文献
附件数学建模参赛经验
一、如何准备数学建模竞赛
二、数学建模队员应该如何学习MATLAB
三、如何在数学建模竞赛中取得好成绩
四、数学建模竞赛中的项目管理和时间管理
五、一种非常实用的数学建模方法——目标建模法
Ⅳ 请高手帮忙编写关于K—mediods算法的MATLAB程序用于处理Iris数据集的聚类处理,得到迭代次数图形和准确率
我把K-mediods的matlab代码贴出来,你好好学习一下
function label = kmedoids( data,k,start_data )
% kmedoids k中心点算法函数
% data 待聚类的数据集,每一行是一个样本数据点
% k 聚类个数
% start_data 聚类初始中心值,每一行为一个中心点,有cluster_n行
% class_idx 聚类结果,每个样本点标记的类别
% 初始化变量
n = length(data);
dist_temp1 = zeros(n,k);
dist_temp2 = zeros(n,k);
last = zeros(n,1);
a = 0;
b = 0;
if nargin==3
centroid = start_data;
else
centroid = data(randsample(n,k),:);
end
for a = 1:k
temp1 = ones(n,1)*centroid(a,:);
dist_temp1(:,a) = sum((data-temp1).^2,2);
end
[~,label] = min(dist_temp1,[],2);
while any(label~=last)
for a = 1:k
temp2 = ones(numel(data(label==a)),1);
temp3 = data(label==a);
for b = 1:n
temp4 = temp2*data(b,:);
temp5 = sum((temp3-temp4).^2,2);
dist_temp2(b,a) = sum(temp5,1);
end
end
[~,centry_indx] = min(dist_temp2,[],1);
last = label;
centroid = data(centry_indx,:);
for a = 1:k
temp1 = ones(n,1)*centroid(a,:);
dist_temp1(:,a) = sum((data-temp1).^2,2);
end
[~,label] = min(dist_temp1,[],2);
end
end
Ⅵ 请教Louvain算法的Java程序(程序小白完全看不懂,希望大神详解)
Louvain算法主要针对文献[1]的一种实现,它是一种基于模块度的图算法模型,与普通的基于模块度和模块度增益不同的是,该算法速度很快,而且对一些点多边少的图,进行聚类效果特别明显,本文用的画图工具是Gephi,从画图的效果来说,提升是很明显的。
文本没有权威,仅是个人工作中的一点总结与思考,能力与时间有限,理解不免有些浅薄,仅做参考。也可能有理解偏差或错误,如有发现,希望不吝指教,多谢!
由于算法中的公式太多,不方便用markdown编辑,所以就将编排好的文档转成图片,如需完整的文档请点击这里下载。
Ⅶ 急求!!!matlab的K-均值聚类算法程序,采用下面的数据进行聚类分析。
没懂你是要如何聚类,如果是把(x1,x2)看成点集的话,直接
x1=[-0.5200
2.5849
0.9919
2.9443
-0.4240
1.7762
2.0581
1.5754
1.7971
0.4869
7.8736
8.1850
9.3666
8.4139
10.5374
9.1401
7.1372
8.5458]
x2=[1.8539
2.2481
1.9234
3.7382
3.6220
2.6264
2.0918
1.1924
1.5387
0.5940
7.6255
7.5291
9.7513
8.7532
8.0650
7.7072
8.0828
8.7662]
kmeans(X,4) %这里以分为4类为例,想分几类就写几
输出的结果就是每一行所对应的类编号了