c#的例子代码:
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());
}
}
} |