Again, it’s all very straightforward. I don’t want to waste paper listing the
code for the other fuzzy sets; they’re just as clear-cut and easy to under
stand. Let’s move on to the fuzzy linguistic variable class.
Creating a Fuzzy Linguistic Variable Class
The fuzzy linguistic variable class FuzzyVariable contains a std::map of
pointers to instances of
FuzzySets — the sets that make up its manifold. In
addition, it has methods for adding fuzzy sets and for fuzzifying and
defuzzifying values.
Whenever a member set is created and added to an FLV, the min/max
ranges of the FLV are recalculated and assigned to the values
and m_dMaxRange. Keeping a record of the range of the domain of the FLV
in this way allows the logic to determine if a value presented for
fuzzification is out of bounds and to exit with an assertion if necessary.
Here’s the class declaration:
class FuzzyVariable
typedef std::map<std::string, FuzzySet*> MemberSets;
//disallow copies
FuzzyVariable(const FuzzyVariable&);
FuzzyVariable& operator=(const FuzzyVariable&);
//a map of the fuzzy sets that comprise this variable
MemberSets m_MemberSets;
//the minimum and maximum value of the range of this variable
double m_dMinRange;
double m_dMaxRange;
//this method is called with the upper and lower bound of a set each time a
//new set is added to adjust the upper and lower range values accordingly
void AdjustRangeToFit(double min, double max);
//a client retrieves a reference to a fuzzy variable when an instance is
//created via FuzzyModule::CreateFLV(). To prevent the client from deleting
//the instance the FuzzyVariable destructor is made private and the
//FuzzyModule class made a friend.
friend class FuzzyModule;
Fuzzy Logic | 443
From Theory to Application: Coding a Fuzzy Logic Module
//the following methods create instances of the sets named in the method
//name and adds them to the member set map. Each time a set of any type is
//added the m_dMinRange and m_dMaxRange are adjusted accordingly. All of the
//methods return a proxy class representing the newly created instance. This
//proxy set can be used as an operand when creating the rule base.
FzSet AddLeftShoulderSet(std::string name,
double minBound,
double peak,
double maxBound);
FzSet AddRightShoulderSet(std::string name,
double minBound,
double peak,
double maxBound);
FzSet AddTriangularSet(std::string name,
double minBound,
double peak,
double maxBound);
FzSet AddSingletonSet(std::string name,
double minBound,
double peak,
double maxBound);
//fuzzify a value by calculating its DOM in each of this variable's subsets
void Fuzzify(double val);
//defuzzify the variable using the MaxAv method
double DeFuzzifyMaxAv()const;
//defuzzify the variable using the centroid method
double DeFuzzifyCentroid(int NumSamples)const;
Notice how the methods for creating and adding sets do not use the same
parameters used by the fuzzy set classes themselves. For example, in addi
tion to a string representing the name, the
AddLeftShoulderSet method
takes as parameters the minimum bound, a peak point, and a maximum
bound, whereas the
FuzzySet_Triangle class uses values specifying a mid
point, a left offset, and a right offset. This is simply to make the methods
more instinctive for clients to use. Typically, when creating FLVs you will
sketch out their member sets on paper (or imagine them in your head),
making it a lot easier to read off the values left to right instead of calculat
ing all the offsets.
444 | Chapter 10
From Theory to Application: Coding a Fuzzy Logic Module

Get Programming Game AI by Example now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.