K-mean clustering, Probleme beim Bilden einer Spaltensumme



  • Liebe C/C++-Kenner,

    ich habe ein k-Means-Clustering Programm geschrieben, um mir etwas Arbeit bei einer wissenschaftlichen Hausarbeit zu sparen. Dabei habe ich schon von von einigen hier in diesem Forum gute Tipps bekommen. Nun habe ich es aber etwas geändert und stehe vor einem neuen, hoffentlich letzten Problem.

    Ich habe Datenpunkte mit drei Dimensionen. Dabei will ich nach den ersten zwei Dimension clustern. Das klappt auch gut.

    Dann will ich, dass das Programm für jedes einzelne Cluster die dritte Dimension der einzelnen Punkte addiert. Wenn die Summe größer als ein vorgegebener Wert x (hier z.B. 200) ist, dann soll ein Hinweis kommen, dass es Probleme mit der Kapazität gibt. Mein Ansatz war, eine if-else-Schleife zu nutzen (siehe ganz unten), aber ich bin ratlos wie ich dem Programm sagen kann, dass er nur die Punkte des jeweiligen Clusters und nicht alle Punkte summieren soll.
    Ich wäre euch sehr dankbar, wenn es jemanden gibt, der mir hier auf die Sprünge helfen kann.

    Außerdem: Wie kann ich dem Programm befehlen, dass es sich selbst beendet, sollte die Kapazitätsgrenze überschritten sein?

    Seid bitte nachsichtig mit mir, wenn das Programm nicht tiptop geschrieben ist, ich hatte nur einmal einen kleinen C-Programmierkurs im Mathestudium Zur Info: Ich nutze Xcode auf Mac OS X.

    Vielen Dank schonmal im Voraus

    #include <stdio.h>
    #include <math.h>
    using namespace std;

    int main()
    {
    int i, j;

    float dmin, dpoint;
    float sum[100][2];
    int cluster[100], count[100], group;
    float flips;
    const int rows = 100;
    const int columns = 3;
    const int crows = 10;
    const int ccolumns = 2;
    int maximum;
    int capacity;
    bool gmatrix[100][10];

    // initialize the points

    int point[rows][columns]={{45,68,10},{45,70,30},{42,66,10},{42,68,10},{42,65,10},{40,69,20},{40,66,20},{38,68,20},{38,70,10},{35,66,10},{35,69,10},{25,85,20},{22,75,30},
    {22,85,10},{20,80,40},{20,85,40},{18,75,20},{15,75,20},{15,80,10},{30,50,10},{30,52,20},{28,52,20},{28,55,10},{25,50,10},{25,52,40},{25,55,10},{23,52,10},{23,55,20},{20,50,10},
    {20,55,10},{10,35,20},{10,40,30},{8,40,40},{8,45,20},{5,35,10},{5,45,10},{2,50,20},{0,40,30},{0,45,20},{35,30,10},{35,32,10},{33,32,20},{33,35,10},{32,30,10},{30,30,10},{30,32,30},
    {30,35,10},{28,30,10},{28,35,10},{26,32,10},{25,30,10},{25,35,10},{44,5,20},{42,10,40},{42,15,10},{40,5,30},{40,15,40},{38,5,30},{38,15,10},{35,5,20},{50,30,10},{50,35,20},
    {50,40,50},{48,30,10},{48,40,10},{47,35,10},{47,40,10},{45,30,10},{45,35,10},{95,30,30},{95,35,20},{53,50,10},{92,30,10},{53,35,50},{45,65,20},{90,35,10},{88,30,10},{88,35,20},
    {87,30,10},{85,25,10},{85,35,30},{75,55,20},{72,55,10},{70,58,20},{68,60,30},{66,55,10},{65,55,20},{65,60,30},{63,58,10},{60,55,10},{60,60,10},{67,85,20},{65,85,40},{65,82,10},
    {62,80,30},{60,80,10},{60,85,30},{58,75,20},{55,80,10},{55,85,20}};

    // initialize the centroids

    double centroid [crows][ccolumns] = {{45,68},{45,70},{42,66},{42,68},{42,65},{40,69},{40,66},{38,68},{38,70},{35,66}};

    // ...

    for (i = 0; i<100; i++) cluster[i] = 0;

    // until there is no change of clusters belonging to each pattern, continue

    flips = 100;
    while (flips>0) {

    // reset the group matrix
    for (i=0; i<100; i++) {
    for (int j=0; j<10; j++) {
    gmatrix[i][j]=false;
    }
    }

    flips = 0;
    flips = 0;

    for (j = 0; j < 10; j++)
    {
    count[j] = 0;
    for (i = 0; i < 2; i++)
    sum[j][i] = 0;
    }

    // now, we need to calculate the distance

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

    dmin = 2000; group = cluster[i];
    for (j = 0; j < 10; j++)
    {

    dpoint = 0.0;

    dpoint += sqrt(pow((point[i][0] - centroid[j][0]),2)+pow((point[i][1] - centroid[j][1]),2));
    fprintf(stdout, "%2.2f ", dpoint); // Show the value of the distance
    if (dpoint < dmin) {
    group = j;
    dmin = dpoint;
    }
    }

    // now, we need to calculate the G matrix (0,1,...,9)

    fprintf(stdout, " * %d *\n", group); // displays 0,1,...,9(to which cluster it belongs)

    gmatrix[i][group]=true;

    if (cluster[i] != group)
    {
    flips++;
    cluster[i] = group; // repeat this process until G(n)=G(n+1)
    }

    count[cluster[i]]++;

    for (j = 0; j < 2; j++)
    sum[cluster[i]][j] += point[i][j];
    }

    // now, display the coordinates of the centroid

    for (i = 0; i < 10; i++) {
    fprintf(stderr," \n The coordinates of the centroid are: ");
    for (j = 0; j < 2; j++) {
    centroid[i][j] = sum[i][j]/count[i];
    fprintf(stderr, "%2.2f ", centroid[i][j]);

    }

    } fprintf(stdout, "\n");

    }
    fprintf(stdout, "\n");

    for (int i=0; i<100; i++) {
    for (int j=0; j<10; j++) {
    fprintf(stderr, " %d ", gmatrix[i][j]);
    }
    fprintf(stderr, "\n");
    }

    //capacity restriction
    {
    maximum += 200; //gives maximum capacity restriction
    {

    for (i = 0; i < 100; i++)

    {
    capacity = 0;
    capacity += point[cluster[i]][2];

    }
    if ( capacity > maximum )
    {
    fprintf(stderr, "Problems with maximal capacity");
    }
    else
    {
    fprintf(stderr, "\nCapacity is OK\n");
    }

    }
    }

    }


Log in to reply