📄 tfuzzyrule.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 + -