瀏覽代碼

More stuff done

Signed-off-by: wmb <wmb@teknik.io>
tags/v0.1.0
wmb 7 月之前
父節點
當前提交
7a3077c6bd
共有 2 個文件被更改,包括 123 次插入15 次删除
  1. 1
    0
      Makefile
  2. 122
    15
      main.c

+ 1
- 0
Makefile 查看文件

@@ -1,4 +1,5 @@
CFLAGS = -Wall -Wextra -Werror -pedantic-errors -std=c99 -g
CPPFLAGS = -D_POSIX_C_SOURCE=200809L
CC = gcc
LDLIBS = -lm


+ 122
- 15
main.c 查看文件

@@ -1,26 +1,57 @@
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>

#include <unistd.h>

#include "benchmark-data.h"

/* Fonctions */
/* TODO: Use typedefs for solution and vector instead of using int (*s)[230]
* and double (*v)[42]. */

/* Functions */
double distance(const double (*u)[42], const double (*v)[42]);
bool trouver_solution_initiale(void);
bool solution_valide(int (*s)[230]);
void print_solution(int (*s)[230], const char *name);
void centre_gravite(int cluster, int (*s)[230], double (*cg)[42]);
int solution_voisine(int (*dest)[230], int (*src)[230]);

int solution[230] = {0};
int new_solution[230] = {0};

int n_clusters = 5;
int n_iterations = 1000;

int main(int argc, char *argv[])
{
if (argc == 2) {
int k = atoi(argv[1]);
if (k > 0)
n_clusters = k;
int c;
int i;

while ((c = getopt(argc, argv, ":c:i:h")) != -1) {
int k;
switch (c) {
case 'c':
k = atoi(optarg);
if (k > 0)
n_clusters = k;
break;
case 'i':
k = atoi(optarg);
if (k > 0)
n_iterations = k;
break;
case 'h':
printf("Usage: %s [-c N_CLUSTERS] [-i N_ITERATIONS]", argv[0]);
exit(EXIT_SUCCESS);
break;
default:
exit(EXIT_FAILURE);
}
}

printf("Using %d clusters\n", n_clusters);
@@ -29,10 +60,19 @@ int main(int argc, char *argv[])

/* Solution initiale */
while (!trouver_solution_initiale())
; /* do it again */
continue; /* do it again */

print_solution(&solution, "initiale");

for (i = 0; i < n_iterations; i++) {

while (!solution_voisine(&new_solution, &solution))
continue; /* do it again */

/* TODO: Calculer les centres de gravités, les distances moyennes inter-/intra-cluster,
* et faire le reste de l'algorithme */
}

exit(EXIT_SUCCESS);
}

@@ -53,26 +93,36 @@ double distance(const double (*u)[42], const double (*v)[42])
}

bool trouver_solution_initiale(void)
{
size_t i;

for (i = 0; i < sizeof(solution) / sizeof(solution[0]); i++)
solution[i] = rand() % n_clusters;

return solution_valide(&solution);
}

bool solution_valide(int (*s)[230])
{
/* This function returns true if the solution that it found is "valid",
* i.e., it has at least one element in each cluster. */

bool *cluster_empty = calloc(n_clusters, sizeof *cluster_empty);
bool ret = false;
size_t i = 0;
bool valid = true;
int i;

for (i = 0; i < (size_t) n_clusters; i++)
for (i = 0; i < n_clusters; i++)
cluster_empty[i] = true;

for (i = 0; i < sizeof(solution) / sizeof(solution[0]); i++)
cluster_empty[solution[i] = rand() % n_clusters] = false;
for (i = 0; (size_t) i < sizeof(*s) / sizeof(*s[0]); i++)
cluster_empty[(*s)[i]] = false;

for (i = 0; !ret && i < (size_t) n_clusters; ++i)
ret = (ret || cluster_empty[i]);
for (i = 0; valid && i < n_clusters; i++)
valid = (valid && !cluster_empty[i]);

free(cluster_empty);

return !ret;
return valid;
}

void print_solution(int (*s)[230], const char *name)
@@ -94,3 +144,60 @@ void print_solution(int (*s)[230], const char *name)
printf("%d%s", (*s)[i++], end);
}
}

void centre_gravite(int cluster, int (*s)[230], double (*cg)[42])
{
/* Calculer le centre de gravité pour les vecteurs du cluster cluster selon la solution s */

const size_t n = sizeof(*cg) / sizeof((*cg)[0]); /* nombre d'attributs dans chaque vecteur. n = 42 */
const size_t nv = sizeof(benchmark_data) / sizeof(benchmark_data[0]); /* nombre de vecteurs. nv = 230 */
size_t i = 0;

assert(n == 42);
assert(nv == 230);

/* Initialiser à 0 */
while (i < n)
(*cg)[i++] = 0;

/* Loop over all vectors */
for (i = 0; i < nv; i++) {
size_t j = 0;

if ((*s)[i] != cluster)
/* Vector i is not part of the cluster, skip it */
continue;

while (j < n)
(*cg)[j] += benchmark_data[i][j];
}

for (i = 0; i < n; i++) {
(*cg)[i] /= n;
}
}

int solution_voisine(int (*dest)[230], int (*src)[230])
{
/* This function changes about 10% of the solution randomly */

memcpy(*dest, *src, sizeof(*src));

const size_t n = sizeof(*src) / sizeof((*src)[0]);
size_t i;
const int a = 10000; /* b = 10% of a */
const int b = 1000;

assert(n == 230);

for (i = 0; i < n; i++) {
if (rand() % a < b) {
int new_cluster = rand() % (n_clusters - 1);
/* To avoid the case where the cluster isn't actually changed. */
new_cluster += (new_cluster >= (*src)[i]);
(*dest)[i] = new_cluster;
}
}

return solution_valide(dest);
}

Loading…
取消
儲存