Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <math.h>
- #define VECTORSIZE 2
- int randInt (int min, int max) {
- return (rand() % (max - min + 1)) + min;
- }
- struct vec2 {
- double x;
- double y;
- };
- struct vec2 vectorPlus (struct vec2 a, struct vec2 b) {
- a.x += b.x;
- a.y += b.y;
- return a;
- }
- struct vec2 vectorSubtract (struct vec2 a, struct vec2 b) {
- a.x -= b.x;
- a.y -= b.y;
- return a;
- }
- struct vec2 vectorScalarMultiply (double scalar, struct vec2 vector) {
- vector.x *= scalar;
- vector.y *= scalar;
- return vector;
- }
- double calculateDistance (struct vec2 a, struct vec2 b) {
- struct vec2 c = vectorSubtract(a, b);
- return sqrt(pow(c.x, 2) + pow(c.y, 2));
- }
- int main() {
- srand(time(NULL));
- double learning_rate = 0.001;
- // Reading the inputs
- struct vec2 inputs[1000];
- struct vec2 input;
- int input_num = 0;
- while (scanf("%lf,%lf\n", &input.x, &input.y) != EOF) {
- inputs[input_num] = input;
- input_num++;
- }
- int cluster_size;
- int i = 0;
- double xmin_cost = 99999999;
- double previous_cost = 999999999;
- struct vec2 *xbest_centroids = NULL;
- for (cluster_size = 2; cluster_size < input_num; cluster_size++) {
- double min_cost = 9999999;
- struct vec2 best_centroids[cluster_size];
- for (i = 0; i < 100; i++) {
- // randIntizing centroids by picking non repeating inputs
- struct vec2 centroids[cluster_size];
- int cluster_index = 0;
- int lookup[input_num];
- int j;
- for (j = 0; j < input_num; j++) lookup[j] = 0;
- for (; cluster_index < cluster_size; ) {
- int rand_num = randInt(0, input_num);
- if (lookup[rand_num] == 1) continue;
- lookup[rand_num] = 1;
- centroids[cluster_index] = inputs[rand_num];
- cluster_index++;
- }
- // Starting the training process by iterating N times
- double cost = 0;
- for (j = 0; j < 500; j++) {
- int k;
- for (k = 0; k < input_num; k++) {
- // randIntizing an input
- //struct vec2 rand_input = inputs[randInt(0, input_num)];
- struct vec2 rand_input = inputs[k];
- // Looking for the nearest centroid
- double min_distance = 999999;
- struct vec2 *min_centroid = NULL;
- for (cluster_index = 0; cluster_index < cluster_size; cluster_index++) {
- double distance = calculateDistance(rand_input, centroids[cluster_index]);
- if (distance < min_distance) {
- min_distance = distance;
- min_centroid = ¢roids[cluster_index];
- }
- }
- // Updating the centroids coordinates
- *min_centroid = vectorPlus(
- *min_centroid,
- vectorScalarMultiply(
- learning_rate,
- vectorSubtract(rand_input, *min_centroid)
- )
- );
- cost += pow(min_distance, 2);
- }
- }
- cost /= input_num * 500.0;
- if (cost < min_cost) {
- min_cost = cost;
- for (j = 0; j < cluster_size; j++) {
- best_centroids[j] = centroids[j];
- }
- }
- }
- printf("%lf\n", previous_cost - min_cost);
- if ((input_num * 500.0) * (previous_cost - min_cost) < 500) break;
- previous_cost = min_cost;
- if (min_cost < xmin_cost) {
- xmin_cost = min_cost;
- xbest_centroids = malloc(cluster_size * VECTORSIZE * sizeof(struct vec2));
- for (i = 0; i < cluster_size; i++) {
- xbest_centroids[i] = best_centroids[i];
- }
- }
- }
- cluster_size--;
- for (i = 0; i < cluster_size; i++) {
- printf("%lf,%lf\n", xbest_centroids[i].x, xbest_centroids[i].y);
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment