using
System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace SimpleKmean
{
class Program
{
static int LoopCount = 1;
static bool RecursiveFlag = false;
static void Main(string[] args)
{
int[,] Nodes;
int[,] Classes;
System.Console.Write("how many nodes
do you want? :");
// int NodeNumber =
Convert.ToInt32(System.Console.ReadLine());
int NodeNumber = 15;
System.Console.Write("how many
classes do you want? :");
// int ClassNumber =
Convert.ToInt32(System.Console.ReadLine());
int ClassNumber = 3;
Nodes = new int[NodeNumber, 3]; // index -> x = 0
, y = 1 , classFlag = 3
Classes = new int[NodeNumber, 2]; // classnumber
coordinate , clustering coordinates
Console.WriteLine();
// get random
coordinates
//隨機產生15個點
for (int i = 0; i <
NodeNumber; i++)
{
Random Random = new Random((int)DateTime.Now.Millisecond);
Thread.Sleep(20); //亂數的產生
// get x
Nodes[i, 0] = Random.Next(0,
10);
// get y
Nodes[i, 1] = Random.Next(0,
10);
System.Console.WriteLine("({0},{1})", Nodes[i, 0],
Nodes[i, 1]);
}
System.Console.WriteLine("-----------------");
// get random class
// 隨機產生class位置
for (int i = 0; i <
ClassNumber; i++)
{
Random random = new Random((int)DateTime.Now.Millisecond);
Thread.Sleep(20); //亂數的產生
// get x
Classes[i, 0] = random.Next(0,
10);
// get y
Classes[i, 1] = random.Next(0,
10);
System.Console.WriteLine("class[{0}]--({1},{2})", i, Classes[i, 0],
Classes[i, 1]);
}
System.Console.WriteLine("---------------------------------------------------");
Console.WriteLine("\n");
Kmean(NodeNumber, ClassNumber,
Nodes, Classes);
System.Console.WriteLine("=================================");
System.Console.WriteLine("finish!
recusive times : {0}", LoopCount);
// ShowResult(Nodes,
NodeNumber, Classes, ClassNumber);
System.Console.WriteLine("Press any key
to continue...");
System.Console.ReadKey();
}
// use the euclidean
distane to calculate two coordinates.
// 勾股定理計算距離
static double Distance(int x1, int y1, int x2, int y2)
{
return Math.Sqrt(Math.Pow((x1 - x2), 2) +
Math.Pow((y1 - y2), 2));
}
// procedure that
show the group
//顯示每組產生的過程
static void ShowResult(int[,] Nodes, int NodeNumber, int[,] Classes, int ClassNumber)
{
for (int i = 0; i <
ClassNumber; i++)
{
System.Console.WriteLine("class[{0}]--({1},{2})", i, Classes[i, 0],
Classes[i, 1]);
}
System.Console.WriteLine("-------------------");
for (int i = 0; i <
NodeNumber; i++)
{
System.Console.WriteLine("({0},{1})
--> class[{2}]", Nodes[i, 0], Nodes[i, 1], Nodes[i, 2]);
}
}
// K-means Algorithm
//Kmeans計算
static void Kmean(int NodeNumber, int ClassNumber, int[,] Nodes, int[,] Classes)
{
// calculate the
distance between the class and the coordinate .
for (int i = 0; i <
NodeNumber; i++)
{
double min = 100000;
for (int j = 0; j <
ClassNumber; j++)
{
double mindDistance =
Distance(Nodes[i, 0], Nodes[i, 1], Classes[j, 0], Classes[j, 1]);
if (mindDistance <
min)
{
min = mindDistance;
Nodes[i, 2] = j; // flag to set the
group that the coordinate belong to.
}
}
}
// ShowResult(Nodes,
NodeNumber, Classes, ClassNumber);
// calculate the new
center class
//
int[,] TempClasses = new int[ClassNumber, 3];
for (int j = 0; j <
ClassNumber; j++)
{
int[] TempCoordinate = new int[2];
for (int i = 0; i <
NodeNumber; i++)
{
if (Nodes[i, 2] == j)
{
// new class
TempCoordinate[0] +=
Nodes[i, 0];
TempCoordinate[1] +=
Nodes[i, 1];
TempClasses[j, 2]++;
}
}
if (TempClasses[j, 2]
== 0)TempClasses[j, 2] = 1; //除法分母不為0
TempClasses[j, 0] =
TempCoordinate[0] / TempClasses[j, 2];
TempClasses[j, 1] =
TempCoordinate[1] / TempClasses[j, 2];
System.Console.WriteLine("count =
{3},class[{0}] :new cor ({1},{2})", j, TempClasses[j,
0], TempClasses[j, 1], TempClasses[j, 2]);
}
Console.WriteLine();
int k = 0;
for (k = 0; k <
ClassNumber; k++)
{
if ((TempClasses[k, 0]
!= Classes[k, 0]) || (TempClasses[k, 1] != Classes[k, 1]))
{
RecursiveFlag = true;
break;
}
}
if (k == ClassNumber)
RecursiveFlag = false;
if (RecursiveFlag == true) //New classes center point
{
for (int j = 0; j <
ClassNumber; j++)
{
Classes[j, 0] =
TempClasses[j, 0];
Classes[j, 1] = TempClasses[j,
1];
}
// System.Console.ReadKey();
// recursive
Kmean(NodeNumber, ClassNumber,
Nodes, Classes);
LoopCount++;
}
if (RecursiveFlag == false)
{
//
ShowResult(Nodes, NodeNumber, Classes, ClassNumber);
}
}
}
// procedure for check the same coordinates
}
沒有留言:
張貼留言