//
// GroupPoint.h
// Kmean
//
// Created by zmx on 16/2/26.
// Copyright © 2016年 zmx. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface GroupPoint : NSObject
@property (nonatomic, assign) CGFloat x;
@property (nonatomic, assign) CGFloat y;
@property (nonatomic, assign) int group;
@end
//
// main.m
// Kmean
//
// Created by zmx on 16/2/26.
// Copyright © 2016年 zmx. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "GroupPoint.h"
CGFloat distance(GroupPoint *p1, GroupPoint *p2) {
return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
void kMean(NSArray *points, int k) {
NSMutableArray *meanPoints = [NSMutableArray array];
for (int i = 0; i < k; i ++) {
GroupPoint *point = [points objectAtIndex:i];
GroupPoint *meanPoint = [[GroupPoint alloc] init];
meanPoint.x = point.x;
meanPoint.y = point.y;
[meanPoints addObject:meanPoint];
}
while (YES) {
for (int i = 0; i < points.count; i++) {
GroupPoint *point = [points objectAtIndex:i];
GroupPoint *meanPoint = [meanPoints objectAtIndex:0];
CGFloat minDis = distance(point, meanPoint);
int m = 0;
for (int j = 1; j < k; j++) {
meanPoint = [meanPoints objectAtIndex:j];
CGFloat dis = distance(point, meanPoint);
if (minDis > dis) {
minDis = dis;
m = j;
}
}
point.group = m;
}
double *xSums = (double *)malloc(sizeof(double) * k);
double *ySums = (double *)malloc(sizeof(double) * k);
int *ns = (int *)malloc(sizeof(int) * k);
for (int i = 0; i < points.count; i++) {
GroupPoint *point = [points objectAtIndex:i];
int group = point.group;
xSums[group] += point.x;
ySums[group] += point.y;
ns[group]++;
}
BOOL noChange = YES;
for (int i = 0; i < k; i++) {
GroupPoint *meanPoint = [meanPoints objectAtIndex:i];
CGFloat x = xSums[i] / ns[i];
CGFloat y = ySums[i] / ns[i];
if (x == meanPoint.x && y == meanPoint.y) {
} else {
meanPoint.x = x;
meanPoint.y = y;
noChange = NO;
}
}
if (noChange) {
break;
}
}
for (int i = 0; i < k; i++) {
GroupPoint *meanPoint = [meanPoints objectAtIndex:i];
printf("(%lf, %lf) ", meanPoint.x, meanPoint.y);
}
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
GroupPoint *p1 = [[GroupPoint alloc] init];
p1.x = 2;
p1.y = 1;
GroupPoint *p2 = [[GroupPoint alloc] init];
p2.x = 1;
p2.y = 3;
GroupPoint *p3 = [[GroupPoint alloc] init];
p3.x = 6;
p3.y = 7;
GroupPoint *p4 = [[GroupPoint alloc] init];
p4.x = 4;
p4.y = 7;
NSArray *points = @[p1, p2, p3, p4];
kMean(points, 2);
for (int i = 0; i < points.count; i++) {
GroupPoint *point = [points objectAtIndex:i];
printf("%d ", point.group);
}
}
return 0;
}