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

📄 tfuzzyrule.cpp

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



////////////////////////////////////////////////////////////////////////////////
// TPremise implementation
////////////////////////////////////////////////////////////////////////////////
TPremise::TPremise(TFuzzySet* _fuzzyset, double _scalar)
{
	// make a copy of  TStrings
    fuzzyset = new TFuzzySet(*_fuzzyset);

	if (_scalar  < _fuzzyset->get_variable()->begin) _scalar = _fuzzyset->get_variable()->begin;
	if (_scalar  > _fuzzyset->get_variable()->end)   _scalar = _fuzzyset->get_variable()->end;
	scalar	= ((_scalar - _fuzzyset->get_variable()->begin)/(_fuzzyset->get_variable()->end - _fuzzyset->get_variable()->begin))*DOMAIN_WIDTH;
}


TPremise::~TPremise()
{
    if (fuzzyset != NULL) delete  fuzzyset;
    fuzzyset = NULL;
}

// unify scalar to fuzzyset->variable domain
void TPremise::set_scalar(double _scalar)
{
	if (fuzzyset != NULL)
    {
		if (fuzzyset->get_variable() != NULL)
    	{
		if (_scalar  < fuzzyset->get_variable()->begin) _scalar = fuzzyset->get_variable()->begin;
		if (_scalar  > fuzzyset->get_variable()->end)   _scalar = fuzzyset->get_variable()->end;
		scalar	= ((_scalar - fuzzyset->get_variable()->begin)/(fuzzyset->get_variable()->end - fuzzyset->get_variable()->begin))*DOMAIN_WIDTH;
        }
    }
}


double	TPremise::Evaluate()
{
   	if (fuzzyset != NULL)
    {
   		return (*fuzzyset)[scalar];
    }
    else
    {
  		return ZERO_TRUTH;
    }
}


bool	TPremise::operator == 	(TPremise&	premise2)
{
   	return ( (scalar == premise2.scalar) && (fuzzyset == premise2.fuzzyset) );
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////





////////////////////////////////////////////////////////////////////////////////
// TPredicate implementation
////////////////////////////////////////////////////////////////////////////////
TPredicate::TPredicate()
{
	for (int i=0; i<MAX_PREMISES_PER_PREDICATE; i++)
    {
    	premises[i] = NULL;
    }
	for (int i=0; i<MAX_PREMISES_PER_PREDICATE-1; i++)
    {
    	operators[i] = INVALID_OPERATOR;
    }
}


TPredicate::~TPredicate()
{
   	clear_premises();
   	clear_operators();
}



void TPredicate::clear_premises()
{
  for (int i=0; i<MAX_PREMISES_PER_PREDICATE; i++)
  {
		if (premises[i] != NULL) delete premises[i];
    	premises[i] = NULL;
  }
}


void TPredicate::add_premise(TPremise* _premise)
{
  for (int i=0; i<MAX_PREMISES_PER_PREDICATE; i++)
  {
  	if (premises[i] == NULL)
    {
		premises[i] = _premise;
  	    break;
    }
  }
}


void TPredicate::remove_premise(TPremise* _premise)
{
  for (int i=0; i<MAX_PREMISES_PER_PREDICATE; i++)
  {
  	if (*(premises[i]) == *_premise)
    {
		delete premises[i];
		// shift up
		for (int j=i; j<MAX_PREMISES_PER_PREDICATE-1; j++)
    	{
			premises[j] = premises[j+1];
	    }
		// invalidate last
        premises[MAX_PREMISES_PER_PREDICATE-1] = NULL;
        break;
    }
  }
}



void TPredicate::clear_operators()
{
  for (int i=0; i<MAX_PREMISES_PER_PREDICATE; i++)
  {
		operators[i] = INVALID_OPERATOR;
  }
}

void TPredicate::add_operator(int _operator)
{
  for (int i=0; i<MAX_PREMISES_PER_PREDICATE-1; i++)
  {
  	if (operators[i] == INVALID_OPERATOR)
    {
		operators[i] = _operator;
  	    break;
    }
  }
}


void TPredicate::remove_operator(int _operator)
{
  for (int i=0; i<MAX_PREMISES_PER_PREDICATE-1; i++)
  {
  	if (operators[i] == _operator)
    {
		operators[i] = INVALID_OPERATOR;
		// shift up
		for (int j=i; j<MAX_PREMISES_PER_PREDICATE-2; j++)
    	{
			operators[j] = operators[j+1];
	    }
		// default last
        operators[MAX_PREMISES_PER_PREDICATE-2] = AND;
        break;
    }
  }
}



double TPredicate::Aggregate(int how)			// ZADEH, MEAN, ... PRODUCT, BONDEDSUM
{
	double aggregation_scalar = INVALID_DOMAIN;
   	if (premises[0] != NULL)
    {
		aggregation_scalar = premises[0]->Evaluate();
		for (int i=0; i<MAX_PREMISES_PER_PREDICATE-1; i++)
		{
    		if (premises[i+1] != NULL)
   		    {
    			if (operators[i] == AND)
        	    {
					switch(how)
				   	{
						case ZADEH:			//					min(s1,s2)
				        {
					    	aggregation_scalar = min(aggregation_scalar, premises[i+1]->Evaluate());
				        }
				        break;
						case MEAN:			//      	    	(s1+s2)/2
				        {
					   		aggregation_scalar= (
			                    					(aggregation_scalar + premises[i+1]->Evaluate())
				                                 ) / 2;
				        }
				        break;
						case MEANSQUARE:	//         			((s1+s2)/2)^2
				        {
					   		aggregation_scalar= pow(((
			                    					(aggregation_scalar + premises[i+1]->Evaluate())
					                            ) / 2), 2);
				        }
				        break;
						case MEANROOT:		//					((s1+s2)/2)^.5
				        {
					   		aggregation_scalar= pow(((
			                    					(aggregation_scalar + premises[i+1]->Evaluate())
					                            ) / 2), 0.5);
				        }
				        break;
						case PRODUCT:		//						s1*s2
				        {
					   		aggregation_scalar = aggregation_scalar * premises[i+1]->Evaluate();
				        }
				        break;
						case BOUNDEDSUM:	//					max(0,(s1+s2-1))
				        {
					   		aggregation_scalar= max(0.0,  (aggregation_scalar + premises[i+1]->Evaluate() - 1.0));
				        }
				        break;
				    }
    	        }
   			    else if (operators[i] == OR)
	            {
					switch(how)
				   	{
						case ZADEH:			//					max(s1,s2)
				        {
					    	aggregation_scalar = max(aggregation_scalar, premises[i+1]->Evaluate());
				        }
				        break;
						case MEAN:			//      	    	(2*min(s1,s2)+4*max(s1,s2))/6
				        {
					   		aggregation_scalar= (
				                    					2 * min(aggregation_scalar, premises[i+1]->Evaluate())
				                    					+
														4 * max(aggregation_scalar, premises[i+1]->Evaluate())
				                                 ) / 6;
				        }
				        break;
						case MEANSQUARE:	//         			((2*min(s1,s2)+4*max(s1,s2))/6)^2
				        {
					   		aggregation_scalar= pow(((
				                    					2 * min(aggregation_scalar, premises[i+1]->Evaluate())
				                    					+
														4 * max(aggregation_scalar, premises[i+1]->Evaluate())
					                            ) / 6), 2);
				        }
				        break;
						case MEANROOT:		//					((2*min(s1,s2)+4*max(s1,s2))/6)^.5
				        {
					   		aggregation_scalar= pow(((
				                    					2 * min(aggregation_scalar, premises[i+1]->Evaluate())
				                    					+
														4 * max(aggregation_scalar, premises[i+1]->Evaluate())
					                            ) / 6), 0.5);
				        }
				        break;
						case PRODUCT:		//					(s1+s2)-(s1*s2)
				        {
					   		aggregation_scalar = (aggregation_scalar + premises[i+1]->Evaluate()) - (aggregation_scalar * premises[i+1]->Evaluate());
				        }
				        break;
						case BOUNDEDSUM:	//					min(1,(s1+s2))
				        {
					   		aggregation_scalar= min(1.0,  (aggregation_scalar + premises[i+1]->Evaluate()));
				        }
				        break;
				    }
        	    }
		    }
            else
            {
               	break;
            }
    	}
    }
    return aggregation_scalar;
}


bool  TPredicate::operator ==	(TPredicate&	predicate2)
{
	for (int i=0; i<MAX_PREMISES_PER_PREDICATE; i++)
    {
    	if (!(premises[i] == predicate2.premises[i])) return false;
    }
	for (int i=0; i<MAX_PREMISES_PER_PREDICATE-1; i++)
    {
    	if (!(operators[i] == predicate2.operators[i])) return false;
    }
   	return true;
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////






////////////////////////////////////////////////////////////////////////////////
// TConsequent implementation
////////////////////////////////////////////////////////////////////////////////
TConsequent::TConsequent()
{
	premise = NULL;
}


TConsequent::~TConsequent()
{
	if (premise != NULL) delete premise;
	premise = NULL;
}


void TConsequent::set_premise(TPremise* _premise)
{
	if (premise != NULL) delete premise;
	premise = _premise;
}



TFuzzySet* TConsequent::Correlate(double aggregation_scalar, int how)	// TRUNCATE, SCALE
{
    // create a new fuzzyset to keep original "Consequent->premise->fuzzyset" intacted
    // and assign to FuzzyRule->result_set
    TFuzzySet* result_set = new TFuzzySet(*(premise->fuzzyset));
	switch (how)
    {
       	case TRUNCATE:
    	{
			result_set->truncate(aggregation_scalar);	// chop-off everything above max
        }
        break;
       	case SCALE:
    	{
			result_set->scale_down(aggregation_scalar);	// scale down, preserve shape
	    }
        break;
    }
    return result_set;
}


bool  TConsequent::operator ==	(TConsequent&	consequent2)
{
   	return (premise == consequent2.premise);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////






////////////////////////////////////////////////////////////////////////////////
// TFuzzyRule implementation
////////////////////////////////////////////////////////////////////////////////

TFuzzyRule::TFuzzyRule(bool _conditional, double _alphaCut, double _weight)
{
	conditional	= _conditional;
    predicate	= new TPredicate();
    consequent	= new TConsequent();
	result_set	= NULL;
	alphaCut	= _alphaCut;
	weight		= _weight;
}


TFuzzyRule::~TFuzzyRule()
{
	if (result_set  != NULL) delete result_set;
    result_set = NULL;
    if (consequent	!= NULL) delete consequent;
    consequent = NULL;
    if (predicate	!= NULL) delete predicate;
    predicate = NULL;
}





void	TFuzzyRule::Correlate(
		   				int aggregation_method,		// ZADEH, MEAN, ... PRODUCT, BONDEDSUM
                	    int correlation_method		// TRUNCATE, SCALE
	           				 )
{
    if (conditional)
    {
		double aggregation_scalar = predicate->Aggregate(aggregation_method);
		result_set = consequent->Correlate(aggregation_scalar, correlation_method);
    }
    else if (!conditional)
    {
       	if ( (consequent->premise != NULL) && (predicate->premises[0] != NULL) )
        {
		    // create a new fuzzyset to keep original "predicate->premise->fuzzyset" intacted
		    // and assign to FuzzyRule->result_set
	    	result_set = new TFuzzySet(*(predicate->premises[0]->fuzzyset));
        }
    }
}


void 	TFuzzyRule::ApplyAlphaCut(  // restrict output to area   >   or   >=   alphaCut
	           				        int alphaCut_type		// STRONG, WEAK
   							      )
{
	result_set->set_alphaCut(alphaCut);
	result_set->apply_alphaCut(alphaCut_type);
}


void	TFuzzyRule::ApplyWeight	 (	// scale-down correlated output by weight
   					    	 	 )
{
	result_set->scale_down(weight);
}



TFuzzySet* 	TFuzzyRule::Evaluate (
		   				int aggregation_method,			// ZADEH, MEAN, ... PRODUCT, BONDEDSUM
                	    int correlation_method,			// TRUNCATE, SCALE
	           			int alphaCut_type				// STRONG, WEAK
    					     	 )
{
    Correlate	 (aggregation_method, correlation_method);
    ApplyAlphaCut(alphaCut_type);
    ApplyWeight	 ();
	return result_set;
}



bool TFuzzyRule::operator == (TFuzzyRule& rule2)
{
	if (conditional  != rule2.conditional) return false;
	if (!(predicate  == rule2.predicate))  return false;
	if (!(consequent == rule2.consequent)) return false;
	if (alphaCut     != rule2.alphaCut)    return false;
	if (weight       != rule2.weight)      return false;
    return true;
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


⌨️ 快捷键说明

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