home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 13
/
mediashare_13.zip
/
mediashare_13
/
ZIPPED
/
PROGRAM
/
APR94_1.ZIP
/
FUZZY.ASC
< prev
next >
Wrap
Text File
|
1994-02-27
|
17KB
|
473 lines
_FUZZY LOGIC IN C: AN UPDATE_
by John A.R. Tucker, Phillip E. Fraley, Lawrence Pl Swanson
Listing One
/* Update to Greg Viot's fuzzy system -- DDJ, February 1993, page 94 */
#include <stdio.h>
#include <string.h> /* NEW */
# define max(a,b) (a<b ? b : a) /* NEW */
# define min(a,b) (a>b ? b : a) /* NEW */
struct io_type *System_Inputs; /* anchor inputs NEW */
struct io_type *System_Output; /* anchor output NEW */
#define MAXNAME 10
#define UPPER_LIMIT 255
struct io_type{
char name[MAXNAME];
int value;
struct mf_type *membership_functions;
struct io_type *next;
};
struct mf_type{
char name[MAXNAME];
int value;
int point1;
int point2;
float slope1;
float slope2;
struct mf_type *next;
};
struct rule_type{
struct rule_element_type *if_side;
struct rule_element_type *then_side;
struct rule_type *next;
};
struct rule_element_type{
int *value;
struct rule_element_type *next;
};
struct rule_type *Rule_Base;
main(argc,argv) /* NEW */
int argc; /* NEW */
char *argv[]; /* NEW */
{ int input1, input2; /* NEW */
if(argc!=3) /* NEW */
{ printf("Error - Must supply 2 numeric inputs.\n"); /* NEW */
printf(" Inputs scaled to range 0-255.\n"); /* NEW */
printf("Usage: %s angle velocity\n",argv[0]); /* NEW */
exit(0); /* NEW */
} /* NEW */
input1=atoi(argv[1]); /* NEW */
input2=atoi(argv[2]); /* NEW */
initialize_system(); /* Read input files, NEW */
get_system_inputs(input1,input2); /* Get & put argv NEW */
fuzzification();
rule_evaluation();
defuzzification();
put_system_outputs(); /* print all data, NEW */
} /* END MAIN */
fuzzification()
{ struct io_type *si;
struct mf_type *mf;
for(si=System_Inputs;si!=NULL;si=si->next)
for(mf=si->membership_functions;mf!=NULL;mf=mf->next)
compute_degree_of_membership(mf,si->value);
} /* END FUZZIFICATION */
rule_evaluation()
{ struct rule_type *rule;
struct rule_element_type *ip; /* if ptr */
struct rule_element_type *tp; /* then ptr */
int strength;
int nomatch=0; /* NEW, test some rules */
for(rule=Rule_Base;rule!=NULL;rule=rule->next)
{ strength=UPPER_LIMIT;
for(ip=rule->if_side;ip!=NULL;ip=ip->next)
strength=min(strength,*(ip->value));
for(tp=rule->then_side;tp!=NULL;tp=tp->next)
{ *(tp->value)=max(strength,*(tp->value)); /* NEW */
if(strength>0)nomatch=1; /* NEW */
} /* NEW */
}
if(nomatch==0)printf("NO MATCHING RULES FOUND!\n"); /* NEW */
} /* END RULE EVALUATION */
defuzzification()
{ struct io_type *so;
struct mf_type *mf;
int sum_of_products;
int sum_of_areas;
int area, centroid;
for(so=System_Output;so!=NULL;so=so->next)
{ sum_of_products=0;
sum_of_areas=0;
for(mf=so->membership_functions;mf!=NULL;mf=mf->next)
{ area=compute_area_of_trapezoid(mf);
centroid=mf->point1+(mf->point2-mf->point1)/2;
sum_of_products+=area*centroid;
sum_of_areas+=area;
}
if(sum_of_areas==0) /* NEW */
{ printf("Sum of Areas = 0, will cause div error\n"); /* NEW */
printf("Sum of Products= %d\n",sum_of_products); /* NEW */
so->value=0; /* NEW */
return; /* NEW */
} /* NEW */
so->value=sum_of_products/sum_of_areas;
}
} /* END DEFUZZIFICATION */
compute_degree_of_membership(mf,input)
struct mf_type *mf;
int input;
{ int delta_1, delta_2;
delta_1=input - mf->point1;
delta_2=mf->point2 - input;
if((delta_1<=0)||(delta_2<=0))mf->value=0;
else
{ mf->value=min((mf->slope1*delta_1),(mf->slope2*delta_2));
mf->value=min(mf->value,UPPER_LIMIT);
}
} /* END DEGREE OF MEMBERSHIP */
compute_area_of_trapezoid(mf)
struct mf_type *mf;
{ float run_1,run_2,area,top;
float base;
base=mf->point2 - mf->point1;
run_1=mf->value / mf->slope1;
run_2=mf->value / mf->slope2;
top=base - run_1 - run_2;
area=mf->value*(base+top)/2;
return(area);
} /* END AREA OF TRAPEZOID */
initialize_system() /* NEW FUNCTION INITIALIZE */
{ int a, b, c, d, x;
char buff[10],buff1[4],buff2[4];
static char filename1[]="in1"; /* "angles" filename */
static char filename2[]="in2"; /* "velocities" filename */
static char filename3[]="out1"; /* "forces" filename */
FILE *fp;
struct io_type *outptr;
struct mf_type *top_mf;
struct mf_type *mfptr;
struct io_type *ioptr;
struct rule_type *ruleptr;
struct rule_element_type *ifptr;
struct rule_element_type *thenptr;
ioptr=NULL;
ruleptr=NULL;
ifptr=NULL;
thenptr=NULL;
/* READ THE FIRST FUZZY SET (ANTECEDENT); INITIALIZE STRUCTURES */
if((fp=fopen(filename1,"r"))==NULL) /* open "angles" file */
{ printf("ERROR- Unable to open data file named %s.\n",filename1);
exit(0);
}
ioptr=(struct io_type *)calloc(1,sizeof(struct io_type));
System_Inputs=ioptr; /* Anchor to top of inputs */
x=fscanf(fp,"%s",buff); /* from 1st line, get set's name */
sprintf(ioptr->name,"%s",buff); /* into struct io_type.name */
mfptr=NULL;
while((x=fscanf(fp,"%s %d %d %d %d",buff,&a,&b,&c,&d))!=EOF)/* get line */
{ if(mfptr==NULL) /* first time thru only */
{ mfptr=(struct mf_type *)calloc(1,sizeof(struct mf_type));
top_mf=mfptr;
ioptr->membership_functions=mfptr;
}
else
{ for(mfptr=top_mf;mfptr->next;mfptr=mfptr->next); /* spin to last */
mfptr->next=(struct mf_type *)calloc(1,sizeof(struct mf_type));
mfptr=mfptr->next;
}
sprintf(mfptr->name,"%s",buff); /* membership name, NL, ZE, etc */
mfptr->point1=a; /* left x axis value */
mfptr->point2=d; /* right x axis value */
if(b-a>0) mfptr->slope1=UPPER_LIMIT/(b-a); /* left slope */
else
{ printf("Error in input file %s, membership element %s.\n",
filename1,buff);
exit(1);
}
if(d-c>0) mfptr->slope2=UPPER_LIMIT/(d-c); /* right slope */
else
{ printf("Error in input file %s, membership element %s.\n",
filename1,buff);
exit(1);
}
}
close(fp); /* close "angles" file */
/* READ THE SECOND FUZZY SET (ANTECEDENT); INITIALIZE STRUCTURES */
if((fp=fopen(filename2,"r"))==NULL) /* open "velocity" file */
{ printf("ERROR- Unable to open data file named %s.\n",filename2);
exit(0);
}
ioptr->next=(struct io_type *)calloc(1,sizeof(struct io_type));
ioptr=ioptr->next;
x=fscanf(fp,"%s",buff); /* from 1st line, get set's name */
sprintf(ioptr->name,"%s",buff); /* into struct io_type.name */
mfptr=NULL;
while((x=fscanf(fp,"%s %d %d %d %d",buff,&a,&b,&c,&d))!=EOF)/* get line */
{ if(mfptr==NULL) /* first time thru only */
{ mfptr=(struct mf_type *)calloc(1,sizeof(struct mf_type));
top_mf=mfptr;
ioptr->membership_functions=mfptr;
}
else
{ for(mfptr=top_mf;mfptr->next;mfptr=mfptr->next); /* spin to last */
mfptr->next=(struct mf_type *)calloc(1,sizeof(struct mf_type));
mfptr=mfptr->next;
}
sprintf(mfptr->name,"%s",buff); /* membership name, NL, ZE, etc */
mfptr->point1=a; /* left x axis value */
mfptr->point2=d; /* right x axis value */
if(b-a>0) mfptr->slope1=UPPER_LIMIT/(b-a); /* left slope */
else
{ printf("Error in input file %s, membership element %s.\n",
filename2,buff);
exit(1);
}
if(d-c>0) mfptr->slope2=UPPER_LIMIT/(d-c); /* right slope */
else
{ printf("Error in input file %s, membership element %s.\n",
filename2,buff);
exit(1);
}
}
close(fp); /* close "velocity" file */
/* READ THE THIRD FUZZY SET (CONSEQUENCE); INITIALIZE STRUCTURES */
if((fp=fopen(filename3,"r"))==NULL) /* open "force" file */
{ printf("ERROR- Unable to open data file named %s.\n",filename3);
exit(0);
}
ioptr=(struct io_type *)calloc(1,sizeof(struct io_type));
System_Output=ioptr; /* Anchor output structure */
x=fscanf(fp,"%s",buff); /* from 1st line, get set's name */
sprintf(ioptr->name,"%s",buff); /* into struct io_type.name */
mfptr=NULL;
while((x=fscanf(fp,"%s %d %d %d %d",buff,&a,&b,&c,&d))!=EOF)/* get line */
{ if(mfptr==NULL) /* first time thru */
{ mfptr=(struct mf_type *)calloc(1,sizeof(struct mf_type));
top_mf=mfptr;
ioptr->membership_functions=mfptr;
}
else
{ for(mfptr=top_mf;mfptr->next;mfptr=mfptr->next);
mfptr->next=(struct mf_type *)calloc(1,sizeof(struct mf_type));
mfptr=mfptr->next;
}
sprintf(mfptr->name,"%s",buff); /* membership name, NL, ZE, etc */
mfptr->point1=a; /* left x axis value */
mfptr->point2=d; /* right x axis value */
if(b-a>0) mfptr->slope1=UPPER_LIMIT/(b-a); /* left slope */
else
{ printf("Error in input file %s, membership element %s.\n",
filename3,buff);
exit(1);
}
if(d-c>0) mfptr->slope2=UPPER_LIMIT/(d-c); /* right slope */
else
{ printf("Error in input file %s, membership element %s.\n",
filename3,buff);
exit(1);
}
}
close(fp); /* close "force" file */
/* READ RULES FILE; INITIALIZE STRUCTURES */
ioptr=NULL;
outptr=NULL;
if((fp=fopen("rules","r"))==NULL) /* open rules file */
{ printf("ERROR- Unable to open data file named %s.\n","rules");
exit(0);
}
ruleptr=(struct rule_type *)calloc(1,sizeof(struct rule_type));
if(ioptr==NULL)Rule_Base=ruleptr; /* first time thru, anchor */
while((x=fscanf(fp,"%s %s %s",buff,buff1,buff2))!=EOF) /* get a line */
{ ioptr=System_Inputs; /* points to angle */
for(mfptr=ioptr->membership_functions;mfptr!=NULL;mfptr=mfptr->next)
{ if((strcmp(mfptr->name,buff))==0)
{ ifptr=(struct rule_element_type *)
calloc(1,sizeof(struct rule_element_type));
ruleptr->if_side=ifptr; /* points to angle */
ifptr->value=&mfptr->value; /* needs address here */
ifptr->next=(struct rule_element_type *)
calloc(1,sizeof(struct rule_element_type));
ifptr=ifptr->next;
break; /* match found */
}
}
ioptr=ioptr->next; /* points to velocity */
for(mfptr=ioptr->membership_functions;mfptr!=NULL;mfptr=mfptr->next)
{ if((strcmp(mfptr->name,buff1))==0)
{ ifptr->value=&mfptr->value; /* needs address here */
break; /* match found */
}
}
if(outptr==NULL)outptr=System_Output;/* point then stuff to output */
for(mfptr=outptr->membership_functions;mfptr!=NULL;mfptr=mfptr->next)
{ if((strcmp(mfptr->name,buff2))==0)
{ thenptr=(struct rule_element_type *)
calloc(1,sizeof(struct rule_element_type));
ruleptr->then_side=thenptr;
thenptr->value=&mfptr->value; /* needs address here */
break; /* match found */
}
}
ruleptr->next=(struct rule_type *)calloc(1,sizeof(struct rule_type));
ruleptr=ruleptr->next;
} /* END WHILE READING RULES FILE */
close(fp); /* close "rules" file */
} /* END INITIALIZE */
put_system_outputs() /* NEW */
{ struct io_type *ioptr;
struct mf_type *mfptr;
struct rule_type *ruleptr;
struct rule_element_type *ifptr;
struct rule_element_type *thenptr;
int cnt=1;
for(ioptr=System_Inputs;ioptr!=NULL;ioptr=ioptr->next)
{ printf("%s: Value= %d\n",ioptr->name,ioptr->value);
for(mfptr=ioptr->membership_functions;mfptr!=NULL;mfptr=mfptr->next)
{ printf(" %s: Value %d Left %d Right %d\n",
mfptr->name,mfptr->value,mfptr->point1,mfptr->point2);
}
printf("\n");
}
for(ioptr=System_Output;ioptr!=NULL;ioptr=ioptr->next)
{ printf("%s: Value= %d\n",ioptr->name,ioptr->value);
for(mfptr=ioptr->membership_functions;mfptr!=NULL;mfptr=mfptr->next)
{ printf(" %s: Value %d Left %d Right %d\n",
mfptr->name,mfptr->value,mfptr->point1,mfptr->point2);
}
}
/* print values pointed to by rule_type (if & then) */
printf("\n");
for(ruleptr=Rule_Base;ruleptr->next!=NULL;ruleptr=ruleptr->next)
{ printf("Rule #%d:",cnt++);
for(ifptr=ruleptr->if_side;ifptr!=NULL;ifptr=ifptr->next)
printf(" %d",*(ifptr->value));
for(thenptr=ruleptr->then_side;thenptr!=NULL;thenptr=thenptr->next)
printf(" %d\n",*(thenptr->value));
}
printf("\n");
} /* END PUT SYSTEM OUTPUTS */
get_system_inputs(input1,input2) /* NEW */
int input1, input2;
{ struct io_type *ioptr;
ioptr=System_Inputs;
ioptr->value=input1;
ioptr=ioptr->next;
ioptr->value=input2;
} /* END GET SYSTEM INPUTS */
Example 1:
#include <string.h>
#define max(a,b) (a<b ? b : a)
#define min(a,b) (a>b ? b : a)
struct io_type *System_Inputs;
struct io_type *System_Output;
Example 2:
(a)
if(sum_of_areas==0)
{ printf("Sum of Areas = 0, will cause div error\n");
printf("Sum of Products= %d\n",sum_of_products);
so->value=0;
return;
}
(b)
so->value=sum_of_products/sum_of_areas;
(c)
int nomatch=0;
....
for(tp=rule->then_side;tp!=NULL;tp=tp->next)
{ *(tp->value)=max(strength,*(tp->value));
if(strength>0)nomatch=1;
}
}
if(nomatch==0)printf("NO MATCHING RULES FOUND!\n");
Figure 1:
angle
NL 0 31 31 63
NM 31 63 63 95
NS 63 95 95 127
ZE 95 127 127 159
PS 127 159 159 191
PM 159 191 191 223
PL 191 223 223 255
Figure 2:
(a)
rule 1: IF (angle is NL) AND (velocity is ZE) THEN (force is PL)
rule 2: IF (angle is ZE) AND (velocity is NL) THEN (force is PL)
rule 3: IF (angle is NM) AND (velocity is ZE) THEN (force is PM) ....
rule 15: IF (angle is PL) AND (velocity is ZE) THEN (force is NL)
(b)
NL ZE PL
ZE NL PL
NM ZE PM
....
PL ZE NL
Figure 4:
rule 1: IF (angle is NL) AND (velocity is ZE) THEN (force is PL)
Figure 5:
fuzz 60 125
angle: Value= 60
NL: Value 21 Left 0 Right 63
NM: Value 203 Left 31 Right 95
NS: Value 0 Left 63 Right 127
ZE: Value 0 Left 95 Right 159
PS: Value 0 Left 127 Right 191
PM: Value 0 Left 159 Right 223
PL: Value 0 Left 191 Right 255
velocity: Value= 125
NL: Value 0 Left 0 Right 64
NM: Value 0 Left 31 Right 95
NS: Value 14 Left 63 Right 127
ZE: Value 210 Left 95 Right 159
PS: Value 0 Left 127 Right 191
PM: Value 0 Left 159 Right 223
PL: Value 0 Left 191 Right 255
force: Value= 134
NL: Value 0 Left 0 Right 63
NM: Value 203 Left 31 Right 95
NS: Value 0 Left 63 Right 127
ZE: Value 0 Left 95 Right 159
PS: Value 0 Left 127 Right 191
PM: Value 203 Left 159 Right 223
PL: Value 21 Left 191 Right 255
Rule #1: 21 210 21
Rule #2: 0 0 21
Rule #3: 203 210 203
Rule #4: 0 0 203
Rule #5: 0 210 0
Rule #6: 0 14 0
Rule #7: 0 0 0
Rule #8: 0 210 0
Rule #9: 0 0 0
Rule #10: 0 210 0
Rule #11: 0 14 0
Rule #12: 0 0 203
Rule #13: 203 210 203
Rule #14: 0 0 0
Rule #15: 0 210 0