Now we're going to look at fuzzy sets. The key characteristic of this is that every item of interest contains two values: the quantity of interest, and the probability that it is in the set. We can represent that probability using an Fbool. It has some nice properties that relate to the new functionality of the Fset. The real question is: how do we connect it with the quantity of interest?
The “obvious” choice is to use a set<T>. The problem is a set doesn't really deal with pairs of values. We could use a struct to define that quantity/probability pairing, but since a set<T> doesn't really provide any additional functionality that we explicitly care about. We don't want to use a vector<T> either, since we need to be able to access the probability directly through the quantity of interest. The container we really need is the map<T,X>. Since we might be interested in a variety of different quantities, our final Fset will actually be a template. Fset<T> will use map<T,Fbool> to contain its data. However, to get everything working we'll use Fset with map<string,Fbool>.
We'll want to be aware of the following features of a map as we move forward:
maps have the following methods/operations: size(), empty(), max_size(), ==, !=, <, >, <=, >=, find(key), lower_bound(key), upper_bound(key), equal_range(key), =, swap(), begin(), end(), rbegin(), rend(), insert(), erase(), clear(), and [].
We're going to define an insert, size, empty, erase, clear, &&, ||, !, and [] based on the definition of a Fuzzy Set presented in the first tutorial. With all this in mind, let's look at fset.h:
#ifndef FSET_DEFINED
#define FSET_DEFINED
#include "fbool.h"
#include <map>
#include <string>
class Fset
{
std::map<std::string,Fbool> setdata;
public:
void insert(const std::string,double);
void insert(const std::string,bool);
int size();
bool empty();
void erase(std::string);
void clear();
Fset operator&&(Fset);
Fset operator||(Fset);
Fset operator!();
Fbool& operator[](std::string);
};
#endif
The actual definitions of the functions are located in fset.cpp:
fset.cpp
#include "fbool.h"
#include "fset.h"
#include <string>
void Fset::insert(const std::string key, double prob)
{
Fset::setdata.insert(std::pair<std::string,Fbool>(key,prob));
}
void Fset::insert(const std::string key, bool prob)
{
Fset::setdata.insert(std::pair<std::string,Fbool>(key,prob));
}
int Fset::size()
{
return Fset::setdata.size();
}
bool Fset::empty()
{
return Fset::setdata.empty();
}
void Fset::erase(std::string key)
{
Fset::setdata.erase(key);
}
void Fset::clear()
{
Fset::setdata.clear();
}
Fset Fset::operator&&(Fset operand)
{
Fset temp;
Fbool temp2;
std::map<std::string,Fbool>::iterator pos1;
std::map<std::string,Fbool>::iterator pos2;
for (pos1 = this->setdata.begin(), pos2 = operand.setdata.begin(); pos1 != this->setdata.end() && pos2 != operand.setdata.end();)
{
if (pos1->first < pos2->first)
{
temp2.setval(false);
temp.insert(pos1->first,temp2.getval());
++pos1;
}
else if (pos1->first > pos2->first)
{
temp2.setval(false);
temp.insert(pos2->first,temp2.getval());
++pos2;
}
else
{
temp.insert(pos2->first,((pos1->second)&&(pos2->second)).getval());
++pos1;
++pos2;
}
}
return temp;
}
Fset Fset::operator||(Fset operand)
{
Fset temp;
std::map<std::string,Fbool>::iterator pos1;
std::map<std::string,Fbool>::iterator pos2;
for (pos1 = this->setdata.begin(), pos2 = operand.setdata.begin(); pos1 != this->setdata.end() && pos2 != operand.setdata.end();)
{
if (pos1->first < pos2->first)
{
temp.insert(pos1->first,(pos1->second).getval());
++pos1;
}
else if (pos1->first > pos2->first)
{
temp.insert(pos2->first,(pos2->second).getval());
++pos2;
}
else
{
temp.insert(pos2->first,((pos1->second)||(pos2->second)).getval());
++pos1;
++pos2;
}
}
return temp;
}
Fset Fset::operator!()
{
Fset temp;
std::map<std::string,Fbool>::iterator pos1;
for (pos1 = this->setdata.begin(); pos1 != this->setdata.end();++pos1)
{
temp.insert(pos1->first,(!(pos1->second)).getval());
}
return temp;
}
Fbool& Fset::operator[](std::string key)
{
return Fset::setdata[key];
}
The operators && and || deserve some comment. In order to make sure we cover all the elements, we'll move through both fuzzy sets element by element, adding the appropriate pair. We are taking advantage of the fact that maps store the keys in order by <, so we can meaningfully compare the keys as we step through them with the iterators.
A simple test program is listed below:
testfset.cpp
#include "fset.h"
#include <iostream>
#include <string>
using std::string;
using std::cout;
int main(int argc,char* argv[])
{
Fset mytestset;
cout<<"mytestset.empty = "<<mytestset.empty()<<"\n";
cout<<"mytestset.count = "<<mytestset.size()<<"\n";
mytestset.insert("false",false);
mytestset.insert("true",true);
mytestset.insert("third",0.33);
mytestset.insert("half",0.5);
cout<<"mytestset.empty = "<<mytestset.empty()<<"\n";
cout<<"mytestset.count = "<<mytestset.size()<<"\n";
Fset mytest2;
mytest2.insert("false",true);
mytest2.insert("true",false);
mytest2.insert("quarter",0.25);
mytest2.insert("half",0.5);
cout<<"mytest2.empty = "<<mytest2.empty()<<"\n";
cout<<"mytest2.count = "<<mytest2.size()<<"\n";
Fset andset = mytest2&&mytestset;
Fset orset = mytest2||mytestset;
Fset notset = !mytestset;
cout<<"andset[\"false\"] = "<<andset["false"].getval()<<"\n";
cout<<"orset[\"false\"] = "<<orset["false"].getval()<<"\n";
cout<<"notset[\"false\"] = "<<notset["false"].getval()<<"\n";
return 0;
}
This program will produce the following output:
mytestset.empty = 1 mytestset.count = 0 mytestset.empty = 0 mytestset.count = 4 mytest2.empty = 0 mytest2.count = 4 andset["false"] = 0 orset["false"] = 1 notset["false"] = 1
Edited by WingedPanther, 20 November 2008 - 02:11 AM.
correct includes based on file name changes between this post and my hard drive


Sign In
Create Account

Back to top










