home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 215 / DDJ9302.ZIP / FUZZY.ASC < prev    next >
Text File  |  1993-01-11  |  7KB  |  177 lines

  1. _FUZZY LOGIC IN C_
  2. by Greg Viot
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7. /*  General-purpose fuzzy inference engine supporting any number of system 
  8. inputs and outputs, membership functions, and rules. Membership functions can 
  9. be any shape defineable by 2 points and 2 slopes--trapezoids, triangles, 
  10. rectanlges, etc. Rules can have any number of antecedents and outputs, and can
  11. vary from rule to rule. "Min" method is used to compute rule strength, "Max" 
  12. for applying rule strengths, "Center-of-Gravity" for defuzzification. This 
  13. implementation of Inverted Pendulum control problem has: System Inputs, 2 
  14. (pendulum angle and velocity); System Outputs, 1 (force supplied to base of 
  15. pendulum); Membership Functions, 7 per system input/output; Rules, 15 (each 
  16. with 2 antecedents & 1 output). If more precision is required, integers can 
  17. be changed to real numbers.*/
  18.  
  19. #include <stdio.h>
  20. #define MAXNAME 10          /* max number of characters in names   */
  21. #define UPPER_LIMIT  255    /* max number assigned as degree of membership */ 
  22.  
  23. /* io_type structure builds a list of system inputs and a list of system 
  24. outputs. After initialization, these lists are fixed, except for value field 
  25. which is updated on every inference pass. */
  26. struct io_type{
  27.   char name[MAXNAME];        /*  name of system input/output       */
  28.   int value;                 /*  value of system input/output      */
  29.   struct mf_type             /*  list of membership functions for  */
  30.     *membership_functions;   /*     this system input/output       */
  31.   struct io_type *next;      /*  pointer to next input/output      */
  32.   };
  33. /* Membership functions are associated with each system input and output. */
  34. struct mf_type{
  35.   char name[MAXNAME]; /* name of membership function (fuzzy set)    */
  36.   int value;          /* degree of membership or output strength    */
  37.   int point1;         /* leftmost x-axis point of mem. function */
  38.   int point2;         /* rightmost x-axis point of mem. function    */
  39.   int slope1;         /* slope of left side of membership function  */
  40.   int slope2;         /* slope of right side of membership function */
  41.   struct mf_type *next;   /* pointer to next membership function    */
  42.   };
  43. /*  Each rule has an if side and a then side. Elements making up if side are
  44. pointers to antecedent values inside mf_type structure. Elements making up then
  45. side of rule are pointers to output strength values, also inside mf_type
  46. structure. Each rule structure contains a pointer to next rule in rule base. */
  47. struct rule_element_type{
  48.   int *value;                /* pointer to antecedent/output strength value */
  49.   struct rule_element_type *next; /* next antecedent/output element in rule */ 
  50.   };
  51. struct rule_type{
  52.   struct rule_element_type *if_side;     /* list of antecedents in rule */
  53.   struct rule_element_type *then_side;   /* list of outputs in rule     */
  54.   struct rule_type *next;                /* next rule in rule base  */
  55.   };
  56. struct rule_type *Rule_Base;             /* list of all rules in rule base */
  57.  
  58.  
  59.  
  60. [LISTING TWO]
  61.  
  62. main()
  63. {
  64.  initialize_system();
  65.  while(1){
  66.   get_system_inputs();
  67.   fuzzification();
  68.   rule_evaluation();
  69.   defuzzification();
  70.   put_system_outputs();
  71.   }
  72. }
  73.  
  74.  
  75. [LISTING THREE]
  76.  
  77. /* Fuzzification--Degree of membership value is calculated for each membership
  78. function of each system input. Values correspond to antecedents in rules. */
  79. fuzzification()
  80. {
  81.  struct io_type *si;    /* system input pointer        */
  82.  struct mf_type *mf;    /* membership function pointer */
  83. for(si=System_Inputs; si != NULL; si=si->next)
  84.   for(mf=si->membership_functions; mf != NULL; mf=mf->next)
  85.     compute_degree_of_membership(mf,si->value);
  86. }
  87. /* Rule Evaluation--Each rule consists of a list of pointers to antecedents
  88. (if side), list of pointers to outputs (then side), and pointer to next rule
  89. in rule base. When a rule is evaluated, its antecedents are ANDed together, 
  90. using a minimum function, to form strength of rule. Then strength is applied 
  91. to each of listed rule outputs. If an output has already been assigned a rule 
  92. strength, during current inference pass, a maximum function is used to 
  93. determine which strength should apply. */
  94. rule_evaluation()
  95. {
  96.  struct rule_type *rule;
  97.  struct rule_element_type *ip;       /* pointer of antecedents  (if-parts)   */
  98.  struct rule_element_type *tp;       /* pointer to consequences (then-parts) */
  99.  int strength;                /* strength of  rule currently being evaluated */
  100.  for(rule=Rule_Base; rule != NULL; rule=rule->next){
  101.   strength = UPPER_LIMIT;                       /* max rule strength allowed */
  102.         /* process if-side of rule to determine strength */
  103.   for(ip=rule->if_side; ip != NULL; ip=ip->next)
  104.       strength = min(strength,*(ip->value));
  105.        /* process then-side of rule to apply strength */
  106.   for(tp=rule->then_side; tp != NULL; tp=tp->next)
  107.       *(tp->value) = max(strength,*(tp->value));
  108.   }
  109. }
  110. /* Defuzzification */
  111. defuzzification()
  112. {
  113.  struct io_type *so;    /* system output pointer */
  114.  struct mf_type *mf;    /* output membership function pointer */
  115.  int sum_of_products;   /* sum of products of area & centroid */
  116.  int sum_of_areas;  /* sum of shortend trapezoid area */       
  117.  int area;
  118.  int centroid;
  119.  /* compute a defuzzified value for each system output */
  120. for(so=System_Outputs; so != NULL; so=so->next){
  121.   sum_of_products = 0;
  122.   sum_of_areas = 0;
  123.   for(mf=so->membership_functions; mf != NULL; mf=mf->next){ 
  124.      area = compute_area_of_trapezoid(mf);
  125.      centroid = mf->point1 + (mf->point2 - mf->point1)/2;
  126.      sum_of_products += area * centroid;
  127.      sum_of_areas += area;
  128.      }
  129.   so->value = sum_of_products/sum_of_areas;   /* weighted average */
  130.   }
  131. }
  132.  
  133.  
  134. [LISTING FOUR]
  135.  
  136. /* Compute Degree of Membership--Degree to which input is a member of mf is
  137. calculated as follows: 1. Compute delta terms to determine if input is inside 
  138. or outside membership function. 2. If outside, then degree of membership is 0.
  139. Otherwise, smaller of delta_1 * slope1 and delta_2 * slope2 applies. 
  140. 3. Enforce upper limit. */
  141. compute_degree_of_membership(mf,input)
  142. struct mf_type *mf;
  143. int input;
  144. {
  145.  int delta_1;
  146.  int delta_2;
  147.  delta_1 = input - mf->point1;
  148.  delta_2 = mf->point2 - input;
  149.  if ((delta_1 <= 0) || (delta_2 <= 0))   /* input outside mem. function ? */
  150.    mf->value = 0;                        /* then degree of membership is 0 */
  151.  else
  152.    mf->value = min( (mf->slope1*delta_1),(mf->slope2*delta_2) );
  153.    mf->value = min(mf->value,UPPER_LIMIT);  /* enforce upper limit */
  154. }
  155. /* Compute Area of Trapezoid--Each inference pass produces a new set of output
  156. strengths which affect the areas of trapezoidal membership functions used in 
  157. center-of-gravity defuzzification. Area values must be recalculated with each
  158. pass. Area of trapezoid is h*(a+b)/2 where h=height=output_strength=mf->value 
  159. b=base=mf->point2-mf->point1 a=top= must be derived from h,b, and slopes1&2 */
  160. compute_area_of_trapezoid(mf)
  161. struct mf_type *mf;
  162. {
  163.  int run_1;
  164.  int run_2;
  165.  int base;
  166.  int top;
  167.  int area;
  168.  base = mf->point2 - mf->point1;
  169.  run_1 = mf->value/mf->slope1;
  170.  run_2 = mf->value/mf->slope2;
  171.  top = base - run_1 - run_2;
  172.  area = mf->value * ( base + top)/2;
  173.  return(area);
  174. }
  175.  
  176.  
  177.