📄 fuzzy_c_mean.cpp
字号:
// fuzzy_c_mean.cpp: Implementierung der Klasse Cfuzzy_c_mean.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "fuzzy_c_mean.h"
//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////
/*
Author : Bernd Allmendinger
Date : 14.02.2000
e-mail : webmaster@neurocomputing.de
homepage : www.neurocomputing.de
Version : 1.0
*/
#define MAX_ITER 20000
Cfuzzy_c_mean::Cfuzzy_c_mean(int in, int ip, int im, int ic)
{ n=in; // Anzahl der Inputvekoren
p=ip; // Anzahl Dimension des Inputvekors x
m=im; // Berechnungsparmater normalerweise 2
c=ic; // Anzahl Clustors
anz_benoetigete_Iterationen=0;
Jm=0.0;// evaluation Function
At.setDim(1,c,1,n);
Att.setDim(1,c,1,n);
x.setDim(1,n,1,p);
v.setDim(1,c,1,p);
}
Cfuzzy_c_mean::~Cfuzzy_c_mean()
{
}
double Cfuzzy_c_mean::abstand_x_v(int k, int i)
{ int j;
double wert;
// ACHTUNG evenntuell normieren ??? Inner Productnorm
double abstand=0.0;
for(j=1; j<=p; j++)
{ wert = x.wert[k][j]-v.wert[i][j];
abstand += wert*wert;
}
return(sqrt(abstand));
}
double Cfuzzy_c_mean::JmA(CMatrix* A_m)
{ int k,i;
double Jma=0.0;
double abstand;
for(k=1; k<=n; k++)
{ for(i=1; i<=c; i++)
{ abstand = abstand_x_v(k, i);
Jma += pow(A_m->wert[i][k],m)*abstand*abstand;
}
}
return(Jma);
}
void Cfuzzy_c_mean::cluster_v(CMatrix* A_m)
{ // Gleichung (13.1)
int k,i,j;
double sum_nenner,sum_zaehler;
for(i=1; i<=c; i++)
{
sum_nenner=sum_zaehler=0.0;
for(k=1; k<=n; k++)
{ sum_nenner += pow(A_m->wert[i][k],m);
} // for k
for(j=1; j<=p; j++)
{ sum_zaehler=0.0;
for(k=1; k<=n; k++)
{ sum_zaehler += pow(A_m->wert[i][k],m)*x.wert[k][j];
}
v.wert[i][j] = sum_zaehler/sum_nenner;
} // for j
} // for i
}
void Cfuzzy_c_mean::setArandom(CMatrix* A_m)
{ int k,i;
for(k=1; k<=n; k++)
{ for(i=1; i<=c; i++)
{
A_m->wert[i][k]= zufall(); // Zulassiges Intervall [0,1]
}
}
}
double Cfuzzy_c_mean::diff_A(CMatrix* A1, CMatrix* A2)
{ int k,i;
double differenz=0.0;
for(k=1; k<=n; k++)
{ for(i=1; i<=c; i++)
{
differenz += fabs(A1->wert[i][k]-A2->wert[i][k]);
}
}
return(differenz);
}
int Cfuzzy_c_mean::fuzzy_c_mean_cal() /*
------------------------------------- */
{ int k,i,j;
int anz_gleich_null;
int t=0;
double abstand_j,abstand_i, sum, minabstand;
CVektor Abstand;
Abstand.setDim(1,c);
// 1) Setzen von A(0) (t=0)
setArandom(&Att);
do
{ At=Att;
// 2) Berechnen der c Clusters v1(t) bis vc(t) uber (13.1)
cluster_v(&At);
// 3) Update the fuzzy clusters A(t+1) fuer jedes xk
for(k=1; k<=n; k++)
{ minabstand=100.0;
for(i=1; i<=c; i++)
{ abstand_i = abstand_x_v(k, i);
abstand_i = abstand_i*abstand_i;
Abstand.wert[i]=abstand_i;
if (minabstand>abstand_i)
minabstand=abstand_i;
}// for i
// 2
// a) ||xk-vi(t)|| > 0 fuer i =1,..,c
if (minabstand > 0.0)
{ for(i=1; i<=c; i++)
{ sum=0.0;
for(j=1; j<=c; j++)
{ abstand_j=abstand_x_v(k, j);
sum += pow(Abstand.wert[i]/(abstand_j*abstand_j), 1.0/((double) m-1.0));
} // for j
Att.wert[i][k]=1.0/sum;
} // for i
} // if minabstand > 0.0
else
{ // 2
// b) ||xk-vi(t)|| = 0 fuer ein i element I. I ist echte teilmenge von {1,..,c}
anz_gleich_null=0;
for(i=1; i<=c; i++)
{ if (Abstand.wert[i]==0.0)
{ Att.wert[i][k]=1.0;
anz_gleich_null++;
}
else
{ Att.wert[i][k]=0.0;
}
} // for i
for(i=1; i<=c; i++) // Normieren auf 1
{ Att.wert[i][k] /= (double) anz_gleich_null;
}
}
} // for k Uber a) und b)
// 4) wenn |A(t+1)-A(t)| < eps then stop, sonst t=t+1 und go to 2)
t++;
} while (diff_A(&At,&Att) > EPS && t < MAX_ITER);
anz_benoetigete_Iterationen=t;
return(t);
}
void Cfuzzy_c_mean::ausgabeErgebnisse() /*
------------------------------------- */
{ int k,i,j;
double WertZielfunktion;
char weiter[100];
printf("Fuzzy c mean Cluster Ergebnisse\n");
WertZielfunktion = JmA(&Att);
printf("Zielfunktion Jm(A) = %4.3f\n", WertZielfunktion);
printf("Anzahl benoetigter Iterationen = %d\n", anz_benoetigete_Iterationen);
printf("Anzahl Cluster = %d\n", c);
printf("\nCluster v\n\n");
// Ausgabe der Cluster v
for(i=1; i<=c; i++)
{ printf("Cluster %d\t", i);
for(j=1; j<=p; j++)
{ printf("%4.3f\t", v.wert[i][j]);
} // for k
printf("\n");
} // for j
// Ausgabe der Membershipfunktionen A
printf("\nMembership Funktion A\n\n");
printf("Cluster\t");
for(i=1; i<=c; i++)
{ printf("%d\t", i);
}
printf("\n");
for(k=1; k<=n; k++)
{ printf("n=%d\t", k);
for(i=1; i<=c; i++)
{ printf("%4.3f\t", Att.wert[i][k]);
}
printf("\n");
}
printf("Quit q:");
scanf( "%s" , weiter);
}
void Cfuzzy_c_mean::printErgebnisse() /*
------------------------------------- */
{ int k,i,j;
double WertZielfunktion;
FILE* fpt;
int bestercluster;
double maxmembership;
if (!(fpt = fopen("C:\\temp\\fcm_analyse.txt", "w")))
{ printf("Konnte File %s nicht oeffnen", "C:\\temp\\fcm_analyse");
return ;
}
fprintf(fpt, "Fuzzy c mean Cluster Ergebnisse\n");
fprintf(fpt, "===============================\n");
fprintf(fpt, "n [Anzahl Datensaetze]\t= %d\n", n);
fprintf(fpt, "p [Dimension des Inputvekor]\t= %d\n", p);
fprintf(fpt, "c [Anzahl Cluster]\t= %d\n", c);
fprintf(fpt, "m [Berechnungsparameter]\t= %d\n", m);
fprintf(fpt, "\n");
WertZielfunktion = JmA(&Att);
fprintf(fpt, "Zielfunktion Jm(A) = %4.3f\n", WertZielfunktion);
fprintf(fpt, "Anzahl benoetigter Iterationen = %d\n", anz_benoetigete_Iterationen);
fprintf(fpt, "Anzahl Cluster = %d\n", c);
fprintf(fpt, "\nCluster v\n");
fprintf(fpt, "----------\n");
// Ausgabe der Cluster v
for(i=1; i<=c; i++)
{ fprintf(fpt,"Cluster %d\t", i);
for(j=1; j<=p; j++)
{ fprintf(fpt, "%4.3f\t", v.wert[i][j]);
} // for k
fprintf(fpt, "\n");
} // for j
// Ausgabe der Membershipfunktionen A
fprintf(fpt, "\nMembership Funktion A\n");
fprintf(fpt, "---------------------\n");
fprintf(fpt, "Cluster\t");
for(i=1; i<=c; i++)
{ fprintf(fpt, "%d\t", i);
}
fprintf(fpt, "\n");
for(k=1; k<=n; k++)
{ fprintf(fpt, "n=%d\t", k);
for(i=1; i<=c; i++)
{ fprintf(fpt, "%4.3f\t", Att.wert[i][k]);
}
fprintf(fpt, "\n");
}
// Ausgabe Memberschip A und daten x
fprintf(fpt, "\nAusgabe Memberschip A und Daten x\n\n");
// Ausgabe der Ueberschrift
fprintf(fpt, "n\t");
for(i=1; i<=c; i++)
{ fprintf(fpt, "A%d\t", i);
}
fprintf(fpt, "BestC\t");
fprintf(fpt, "Daten\t");
for(i=1; i<=p; i++)
{ fprintf(fpt, "x%d\t", i);
}
fprintf(fpt, "\n");
// Ausgabe der Werte
for(k=1; k<=n; k++)
{ fprintf(fpt, "%d\t", k);
// Print A und Ermittlung des Besten Clusters
maxmembership=-1.0;
bestercluster = -1;
for(i=1; i<=c; i++)
{ fprintf(fpt, "%4.3f\t", Att.wert[i][k]);
if (Att.wert[i][k]>maxmembership)
{ maxmembership=Att.wert[i][k];
bestercluster=i;
}
}
fprintf(fpt, "%d\t", bestercluster);
// ----------------------------------
fprintf(fpt, "|\t");
// Print Daten
for(j=1; j<=p; j++)
{ fprintf(fpt, "%4.7f\t", x.wert[k][j]);
}
fprintf(fpt, "\n");
}
}
int Cfuzzy_c_mean::trimStrEnds (char* string) /*
------------------------------- */
{
char *sptr;
int n;
sptr = string;
while (*sptr==' ' || *sptr=='\t' || *sptr==0)
{ if (*sptr==0) break;
*sptr++;
}
strcpy (string,sptr);
n = strlen (string);
string += --n;
while (n>=0 && (*string==' ' || *string=='\t' || *string=='\n'))
{ n--;
string--;
}
*(string+1) = 0;
return (n+1);
}
// Naechstes wort aus String lesen. Worte muessen durch Blanks getrennt sein
// und die Zeile muss mit Semikolon abgeschlossen sein.
// Ein Wort ist auch * und -
int Cfuzzy_c_mean::hole_naechstes_wort(char* zeilex, char* wortx) /*
------------------------------------------------------------------ */
{ int i, laenge;
*wortx = '\0';
i=0;
laenge = strlen(zeilex);
trimStrEnds (zeilex);
do
{ wortx[i] = zeilex[i];
zeilex[i] = ' ';
i++;
} while (i <= laenge && zeilex[i] != ' ' && zeilex[i] != '\t');
wortx[i] = '\0';
trimStrEnds (zeilex);
trimStrEnds (wortx);
return(1);
}
int Cfuzzy_c_mean::einlesen_Matrix(char* pfad_str, CMatrix* M, int anz_zeilen, int anz_Spalten) /*
------------------------------------------------------- */
{ FILE *pro;
char str[2500], wort[100];
char *stopstring;
int i, j;
double wrt;
/* File Format:
Jede zeile enthaelt anz_Spalten Zahlen (ein Datensatzt)
Das File muss genau n anz_zeilen (Anzahl der datensaetze) enthalten
*/
*str = '\0';
if (!(pro = fopen(pfad_str, "r")))
{ printf("Konnte File %s nicht oeffnen", pfad_str);
return(0);
}
fgets (str, 2500, pro);
if (feof (pro)) return (0);
for (j=1; j <= anz_zeilen; j++)
{ for (i=1; i <= anz_Spalten; i++)
{ hole_naechstes_wort(str, wort);
wrt = strtod(wort, &stopstring);
M->wert[j][i] = wrt;
} // for j
if (feof (pro)) return (0);
fgets (str, 2500, pro);
} // for j
return(1);
}
double Cfuzzy_c_mean::zufall() /*
--------------- */
{ /* Erzeugt eine gleichverteilte Zufallszahl im Interval [0,1]
*/
return ((double) rand()/RAND_MAX);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -