⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfuzzyset.cpp

📁 人工智能中模糊逻辑算法 FuzzyLib 2.0 is a comprehensive C++ Fuzzy Logic library for constructing fuzzy logic sy
💻 CPP
📖 第 1 页 / 共 4 页
字号:
////////////////////////////////////////////////////////////////////////////////
#include "TFuzzySet.h"
////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
//TVariable class implementation
///////////////////////////////////////////////////////////////////////////////
TVariable::TVariable(char* _name, char* _unit, double _begin, double _end)
{
	if (_name != NULL)
	{
    	name	= new char[strlen(_name)+1];
		strcpy(name, _name);
    }
    if (_unit != NULL)
    {
       	unit	= new char[strlen(_unit)+1];
        strcpy(unit, _unit);
    }
	begin	= _begin;
	end		= _end;

    for (int i=0; i<MAX_FUZZYSETS_PER_VARIABLE; i++)
    {
		fuzzysets[i] = NULL;
    }
}


TVariable::~TVariable()
{
   	if (name != NULL) delete[] name;
    name = NULL;
   	if (unit != NULL) delete[] unit;
    unit = NULL;
	clear_fuzzysets();
}


void TVariable::clear_fuzzysets()
{
  for (int i=0; i<MAX_FUZZYSETS_PER_VARIABLE; i++)
  {
		if (fuzzysets[i] != NULL) delete fuzzysets[i];
		fuzzysets[i] = NULL;
  }
}

void TVariable::add_fuzzyset(TFuzzySet* fuzzyset)
{
  for (int i=0; i<MAX_FUZZYSETS_PER_VARIABLE; i++)
  {
  	if (fuzzysets[i] == NULL)
    {
		fuzzyset->set_variable(this);
		fuzzysets[i] = fuzzyset;
  	    break;
    }
  }
}

void TVariable::remove_fuzzyset(TFuzzySet* fuzzyset)
{
  for (int i=0; i<MAX_FUZZYSETS_PER_VARIABLE; i++)
  {
  	if (*(fuzzysets[i]) == *fuzzyset)
    {
		delete fuzzysets[i];
		// shift up
		for (int j=i; j<MAX_FUZZYSETS_PER_VARIABLE-1; j++)
    	{
			fuzzysets[j] = fuzzysets[j+1];
	    }
		// invalidate last
        fuzzysets[MAX_FUZZYSETS_PER_VARIABLE-1] = NULL;
        break;
    }
  }
}


bool TVariable::operator == (TVariable& variable2)
{
	if (*name  != *(variable2.name)) return false;
	if (*unit  != *(variable2.unit)) return false;
	if (begin  != variable2.begin) 	 return false;
	if (end    != variable2.end)     return false;
	for (int i=0; i<MAX_FUZZYSETS_PER_VARIABLE; i++)
   	{
    	if (!(fuzzysets[i] == variable2.fuzzysets[i])) return false;
    }
    return true;
}
///////////////////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////
//TFuzzySet class implementation
///////////////////////////////////////////////////////////////////////////////
TFuzzySet::TFuzzySet(	TVariable*	_variable,
						char* 		_name,
                        int 		_shape,
                        int 		_direction,
						double 		_min,
                        double 		_mid1,
                        double 		_mid,
                        double 		_mid2,
                        double 		_max,
                        double 		_minTruth,
                        double 		_maxTruth
					)
{
	variable	= _variable;
    if (_name != NULL)
   	{
   		name	= new char[strlen(_name)+1];
        strcpy(name, _name);
   	}
	shape		= _shape;
	direction	= _direction;
    if (variable != NULL)
    {
		if (_min  < variable->begin) _min = variable->begin;
		if (_min  > variable->end)   _min = variable->end;
		if (_mid1 < variable->begin) _mid1= variable->begin;
		if (_mid1 > variable->end)   _mid1= variable->end;
		if (_mid  < variable->begin) _mid = variable->begin;
		if (_mid  > variable->end)   _mid = variable->end;
		if (_mid2 < variable->begin) _mid2= variable->begin;
		if (_mid2 > variable->end)   _mid2= variable->end;
		if (_max  < variable->begin) _max = variable->begin;
		if (_max  > variable->end)   _max = variable->end;
		min		= ((_min  - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
		mid1	= ((_mid1 - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
		mid		= ((_mid  - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
		mid2	= ((_mid2 - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
		max		= ((_max  - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
	}
	minTruth	= _minTruth;
	maxTruth	= _maxTruth;
	for(int i=0; i<DOMAIN_POINTS; i++) 	truths[i] = ZERO_TRUTH;
	for(int i=0; i<MAX_HEDGES; i++)    	hedges[i] = INVALID_HEDGE;
	interpolate_truths();
	set_alphaCut(0.0);
}


TFuzzySet::TFuzzySet(TFuzzySet& set2)
{
	set_variable(set2.get_variable());
    if (set2.get_name() != NULL)
   	{
   		name	= new char[strlen(set2.get_name())+1];
        strcpy(name, set2.get_name());
   	}
	set_shape(set2.get_shape());
	set_direction(set2.get_direction());
	set_min (set2.get_min());
	set_mid1(set2.get_mid1());
	set_mid (set2.get_mid());
	set_mid2(set2.get_mid2());
	set_max (set2.get_max());
	set_minTruth(set2.get_minTruth());
	set_maxTruth(set2.get_maxTruth());
	for(int i=0; i<MAX_HEDGES; i++)    	hedges[i] = set2.hedges[i];
	for(int i=0; i<DOMAIN_POINTS; i++) 	truths[i] = set2.truths[i];
	set_alphaCut(set2.get_alphaCut());
}


// convert scalar into a singleton fuzzy set
TFuzzySet::TFuzzySet(double scalar)
{
	variable	= new TVariable();
    name 		= new char[strlen("Singleton")+1];	strcpy(name, "Singleton");
	shape		= SINGLETON;
	direction	= UP;
	if (scalar  < variable->begin) scalar = variable->begin;
	if (scalar  > variable->end)   scalar = variable->end;
	min			= ((scalar - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
	mid1		= ((scalar - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
	mid			= ((scalar - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
	mid2		= ((scalar - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
	max			= ((scalar - variable->begin)/(variable->end - variable->begin))*DOMAIN_WIDTH;
	minTruth	= 0.0;
	maxTruth	= 1.0;
	for(int i=0; i<DOMAIN_POINTS; i++) 	truths[i] = ZERO_TRUTH;
	for(int i=0; i<MAX_HEDGES; i++)    	hedges[i] = INVALID_HEDGE;
	interpolate_truths();
	set_alphaCut(0.0);
}


TFuzzySet::~TFuzzySet()
{
	// variable is parent so don't delete
    variable = NULL;
	if (name != NULL) delete[] name;
    name = NULL;
}






void TFuzzySet::interpolate_truths()
{
	switch (shape)
    {
    	case NO_SHAPE:
        	{
				for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
				for (int x=min; x<=max; x++)
				{
			   		truths[x] = ZERO_TRUTH;
				}
				for (int x=max+1; x<DOMAIN_POINTS; x++)	{ truths[x] = ZERO_TRUTH; }
            }
            break;
    	case SINGLETON:
        	{
				for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
				for (int x=min; x<mid; x++)
				{
			   		truths[x] = minTruth;
				}

		   		truths[(int)mid] = maxTruth;

				for (int x=mid+1; x<=max; x++)
				{
			   		truths[x] = minTruth;
				}
				for (int x=max+1; x<DOMAIN_POINTS; x++)	{ truths[x] = ZERO_TRUTH; }
			}
            break;
    	case PLATEAU:
           	{
				for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
				for (int x=min; x<=max; x++)
				{
			   		truths[x] = maxTruth;
				}
				for (int x=max+1; x<DOMAIN_POINTS; x++)	{ truths[x] = ZERO_TRUTH; }
            }
            break;
    	case LINEAR:
        	{
  			  for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
			  if(direction == UP)
              {
              	for (int x=min; x<=max; x++)
				{
			   		truths[x] = minTruth + (x-min) * ((maxTruth-minTruth)/(max-min));
				}
              }
              else if(direction == DOWN)
              {
              	for (int x=min; x<=max; x++)
				{
			   		truths[x] = maxTruth - (x-min) * ((maxTruth-minTruth)/(max-min));
				}
              }
			  for (int x=max+1; x<DOMAIN_POINTS; x++)	{ truths[x] = ZERO_TRUTH; }
            }
            break;
    	case TRIANGLE:
        	{
				for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
				for (int x=min; x<mid; x++)
				{
			   		truths[x] = minTruth + (x-min) * ((maxTruth-minTruth)/(mid-min));
				}
				for (int x=mid; x<=max; x++)
				{
			   		truths[x] = maxTruth - (x-mid) * ((maxTruth-minTruth)/(max-mid));
				}
				for (int x=max+1; x<DOMAIN_POINTS; x++) { truths[x] = ZERO_TRUTH; }
            }
            break;
    	case TRAPEZOIDAL:
        	{
				for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
				for (int x=min; x<mid1; x++)
				{
			   		truths[x] = minTruth + (x-min) * ((maxTruth-minTruth)/(mid1-min));
				}
				for (int x=mid1; x<mid2; x++)
				{
			   		truths[x] = maxTruth;
				}
				for (int x=mid2; x<=max; x++)
				{
			   		truths[x] = maxTruth - (x-mid2) * ((maxTruth-minTruth)/(max-mid2));
				}
				for (int x=max+1; x<DOMAIN_POINTS; x++) { truths[x] = ZERO_TRUTH; }
            }
            break;
    	case SHOULDER:
        	{
			  for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
              if(direction == LEFT)
              {
				for (int x=min; x<mid; x++)
				{
			   		truths[x] = maxTruth;
				}
				for (int x=mid; x<=max; x++)
				{
			   		truths[x] = maxTruth - (x-mid) * ((maxTruth-minTruth)/(max-mid));
				}
              }
			  else if(direction == RIGHT)
              {
				for (int x=min; x<mid; x++)
				{
			   		truths[x] = minTruth + (x-min) * ((maxTruth-minTruth)/(mid-min));
				}
				for (int x=mid; x<=max; x++)
				{
			   		truths[x] = maxTruth;
				}
              }
			  for (int x=max+1; x<DOMAIN_POINTS; x++) 	{ truths[x] = ZERO_TRUTH; }
            }
            break;
    	case S_CURVE:
        	{
			  for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
			  if(direction == UP)
              {
              	for (int x=min; x<mid; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(2* ( ((x-min)/((mid-min)*2)) * ((x-min)/((mid-min)*2)) ));
				}
              	for (int x=mid; x<=max; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(1 - 2* ( ((max-x)/((max-mid)*2)) * ((max-x)/((max-mid)*2)) ));
				}
              }
              else if(direction == DOWN)
              {
              	for (int x=min; x<mid; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(1 - (2* ( ((x-min)/((mid-min)*2)) * ((x-min)/((mid-min)*2)) )));
				}
              	for (int x=mid; x<=max; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(1 - (1 - 2* ( ((max-x)/((max-mid)*2)) * ((max-x)/((max-mid)*2)) )));
				}
              }
			  for (int x=max+1; x<DOMAIN_POINTS; x++)	{ truths[x] = ZERO_TRUTH; }
            }
            break;
    	case PI_CURVE:
        	{
				for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
              	for (int x=min; x<mid1; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(2* ( ((x-min)/((mid1-min)*2)) * ((x-min)/((mid1-min)*2)) ));
				}
              	for (int x=mid1; x<mid; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(1 - 2* ( ((mid-x)/((mid-mid1)*2)) * ((mid-x)/((mid-mid1)*2)) ));
				}
              	for (int x=mid; x<mid2; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(1 - (2* ( ((x-mid)/((mid2-mid)*2)) * ((x-mid)/((mid2-mid)*2)) )));
				}
              	for (int x=mid2; x<=max; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(1 - (1 - 2* ( ((max-x)/((max-mid2)*2)) * ((max-x)/((max-mid2)*2)) )));
				}
				for (int x=max+1; x<DOMAIN_POINTS; x++)	{ truths[x] = ZERO_TRUTH; }
            }
            break;
    	case BETA_CURVE:
        	{
				for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
              	for (int x=min; x<mid; x++)
				{
			   		truths[x] = 1 / ( 1 + ( ((mid-x)/(mid1-min)) * ((mid-x)/(mid1-min)) ) );
				}
              	for (int x=mid; x<=max; x++)
				{
			   		truths[x] = 1 / ( 1 + ( ((x-mid)/(mid2-mid)) * ((x-mid)/(mid2-mid)) ) );
				}
				for (int x=max+1; x<DOMAIN_POINTS; x++)	{ truths[x] = ZERO_TRUTH; }
            }
            break;
    	case GAUSSIAN_CURVE:
        	{
				for (int x=0; x<min; x++)				{ truths[x] = ZERO_TRUTH; }
              	for (int x=min; x<mid; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(exp( -(mid-min) * ((mid-x)/max)*((mid-x)/max) ));
				}
              	for (int x=mid; x<=max; x++)
				{
			   		truths[x] = minTruth+(maxTruth-minTruth)*(exp( -(max-mid) * ((x-mid)/max)*((x-mid)/max) ));
				}
				for (int x=max+1; x<DOMAIN_POINTS; x++)	{ truths[x] = ZERO_TRUTH; }
            }
            break;
    	default:
				for (int x=0; x<DOMAIN_POINTS; x++) 	{ truths[x] = ZERO_TRUTH; }
    }
}




void TFuzzySet::clear_hedges()
{
  for(int i=0; i<MAX_HEDGES; i++)
  {
  	hedges[i] == INVALID_HEDGE;
  }
}


void TFuzzySet::add_hedge (int type)
{
  for(int i=0; i<MAX_HEDGES; i++)
  {
  	if (hedges[i] == INVALID_HEDGE)
    {
		hedges[i] = type;

		switch(type)
        {
// negation
          case NOT:				// !
          {
			*this = !*this;
          }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -