📄 fis.cpp
字号:
else{
//printf("Illegal ormethod\n");
}
}
}
else if (strncmp(namebuf, "ImpMethod", 9) == 0){
if (getString()){
if (strncmp(stringbuf, "min", 3) == 0){
imptype = MINAND;
}
else if (strncmp(stringbuf, "prod", 4) == 0){
imptype = PRODAND;
}
else{
//printf("Illegal impmethod\n");
}
}
}
else if (strncmp(namebuf, "AggMethod", 9) == 0){
if (getString()){
if (strncmp(stringbuf, "max", 3) == 0){
aggtype = MAXOR;
}
else if (strncmp(stringbuf, "probor", 6) == 0){
aggtype = PROBOR;
}
else{
//printf("Illegal aggmethod\n");
}
}
}
else if (strncmp(namebuf, "DefuzzMethod", 12) == 0){
if (getString()){
if (strncmp(stringbuf, "centroid", 8) == 0){
defzytype = CENTROID;
}
else if (strncmp(stringbuf, "wtsum", 5) == 0){
defzytype = WEIGHTSUM;
}
else{
//printf("Illegal defzytype\n");
}
}
}
else{
//printf("Illegal inputs\n");
}
}
if (numinputs <= 0 || numoutputs <= 0 || numrules <= 0) return False;
int mfsidx;
/* Read inputs */
fuzzyinputs = new FuzzyVariable[numinputs];
int i;
for(i = 0; i < numinputs ; i++){
while(AnalyzeNextEntry(fp)){
if (Islabel) break;
if (strncmp(namebuf, "Name", 4) == 0){
if (getString()){
strcpy(fuzzyinputs[i].name, stringbuf);
}
}
else if (strncmp(namebuf, "Range", 5) == 0){
tmp = sscanf(valuebuf, "[%f%f]", &fuzzyinputs[i].input_inf, &fuzzyinputs[i].input_sup);
if (tmp != 2 || fuzzyinputs[i].input_inf > fuzzyinputs[i].input_sup)
goto ExitReadInput;
}
else if (strncmp(namebuf, "NumMFs", 6) == 0){
tmp = sscanf(valuebuf, "%d", &fuzzyinputs[i].nummfs);
if (tmp != 1 || fuzzyinputs[i].nummfs <= 0)
goto ExitReadInput;
fuzzyinputs[i].mfs = new MemFunc[fuzzyinputs[i].nummfs];
mfsidx = 0;
}
else{
/* Membership functions */
if (fuzzyinputs[i].mfs == NULL){
goto ExitReadInput;
}
tmp = sscanf(valuebuf, "'%[^']' %[^']' %[^']' %[^[] [ %[^]]", fuzzyinputs[i].mfs[mfsidx].name, tmpbuf1,
tmpbuf2, tmpbuf3, tmpbuf4);
if (tmp != 5)
goto ExitReadInput;
tmp = sscanf(tmpbuf4, "%f%f%f%f%f", &fuzzyinputs[i].mfs[mfsidx].params[0],
&fuzzyinputs[i].mfs[mfsidx].params[1],
&fuzzyinputs[i].mfs[mfsidx].params[2],
&fuzzyinputs[i].mfs[mfsidx].params[3],
&fuzzyinputs[i].mfs[mfsidx].params[4]);
if (strncmp(tmpbuf2, "trimf", 5) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(TRIMF);
}
else if (strncmp(tmpbuf2, "gaussmf", 7) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(GAUSSMF);
}
else if (strncmp(tmpbuf2, "gauss2mf", 8) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(GAUSS2MF);
}
else if (strncmp(tmpbuf2, "trapmf", 6) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(TRAPMF);
}
else if (strncmp(tmpbuf2, "gbellmf", 7) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(GBELLMF);
}
else if (strncmp(tmpbuf2, "sigmf", 5) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(SIGMF);
}
else if (strncmp(tmpbuf2, "dsigmf", 6) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(DSIGMF);
}
else if (strncmp(tmpbuf2, "psigmf", 6) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(PSIGMF);
}
else if (strncmp(tmpbuf2, "zmf", 3) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(ZMF);
}
else if (strncmp(tmpbuf2, "pimf", 4) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(PIMF);
}
else if (strncmp(tmpbuf2, "smf", 3) == 0){
fuzzyinputs[i].mfs[mfsidx].SetMFType(SMF);
}
else{
//printf("Illegal membership function type\n");
}
if (tmp != fuzzyinputs[i].mfs[mfsidx].numparams)
goto ExitReadInput;
mfsidx ++;
}
}
if (fuzzyinputs[i].nummfs <= 0 || fuzzyinputs[i].mfs == NULL)
goto ExitReadInput;
}
ExitReadInput:
if (i != numinputs){
delete fuzzyinputs;
return False;
}
/* Read Output */
fuzzyoutputs = new FuzzyVariable[numoutputs];
for(i = 0; i < numoutputs ; i++){
if (!AnalyzeNextEntry(fp))
goto ExitReadOutput;
if (Islabel)
continue;
while(AnalyzeNextEntry(fp)){
if (Islabel) break;
if (strncmp(namebuf, "Name", 4) == 0){
if (getString()){
strcpy(fuzzyoutputs[i].name, stringbuf);
}
}
else if (strncmp(namebuf, "Range", 5) == 0){
tmp = sscanf(valuebuf, "[%f%f]", &fuzzyoutputs[i].input_inf, &fuzzyoutputs[i].input_sup);
if (tmp != 2 || fuzzyoutputs[i].input_inf > fuzzyoutputs[i].input_sup)
goto ExitReadOutput;
}
else if (strncmp(namebuf, "NumMFs", 6) == 0){
tmp = sscanf(valuebuf, "%d", &fuzzyoutputs[i].nummfs);
if (tmp != 1 || fuzzyoutputs[i].nummfs <= 0)
goto ExitReadOutput;
fuzzyoutputs[i].mfs = new MemFunc[fuzzyoutputs[i].nummfs];
mfsidx = 0;
}
else{
/* Membership functions */
if (fuzzyoutputs[i].mfs == NULL){
goto ExitReadOutput;
}
tmp = sscanf(valuebuf, "'%[^']' %[^']' %[^']' %[^[] [ %[^]]", fuzzyoutputs[i].mfs[mfsidx].name, tmpbuf1,
tmpbuf2, tmpbuf3, tmpbuf4);
if (tmp != 5)
goto ExitReadOutput;
tmp = sscanf(tmpbuf4, "%f%f%f%f%f", &fuzzyoutputs[i].mfs[mfsidx].params[0],
&fuzzyoutputs[i].mfs[mfsidx].params[1],
&fuzzyoutputs[i].mfs[mfsidx].params[2],
&fuzzyoutputs[i].mfs[mfsidx].params[3],
&fuzzyoutputs[i].mfs[mfsidx].params[4]);
if (strncmp(tmpbuf2, "trimf", 5) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(TRIMF);
}
else if (strncmp(tmpbuf2, "gaussmf", 7) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(GAUSSMF);
}
else if (strncmp(tmpbuf2, "gauss2mf", 8) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(GAUSS2MF);
}
else if (strncmp(tmpbuf2, "trapmf", 6) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(TRAPMF);
}
else if (strncmp(tmpbuf2, "gbellmf", 7) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(GBELLMF);
}
else if (strncmp(tmpbuf2, "sigmf", 5) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(SIGMF);
}
else if (strncmp(tmpbuf2, "dsigmf", 6) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(DSIGMF);
}
else if (strncmp(tmpbuf2, "psigmf", 6) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(PSIGMF);
}
else if (strncmp(tmpbuf2, "zmf", 3) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(ZMF);
}
else if (strncmp(tmpbuf2, "pimf", 4) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(PIMF);
}
else if (strncmp(tmpbuf2, "smf", 3) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(SMF);
}
else if (strncmp(tmpbuf2, "constant", 8) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(CONSTANT);
}
else if (strncmp(tmpbuf2, "linear", 8) == 0){
fuzzyoutputs[i].mfs[mfsidx].SetMFType(LINEAR);
}
else{
//printf("Illegal membership function type\n");
}
if (tmp != fuzzyoutputs[i].mfs[mfsidx].numparams)
goto ExitReadOutput;
mfsidx ++;
}
}
if (fuzzyoutputs[i].nummfs <= 0 || fuzzyoutputs[i].mfs == NULL)
goto ExitReadOutput;
}
ExitReadOutput:
if (i != numoutputs){
delete fuzzyoutputs;
return False;
}
/* Read rules */
rules = new Rule[numrules];
for(i = 0; i < numrules ; i++){
rules[i].SetRuleParams(numinputs, numoutputs);
if (!AnalyzeNextEntry(fp))
goto ExitReadRule;
if (Islabel) continue;
int p_buf = 0;
int j;
for(j = 0; j < numinputs; j ++){
if (sscanf(buf + p_buf, "%d", &rules[i].inputmfidx[j]) != 1)
goto ExitReadRule;
while( (*(buf + p_buf) < '0' || *(buf + p_buf) > '9') && *(buf + p_buf) !='-' && *(buf + p_buf) !=0 )
p_buf ++;
while( *(buf + p_buf) >= '0' && *(buf + p_buf) <= '9')
p_buf ++;
}
while( *(buf + p_buf) != ',' && *(buf + p_buf) != 0)
p_buf ++;
p_buf ++;
for(j = 0; j < numoutputs; j ++){
if (sscanf(buf + p_buf, "%d", &rules[i].outputmfidx[j]) != 1)
goto ExitReadRule;
while( (*(buf + p_buf) < '0' || *(buf + p_buf) > '9') && *(buf + p_buf) !='-' && *(buf + p_buf) !=0 )
p_buf ++;
while( *(buf + p_buf) >= '0' && *(buf + p_buf) <= '9')
p_buf ++;
}
if (sscanf(buf + p_buf, "%[^(](%f", tmpbuf1, &rules[i].weight) != 2)
goto ExitReadRule;
if (sscanf(buf + p_buf, "%[^:]:%d", tmpbuf1, &tmp) != 2)
goto ExitReadRule;
if (tmp == 1)
rules[i].rc_type = ANDRULE;
else if (tmp == 2)
rules[i].rc_type = ORRULE;
else{
//printf("Illegal rctype\n");
}
}
ExitReadRule:
if (i != numrules){
delete rules;
return False;
}
return True;
}
float FIS::AND(float x, float y){
return AND(x, y, andtype);
}
float FIS::AND(float x, float y, AndMethod and_type){
switch(and_type){
case MINAND: return x < y ? x : y;
case PRODAND: return x * y;
}
return x < y ? x : y;
}
float FIS::OR(float x, float y){
return OR(x, y, ortype);
}
float FIS::OR(float x, float y, ORMethod or_type){
switch(or_type){
case MAXOR: return x > y ? x : y;
case PROBOR: return x + y - x * y;
}
return x > y ? x : y;
}
void FIS::SetInput(int idx, float input){
if (idx <= 0 || idx > numinputs)
return;
fuzzyinputs[idx - 1].SetInput(input);
}
void FIS::SetInput(float* input){
int idx;
for(idx = 1; idx <= numinputs; idx ++){
fuzzyinputs[idx -1].SetInput(input[idx -1]);
}
}
void FIS::Fuzzify(){
int idx;
for(idx = 1; idx <= numinputs; idx ++){
fuzzyinputs[idx -1].Fuzzify();
}
}
void FIS::ApplyRule(int idx){
if (idx <= 0 || idx > numrules)
return;
float fire, tmp;
if (rules[idx -1].rc_type == ANDRULE){
fire = 1;
int i;
for(i = 1; i <= numinputs; i ++){
if (rules[idx -1].inputmfidx[i -1] == 0) continue;
tmp = fuzzyinputs[i -1].GetOutput(abs(rules[idx -1].inputmfidx[i -1]));
if (rules[idx -1].inputmfidx[i -1] < 0)
tmp = NOT(tmp);
fire = AND(fire, tmp);
}
}
else{
fire = 0;
int i;
for(i = 1; i <= numinputs; i ++){
if (rules[idx -1].inputmfidx[i -1] == 0) continue;
tmp = fuzzyinputs[i -1].GetOutput(abs(rules[idx -1].inputmfidx[i -1]));
if (rules[idx -1].inputmfidx[i -1] < 0)
tmp = NOT(tmp);
fire = OR(fire, tmp);
}
}
rules[idx -1].firestrength = fire;
}
float FIS::Imp_Defuzzy(int idx){
if (idx <= 0 || idx > numoutputs)
return 0.0f;
switch(defzytype){
case CENTROID:
return CentroidDefzy(idx);
break;
}
return 0.0f;
}
/* Intergral Simpson */
//no is the indicator of the different weight functions
float FIS::Simpson(int n, float a, float b, int no){
if(n <= 0) return 0.0f;
float h = (float) (b - a)/n, x;
float result = WeightFunc(b, no)+WeightFunc(a, no);
x = h/2 + a;
int k;
for(k = 0; k < n; k++)
result += 4 * WeightFunc(x, no), x += h;
x= h + a;
for(k = 1; k < n; k++)
result += 2 * WeightFunc(x, no), x += h;
result *= h/6;
return result;
}
float FIS::Gauss(int n, float a, float b, int no){
if (n<=0) return 0;
float h = (b-a) /n;
float result = 0;
int i;
for(i=0; i < n; i++){
result += WeightFunc((i+0.5f)*h+a-h/(2.0f*(float)sqrt(3.0f)), no)+WeightFunc((i+0.5f)*h+a+h/(2.0f*(float)sqrt(3.0f)), no);
}
result *= h/2;
return result;
}
float FIS::Romberg(int n, float a, float b, int no){
if (n<=0) return 0;
float* T = new float[n];
float h = b - a;
int i, k, t;
T[0] = h*(WeightFunc(a, no) + WeightFunc(b, no))/2;
t = 1;
for(k=1; k < n; k++){
T[k] = T[k-1]/2;
for(i=0; i<t; i++){
T[k] += h/2*WeightFunc(a+h*(i+0.5f), no);
}
h /= 2;
t *= 2;
}
t = 4;
for (k = 1; k < n; k++){
for(i = 0; i< n - k; i++)
T[i] = (t*T[i+1] - T[i]) / (t-1);
t *= 4;
}
float result = T[0];
delete T;
return result;
}
/* WeightFunc */
float FIS::WeightFunc(float x, int no){
float weight, tmp;
weight = 0.0f;
int i;
for(i = 1; i <= numrules; i ++){
if (rules[i -1].outputmfidx[outputidx -1] == 0) continue;
tmp = fuzzyoutputs[outputidx -1].GetMembership(abs(rules[i -1].outputmfidx[outputidx -1]), x);
if (rules[i -1].outputmfidx[outputidx -1] < 0)
tmp = NOT(tmp);
weight = OR(weight, AND(rules[i -1].GetFirestrength(), tmp, imptype), aggtype);
}
switch(no){
case 0:
break;
case 1:
weight *= x;
break;
}
return weight;
}
float FIS::CentroidDefzy(int idx){
outputidx = idx;
float sumweight;
sumweight = Simpson(10, 0, 1, 0);
if (sumweight == 0) return 0.0f;
return Simpson(10, 0, 1, 1)/ sumweight;
}
void FIS::FISRun(float *input, float * output){
SetInput(input);
Fuzzify();
int idx;
for(idx = 1; idx <= numrules; idx ++){
ApplyRule(idx);
}
for(idx = 1; idx <= numoutputs; idx ++){
output[idx -1] = Imp_Defuzzy(idx);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -