k均值算法是模式识别的聚分类问题,这是用C#实现其算法 以下是程序源代码: using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace KMean_win { /// /// Form1 的摘要说明。 /// public class Form1 : System.Windows.Forms.Form { /// /// 必需的设计器变量。 /// private System.ComponentModel.Container components = null; private static int k = 2; //类数,此例题为2类 private static int total = 20; //点个数 private int test = 0; private PointF[] unknown = new PointF[total]; //点数组 private int[] type = new int[total]; //每个点暂时的类 public PointF[] z = new PointF[k]; //保存新的聚类中心 public PointF[] z0 = new PointF[k]; //保存上一次的聚类中心 private PointF sum; private int temp = 0; private System.Windows.Forms.TextBox textBox1; private int l = 0; //迭代次数 //构造
,初始化 public Form1() { unknown[0]=new Point(0,0); unknown[1]=new Point(1,0); unknown[2]=new Point(0,1); unknown[3]=new Point(1,1); unknown[4]=new Point(2,1); unknown[5]=new Point(1,2); unknown[6]=new Point(2,2); unknown[7]=new Point(3,2); unknown[8]=new Point(6,6); unknown[9]=new Point(7,6); unknown[10]=new Point(8,6); unknown[11]=new Point(6,7); unknown[12]=new Point(7,7); unknown[13]=new Point(8,7); unknown[14]=new Point(9,7); unknown[15]=new Point(7,8); unknown[16]=new Point(8,8); unknown[17]=new Point(9,8); unknown[18]=new Point(8,9); unknown[19]=new Point(9,9); InitializeComponent(); test = 0; //选k个初始聚类中心 z[i] for(int i=0;i z[i] = unknown[i]; for(int i=0;i type[i] = 0; } //计算新的聚类中心 public PointF newCenter(int m) { int N = 0; for(int i=0;i { if(type[i] == m) { sum.X = unknown[i].X+sum.X; sum.Y = unknown[i].Y+sum.Y; N += 1; } } sum.X=sum.X/N; sum.Y=sum.Y/N; return sum; } //比较两个聚类中心的是否相等 private bool compare(PointF a,PointF b) { if(((int)(a.X*10) == (int)(b.X*10)) && ((int)(a.X*10) == (int)(b.X*10))) return true; else return false; } //进行迭代,对total个样本根据聚类中心进行分类 private void order() { int temp = 0;//
unknown[i]暂时在哪个类中 for(int i=0;i { for(int j=0;j { if(distance(unknown[i],z[temp]) > distance(unknown[i],z[j])) temp = j; } type[i] = temp; Console.WriteLine("经比较后,{0}归为{1}类",unknown[i],temp); } } //计算两个点的欧式距离 private float distance(PointF p1,PointF p2) { return((p1.X-p2.X)*(p1.X-p2.X)+ (p1.Y-p2.Y)*(p1.Y-p2.Y)); } /// /// 清理所有正在使用的资源。 /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } //程序结构 public void main() { Console.WriteLine("共有如下个未知样本:"); for(int i=0;i { Console.WriteLine(unknown[i]); } /* for(int i=0;i Console.WriteLine("初始时,第{0}类中心{1}",i,z[i]); order(); for(int i=0;i { z[i] = newCenter(i); Console.WriteLine("第{0}类新中心{1}",i,z[i]); if(z[i].Equals(z0[i]) ) test = test+1; else z0[i] = z[i]; } */ for(int i=0;i Console.WriteLine("初始时,第{0}类中心{1}",i,z[i]); while( test!=k ) { order(); for(int i=0;i { z[i] = newCenter(i); Console.WriteLine("第{0}类新中心{1}",i,z[i]); if(compare(z[i],z0[i])) test = test+1; else z0[i] = z[i]; } l = l+1; Console.WriteLine("******已完成第{0}次迭代*******",l); Console.Write("{0}","分类后:"); for(int j=0;j { Console.Write("第{0}类有:",j); for(int i=0;i { if(type[i] == j) Console.WriteLine("{0},{1}",unknown[i].X,unknown[i].Y); } } } } #region Windows 窗体设计器生成的代码 /// /// 设计器支持所需的
- 不要使用代码编辑器修改 /// 此方法的内容。 /// private void InitializeComponent() { this.textBox1 = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(0, 0); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.textBox1.Size = new System.Drawing.Size(296, 272); this.textBox1.TabIndex = 0; this.textBox1.Text = ""; // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(292, 271); this.Controls.Add(this.textBox1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion } class entrance { /// /// 应用程序的主入口点。 /// [STAThread] static void Main() { Form1 my = new Form1(); my.main(); Application.Run(new Form1()); } } }