|
|
|
ช่วยอธิบายโค้ด kmean ด้วยคะ ว่าแต่ละคำสั่งมันหมายความว่าอะไรคะ |
|
|
|
|
|
|
|
Code (C#)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using System.Drawing;
using System.Diagnostics;
using System.Windows;
using System.Threading.Tasks;
namespace KMeans
{
public class KMeansWorker
{
private PointPlane pointPlane;
public void Cluster(PointPlane pointPlane, int width, int height, int dataPoints)
{
var random = new MersenneTwister();
int clusters = 15;
var points = new List<Point>();
this.pointPlane = pointPlane;
for (int i = 0; i < dataPoints; i++)
{
int x = random.Next(0, width);
int y = random.Next(0, height);
var point = new Point(x, y);
points.Add(point);
point.Color = Color.Black;
}
pointPlane.DrawPoints(points);
var randomCenters = PickRandomCenters(random, clusters, points);
var sw = new Stopwatch();
sw.Start();
ProcessGroups(points, randomCenters);
sw.Stop();
DisplayTiming("Single Threaded:", sw.Elapsed);
Dispatcher.CurrentDispatcher.Invoke(new Action(() => pointPlane.Clear()));
sw.Reset();
sw.Start();
ParallelProcessGroups(points, randomCenters);
sw.Stop();
DisplayTiming("Parallel:", sw.Elapsed);
}
private void ProcessGroups(List<Point> points, List<Point> randomCenters)
{
Dictionary<Point, List<Point>> centerAssignments = GetCenterAssignments(points, randomCenters);
ColorClusters(centerAssignments);
List<Point> oldCenters = null;
while (true)
{
//calculate average center
List<Point> newCenters = GetNewCenters(centerAssignments);
if (CentersEqual(newCenters, oldCenters))
{
break;
}
centerAssignments = GetCenterAssignments(points, newCenters);
ColorClusters(centerAssignments);
oldCenters = newCenters;
}
}
private void ParallelProcessGroups(List<Point> points, List<Point> randomCenters)
{
Dictionary<Point, List<Point>> centerAssignments = ParallelGetCenterAssignments(points, randomCenters);
ColorClusters(centerAssignments);
List<Point> oldCenters = null;
while (true)
{
//calculate average center
List<Point> newCenters = ParallelGetNewCenters(centerAssignments);
if (CentersEqual(newCenters, oldCenters))
{
break;
}
centerAssignments = ParallelGetCenterAssignments(points, newCenters);
ColorClusters(centerAssignments);
oldCenters = newCenters;
}
}
private static List<Point> PickRandomCenters(MersenneTwister random, int clusters, List<Point> points)
{
//pick random points
var randomCenters = new List<Point>();
int pickedPointCount = 0;
while (pickedPointCount < clusters)
{
var point = points[random.Next(0, points.Count - 1)];
if (!randomCenters.Contains(point))
{
randomCenters.Add(point);
pickedPointCount++;
}
}
return randomCenters;
}
private bool CentersEqual(List<Point> newCenters, List<Point> oldCenters)
{
if (newCenters == null || oldCenters == null)
{
return false;
}
foreach (Point newCenter in newCenters)
{
bool found = false;
foreach (Point oldCenter in oldCenters)
{
if (newCenter.X == oldCenter.X && newCenter.Y == oldCenter.Y)
{
found = true;
break;
}
}
if (!found)
{
return false;
}
}
return true;
}
private void DisplayTiming(string message, TimeSpan timespan)
{
Dispatcher.CurrentDispatcher.Invoke(new Action(() => MessageBox.Show(message + timespan.TotalSeconds.ToString())));
}
private List<Point> GetNewCenters(Dictionary<Point, List<Point>> centerAssignments)
{
double totalX = 0;
double totalY = 0;
var newCenters = new List<Point>();
foreach (Point center in centerAssignments.Keys)
{
totalX = 0;
totalY = 0;
foreach (Point point in centerAssignments[center])
{
totalX += point.X;
totalY += point.Y;
}
double averageX = totalX / centerAssignments[center].Count;
double averageY = totalY / centerAssignments[center].Count;
var newCenter = new Point((int)averageX, (int)averageY);
newCenters.Add(newCenter);
newCenter.Color = Color.Black;
pointPlane.DrawPoint(newCenter);
}
return newCenters;
}
private List<Point> ParallelGetNewCenters(Dictionary<Point, List<Point>> centerAssignments)
{
var newCenters = new Point[centerAssignments.Keys.Count];
Parallel.ForEach(centerAssignments.Keys, (center, state, i) =>
{
double totalX = 0;
double totalY = 0;
foreach (Point point in centerAssignments[center])
{
totalX += point.X;
totalY += point.Y;
}
double averageX = totalX / centerAssignments[center].Count;
double averageY = totalY / centerAssignments[center].Count;
var newCenter = new Point((int)averageX, (int)averageY);
newCenters[i] = newCenter;
newCenter.Color = Color.Black;
});
foreach (Point newCenter in newCenters)
{
pointPlane.DrawPoint(newCenter);
}
return newCenters.ToList();
}
private Dictionary<Point, List<Point>> GetCenterAssignments(List<Point> points, List<Point> centers)
{
var centerAssignments = new Dictionary<Point, List<Point>>();
//make them red
foreach (Point point in centers)
{
point.Color = Color.Red;
centerAssignments.Add(point, new List<Point>());
}
pointPlane.DrawPoints(centers);
foreach (Point point in points)
{
double x = point.X;
double y = point.Y;
Point closestCenter = null;
double closestCenterDistance = double.MaxValue;
foreach (Point centerPoint in centers)
{
double centerX = centerPoint.X;
double centerY = centerPoint.Y;
double distance = Math.Sqrt(Math.Pow(x - centerX, 2) + Math.Pow(y - centerY, 2));
if (distance < closestCenterDistance)
{
closestCenterDistance = distance;
closestCenter = centerPoint;
}
}
lock (centerAssignments)
{
centerAssignments[closestCenter].Add(point);
}
}
return centerAssignments;
}
private Dictionary<Point, List<Point>> ParallelGetCenterAssignments(List<Point> points, List<Point> centers)
{
var centerAssignments = new Dictionary<Point, List<Point>>();
//make them red
foreach (Point point in centers)
{
point.Color = Color.Red;
centerAssignments.Add(point, new List<Point>());
}
pointPlane.DrawPoints(centers);
//Parallel.ForEach(points, point =>
points.AsParallel().ForAll(point =>
{
double x = point.X;
double y = point.Y;
Point closestCenter = null;
double closestCenterDistance = double.MaxValue;
foreach (Point pickedPoint in centers)
{
double centerX = pickedPoint.X;
double centerY = pickedPoint.Y;
double distance = Math.Sqrt(Math.Pow(x - centerX, 2)
+ Math.Pow(y - centerY, 2));
if (distance < closestCenterDistance)
{
closestCenterDistance = distance;
closestCenter = pickedPoint;
}
}
lock (centerAssignments)
{
centerAssignments[closestCenter].Add(point);
}
});
return centerAssignments;
}
private void ColorClusters(Dictionary<Point, List<Point>> centerAssignments)
{
var colorStack = new Stack<Color>();
colorStack.Push(Color.Red);
colorStack.Push(Color.Blue);
colorStack.Push(Color.Orange);
colorStack.Push(Color.Purple);
colorStack.Push(Color.Green);
colorStack.Push(Color.Magenta);
colorStack.Push(Color.Fuchsia);
colorStack.Push(Color.Gold);
colorStack.Push(Color.Lavender);
colorStack.Push(Color.Maroon);
colorStack.Push(Color.Orchid);
colorStack.Push(Color.Pink);
colorStack.Push(Color.YellowGreen);
colorStack.Push(Color.PaleGreen);
colorStack.Push(Color.Beige);
//group
foreach (Point center in centerAssignments.Keys)
{
Color color = colorStack.Pop();
center.Color = color;
foreach (Point point in centerAssignments[center])
{
point.Color = color;
}
pointPlane.DrawPoint(center);
pointPlane.DrawPoints(centerAssignments[center]);
}
}
}
}
Tag : .NET, C#
|
|
|
|
|
|
Date :
2010-10-08 12:38:57 |
By :
PP |
View :
1274 |
Reply :
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
คร่าว ๆ ก็เป็น code เกี่ยวกับรูปภาพ read/write จัดการรูปภาพครับ
|
|
|
|
|
Date :
2010-10-12 13:40:47 |
By :
webmaster |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Load balance : Server 03
|