00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdarg.h>
00028 #include "image.h"
00029 #include "proto2D.h"
00030 #include "ff_symb.h"
00031
00032
00033 int
00034 tn_zadeh(
00035 const degre_app* x,
00036 const degre_app* y,
00037 degre_app* z
00038 ){
00039 *z = MINI(*x, *y);
00040 return 0;
00041 }
00042
00043 int tc_zadeh(
00044 const degre_app* x,
00045 const degre_app* y,
00046 degre_app* z
00047 ){
00048 *z = MAXI(*x, *y);
00049 return 0;
00050 }
00051
00052 int tn_proba(
00053 const degre_app* x,
00054 const degre_app* y,
00055 degre_app* z
00056 ){
00057 *z = (*x) * (*y);
00058 return 0;
00059 }
00060
00061 int tc_proba(
00062 const degre_app* x,
00063 const degre_app* y,
00064 degre_app* z
00065 ){
00066 (*z) = (*x) + (*y) - (*x)*(*y);
00067 return 0;
00068 }
00069
00070 int tn_luk(
00071 const degre_app* x,
00072 const degre_app* y,
00073 degre_app* z
00074 ){
00075 degre_app tmp;
00076 tmp = *x+*y-1;
00077 *z = MAXI(tmp,0);
00078 }
00079
00080 int tc_luk(
00081 const degre_app* x,
00082 const degre_app* y,
00083 degre_app* z
00084 ){
00085 degre_app tmp;
00086 tmp = *x+*y;
00087 *z = MINI(tmp,1);
00088 }
00089
00090 int tn_weber(
00091 const degre_app* x,
00092 const degre_app* y,
00093 degre_app* z
00094 ){
00095 (*z) = (*x == 1) ? (*y) : ((*y == 1) ? (*x) : (0));
00096 return 0;
00097 }
00098
00099 int tc_weber(
00100 const degre_app* x,
00101 const degre_app* y,
00102 degre_app* z
00103 ){
00104 (*z) = (*x == 0) ? (*y) : ((*y == 0) ? (*x) : (1));
00105 return 0;
00106 }
00107
00108
00109
00110 init(char * filename, Fct_appartenance * fct, Les_regles * rules, Descripteur *dpteur)
00111 {
00112 FILE * fin;
00113 int i, j, tmp;
00114 int nb_regle=1;
00115 chaine var;
00116
00117 if( (fin=fopen(filename, "r")) == NULL) {
00118 printf("ERREUR: impossible d'ouvrir le fichier %s\n", filename);
00119 exit(1);
00120 }
00121
00122
00123 printf("lecture du nombre d'entree\n");
00124 fscanf(fin, "%d", &tmp);
00125 fct->nb_entree = (unsigned char)tmp;
00126 if( (fct->partition=(Partition *)malloc(fct->nb_entree*sizeof(Partition))) ==NULL){ printf("problème d'allocation mémoire.\n"); exit(1); }
00127
00128
00129 for(i=0; i<fct->nb_entree; i++)
00130 {
00131
00132 fscanf(fin, "%s %d", fct->partition[i].nom, &tmp );
00133 fct->partition[i].nb_fct = (unsigned char)tmp;
00134 if( (fct->partition[i].part = (Symbol *)malloc(fct->partition[i].nb_fct*sizeof(Symbol))) == NULL){
00135 printf("problème d'allocation mémoire.\n");
00136 exit(1);
00137 }
00138
00139
00140 for(j=0; j<fct->partition[i].nb_fct; j++)
00141 fscanf(fin, "%s %f %f %f", fct->partition[i].part[j].nom, &fct->partition[i].part[j].gauche, &fct->partition[i].part[j].mode, &fct->partition[i].part[j].droite);
00142 }
00143
00144
00145
00146 fscanf(fin, "%d", &rules->nb_regle);
00147 if( (rules->regle=(Une_regle *)malloc(rules->nb_regle * sizeof(Une_regle))) ==NULL){
00148 printf("problème d'allocation mémoire.\n");
00149 exit(1);
00150 }
00151
00152 for(i=0; i<rules->nb_regle; i++)
00153 if( (rules->regle[i].liste_in = (unsigned char *)calloc( fct->nb_entree-1, sizeof(unsigned char)) ) == NULL){
00154 printf("problème d'allocation mémoire.\n");
00155 exit(1);
00156 }
00157
00158
00159
00160 for(j=0; j<rules->nb_regle; j++) {
00161 for(i=0; i<fct->nb_entree-1; i++){
00162 fscanf(fin, "%s", var);
00163 tmp = 0;
00164 while(strcmp(var,fct->partition[i].part[tmp].nom)!=0)
00165 tmp++;
00166 rules->regle[j].liste_in[i] = tmp;
00167 }
00168 fscanf(fin, "%s %f", var, &rules->regle[j].ponderation );
00169 tmp = 0;
00170 while(strcmp(var,fct->partition[fct->nb_entree-1].part[tmp].nom)!=0)
00171 tmp++;
00172 rules->regle[j].nom_out = tmp;
00173
00174 }
00175
00176 fclose(fin);
00177
00178
00179
00180 dpteur->nb_descripteur = fct->nb_entree;
00181 if( (dpteur->descript = (ss_ens_flou_symb *)malloc(dpteur->nb_descripteur*sizeof(ss_ens_flou_symb))) == NULL) {
00182 printf("problème d'allocation mémoire.\n");
00183 exit(1);
00184 }
00185 for(i=0; i<fct->nb_entree; i++)
00186 if( (dpteur->descript[i] = (degre_app *)malloc(fct->partition[i].nb_fct*sizeof(degre_app))) == NULL) {
00187 printf("problème d'allocation mémoire.\n");
00188 exit(1);
00189 }
00190
00191
00192 }
00193
00194 int
00195 ff_symb_init_set_pfi(
00196 fusion_floue_t* ff
00197 ){
00198 switch(ff->Tnorme){
00199 case 0:
00200 ff->tn = tn_zadeh;
00201 break;
00202 case 1:
00203 ff->tn = tn_proba;
00204 break;
00205 case 2:
00206 ff->tn = tn_luk;
00207 break;
00208 case 3:
00209 ff->tn = tn_weber;
00210 break;
00211 default:
00212 printf("erreur sur le choix du type de T-norme\n");
00213 exit(1);
00214 break;
00215 }
00216 switch(ff->Tconorme){
00217 case 0:
00218 ff->tcn = tc_zadeh;
00219 break;
00220 case 1:
00221 ff->tcn = tc_proba;
00222 break;
00223 case 2:
00224 ff->tcn = tc_luk;
00225 break;
00226 case 3:
00227 ff->tcn = tc_weber;
00228 break;
00229 default:
00230 printf("erreur sur le choix du type de T-norme\n");
00231 exit(1);
00232 break;
00233 }
00234 return 0;
00235 }
00236
00237
00238
00239 float
00240 calcul_premisse(
00241 Fct_appartenance* fct,
00242 Descripteur* desc,
00243 unsigned char* liste,
00244 int (*tnorme)()
00245 ){
00246 int l;
00247 float premisse=1.0;
00248
00249
00250 for(l=0; l<fct->nb_entree-1; l++)
00251
00252 (*tnorme)(&premisse, &desc->descript[l][liste[l]], &premisse);
00253
00254 return(premisse);
00255 }
00256
00257
00258 degre_app appartenance (float x, Symbol s)
00259 {
00260 if (x <= s.gauche)
00261 if(s.gauche==s.mode)
00262 return(1.0);
00263 else
00264 return (0.0);
00265
00266 if (x <= s.mode)
00267 return ( ( x - s.gauche ) / ( s.mode - s.gauche ) );
00268
00269 if (x <= s.droite)
00270 if ( s.droite != s.mode )
00271 return ( ( s.droite - x ) / ( s.droite - s.mode ) );
00272 else
00273 return (1.0);
00274
00275 if ( x > s.droite)
00276 if(s.droite==s.mode)
00277 return (1.0);
00278 else
00279 return (0.0);
00280
00281 printf("Erreur dans la fonction appartenance");
00282 return(0.0);
00283 }
00284
00285
00286
00287 fuzzification(float *val, Fct_appartenance *fct, Descripteur *desc)
00288 {
00289 int i, j;
00290
00291
00292 for(i=0; i<fct->nb_entree-1; i++)
00293
00294 for(j=0; j<fct->partition[i].nb_fct; j++)
00295
00296 desc->descript[i][j] = appartenance(val[i],fct->partition[i].part[j]);
00297 }
00298
00299
00300
00301
00302
00303 int defuzzification(float *result, Fct_appartenance *fct, Descripteur * desc, int t)
00304 {
00305 int i;
00306 float max=0.0, num=0.0, denum=0.0;
00307 int mot=0;
00308
00309 switch(t){
00310 case 0:
00311
00312 for(i=0; i<fct->partition[fct->nb_entree-1].nb_fct; i++) {
00313 result[i]=desc->descript[fct->nb_entree-1][i];
00314 if( desc->descript[fct->nb_entree-1][i] > max ){
00315 max = desc->descript[fct->nb_entree-1][i];
00316 mot = i;
00317 }
00318 }
00319 return(mot);
00320 break;
00321 case 1:
00322
00323 for(i=0; i<fct->partition[fct->nb_entree-1].nb_fct; i++){
00324 num = num + desc->descript[fct->nb_entree-1][i] * fct->partition[fct->nb_entree-1].part[i].mode;
00325 denum = denum + desc->descript[fct->nb_entree-1][i];
00326 }
00327 result[0] = (float)(num/denum);
00328 break;
00329 default:
00330 printf("type defuzzification incorrect\n");
00331 exit(1);
00332 }
00333 }
00334
00335
00336
00337
00338 int
00339 inference(
00340 Fct_appartenance* fct,
00341 Les_regles* rules,
00342 Descripteur* desc,
00343 int (*tnorme) (),
00344 int (*tconorme) ()
00345 ){
00346 int s, r;
00347 float premisse, combinaison, projection;
00348
00349
00350 for (s=0; s<fct->partition[fct->nb_entree-1].nb_fct; s++)
00351 {
00352 projection = 0.0;
00353
00354 for(r=0; r<rules->nb_regle; r++)
00355 {
00356 if( rules->regle[r].nom_out == s)
00357 {
00358
00359 premisse = calcul_premisse(fct, desc, rules->regle[r].liste_in, (*tnorme));
00360
00361 (*tnorme)( &premisse, &rules->regle[r].ponderation, &combinaison);
00362
00363 (*tconorme)( &projection, &combinaison, &projection );
00364 }
00365 }
00366 desc->descript[desc->nb_descripteur-1][s] = projection;
00367
00368 }
00369 }
00370
00463 param *ff_symb_lect( fusion_floue_t *d, param *ptp, char *debq)
00464 {
00465 char question[500];
00466
00467 sprintf(question, "%s fichier d'initialisation", debq);
00468 lec_param(question, ptp);
00469 d->nom = ptp->rep;
00470 ptp = ptp->next;
00471
00472 sprintf(question, "%s type de Tnorme (0-3)", debq);
00473 lec_param(question, ptp);
00474 d->Tnorme = atoi(ptp->rep);
00475 ptp = ptp->next;
00476
00477 sprintf(question, "%s type de Tconorme (0-3)", debq);
00478 lec_param(question, ptp);
00479 d->Tconorme = atoi(ptp->rep);
00480 ptp = ptp->next;
00481
00482 sprintf(question, "%s type de défuzzification (0-1)", debq);
00483 lec_param(question, ptp);
00484 d->defuzz = atoi(ptp->rep);
00485 ptp = ptp->next;
00486
00487 return(ptp);
00488 }
00489
00490
00491
00499 int ff_symb_init(fusion_floue_t *d){
00500 init(d->nom, &d->fonction, &d->rgl, &d->des);
00501 ff_symb_init_set_pfi( d);
00502 }
00503
00504
00505
00514 int
00515 ff_symb_calc(
00516 fusion_floue_t* d,
00517 degre_app* data,
00518 degre_app* result
00519 ){
00520 fuzzification(data, &d->fonction, &d->des);
00521 inference( &d->fonction,
00522 &d->rgl,
00523 &d->des,
00524 d->tn,
00525 d->tcn
00526 );
00527 return( defuzzification(result, &d->fonction, &d->des, d->defuzz) );
00528 }
00529
00530
00537 int
00538 ff_symb_ferm(
00539 fusion_floue_t *d
00540 ){
00541 int i;
00542
00543 free( d->fonction.partition);
00544 for ( i = 0; i < d->fonction.nb_entree; i++) {
00545 free( d->fonction.partition[i].part );
00546 }
00547 free( d->rgl.regle );
00548 free( d->des.descript );
00549 for ( i = 0; i < d->fonction.nb_entree; i++) {
00550 free(d->des.descript[i]);
00551 }
00552 return 0;
00553 }