Go言語を使った自作のファジィ(Fuzzy)推論コードを探していたのですが、見つけることができずにちょっとショックを受けております。
というか、Go言語どころか、C言語でも見つけられなかった(いや、あるはずだ)ので、今、PCの中探して見つかったものをアップしておきます。
毎回スクラッチから作るのも迂遠なので。
↓のコードですが、こちらのコラムで使ったものだと思います。
#include <stdio.h>
#include <stdlib.h>
double max(double a){
return a;
}
double max(double a, double b){
if (a > b)
return a;
else
return b;
};
double max(double a, double b, double c ){
return max(max(a,b), max(b,c));
};
double max(double a, double b, double c, double d ){
return max(max(a,b,c), d);
};
double min(double a){
return a;
}
double min(double a, double b){
if (b > a)
return a;
else
return b;
};
double min(double a, double b, double c ){
return min(min(a,b), min(b,c));
};
double min(double a, double b, double c, double d ){
return min(min(a,b,c), d);
};
typedef enum scale {LESSLESS, LESS, ZERO, MORE, MOREMORE} SCALE;
class condition_MF3
{
private:
double center;
double width;
SCALE express;
public:
condition_MF3(double _center, double _witdth, SCALE _express){
center = _center;
width = _witdth;
express = _express;
if ((express == LESSLESS) || (express == MOREMORE)){
printf("wrong expression used \n");
exit(0);
}
};
double func(double _x);
};
double condition_MF3::func(double _x)
{
double x = _x;
double y = 0.0;
if (express == LESS){
if (x <= center - width){
y = 1.0;
}
else if (x <= center){
y = - 1.0 / width * (x - center);
}
else{
y = 0.0;
}
}
else if (express == ZERO){
if (x <= center - width){
y = 0.0;
}
else if (x <= center){
y = 1.0 / width * (x - center) + 1.0;
}
else if (x <= center + width){
y = -1.0 / width * (x - center) + 1.0;
}
else{
y = 0.0;
}
}
else if (express == MORE){
if (x <= center){
y = 0.0;
}
else if (x <= center + width){
y = 1.0 / width * (x - center);
}
else{
y = 1.0;
}
}
else {
printf("wrong expression\n");
exit(1);
}
return y;
};
class condition_MF5
{
private:
double center;
double width;
SCALE express;
public:
condition_MF5(double _center, double _witdth, SCALE _express){
center = _center;
width = _witdth;
express = _express;
};
double func(double _x);
};
double condition_MF5::func(double _x)
{
double x = _x;
double y = 0.0;
if (express == LESSLESS){
if (x <= center - 2.0 * width){
y = 1.0;
}
else if (x <= center - width){
y = - 1.0 / width * (x - (center - 2.0 * width)) + 1.0;
}
else{
y = 0.0;
}
}
else if (express == LESS){
if (x <= center - 2.0 * width){
y = 0.0;
}
else if (x <= center - width){
y = 1.0 / width * (x - (center - width)) + 1.0;
}
else if (x <= center){
y = -1.0 / width * (x - (center - width)) + 1.0;
}
else{
y = 0.0;
}
}
else if (express == ZERO){
if (x <= center - width){
y = 0.0;
}
else if (x <= center){
y = 1.0 / width * (x - center) + 1.0;
}
else if (x <= center + width){
y = -1.0 / width * (x - center) + 1.0;
}
else{
y = 0.0;
}
}
else if (express == MORE){
if (x <= center){
y = 0.0;
}
else if (x <= center + width){
y = 1.0 / width * (x - (center + width)) + 1.0;
}
else if (x <= center + 2.0 * width){
y = -1.0 / width * (x - (center + width)) + 1.0;
}
else{
y = 0.0;
}
}
else if (express == MOREMORE){
if (x <= center + width){
y = 0.0;
}
else if (x <= center + 2.0 * width){
y = 1.0 / width * (x - (center + 2.0 * width)) + 1.0;
}
else{
y = 1.0;
}
}
return y;
};
class action_MF3
{
private:
double center;
double width;
SCALE express;
double x;
double y;
public:
action_MF3(double _center, double _witdth, SCALE _express){
y = 0.0;
center = _center;
width = _witdth;
express = _express;
if (express == LESS){
x = center - width;
}
else if (express == ZERO){
x = center;
}
else if (express == MORE){
x = center + width;
}
else{
printf("wrong scale expression\n");
exit(0);
}
};
void func_Max(double b){
y = max(b, y);
};
double func_X(void){
return x;
};
double func_Y(){
return y;
};
};
class action_MF5
{
private:
double center;
double width;
SCALE express;
double x;
double y;
public:
action_MF5(double _center, double _witdth, SCALE _express){
y = 0.0;
center = _center;
width = _witdth;
express = _express;
if (express == LESSLESS){
x = center - 2.0 * width;
}
else if (express == LESS){
x = center - width;
}
else if (express == ZERO){
x = center;
}
else if (express == MORE){
x = center + width;
}
else if (express == MOREMORE){
x = center + 2.0 * width;
}
else{
printf("wrong scale expression\n");
}
};
void func_Max(double b){
y = max(b, y);
};
double func_X(void){
return x;
};
double func_Y(){
return y;
};
};
int main()
{
condition_MF3 Period_Short(14, 14, LESS);
condition_MF3 Period_Middle(14, 14, ZERO);
condition_MF3 Period_Long(14, 14, MORE);
condition_MF3 WeighChange_Small(1.0, 1.0, LESS);
condition_MF3 WeighChange_Middle(1.0, 1.0, ZERO);
condition_MF3 WeighChange_High(1.0, 1.0, MORE);
condition_MF3 Suffer_Zerol(400.0, 400.0, LESS);
condition_MF3 Suffer_Middle(400.0, 400.0, ZERO);
condition_MF3 Suffer_Hight(400.0, 400.0, MORE);
condition_MF5 BMI_lowlow(22.0, 3.0, LESSLESS);
condition_MF5 BMI_low(22.0, 3.0, LESS);
condition_MF5 BMI_Normal(22.0, 3.0, ZERO);
condition_MF5 BMI_High(22.0, 3.0, MORE);
condition_MF5 BMI_HighHigh(22.0, 3.0, MOREMORE);
action_MF5 Eat_LittleLittle(2500, 1000, LESSLESS);
action_MF5 Eat_Little(2500, 1000, LESS);
action_MF5 Eat_Normal(2500, 1000, ZERO);
action_MF5 Eat_Lot(2500, 1000, MORE);
action_MF5 Eat_LotLot(2500, 1000, MOREMORE);
double weight = 78.0;
double lengthw = 172.0;
double age = 49.0 + 94/365;
double consumption_calorie =
66.5 + weight * 13.8 + 172.0 * 5.0 - age * 6.8;
consumption_calorie += weight/66.5 * 708.0;
printf("consumption_calorie = %f\n", consumption_calorie);
double last_weight[14];
for (int i = 0; i++; i < 14){
last_weight[i] = weight;
}
for (int day=0; day < 1460; day++){
for (int i = 0; i++; i < 14-1 ){
last_weight[i+1] = last_weight[i];
}
last_weight[0] = weight;
double k1=0,k2=0,k3=0,k4=0;
for (int i = 0; i++; i < 14 ){
k1 += (double)i * (double)i;
k2 += (double)i * last_weight[i];
k3 += (double)i;
k4 += last_weight[i] *last_weight[i];
}
double dW = (14.0 * k2 - k3 * k4) / (14.0 * k4 - k3*k3);
double bmi = weight / 1.72 / 1.72;
double r1 = min(Period_Short.func(day));
Eat_Little.func_Max(r1);
double r2 = min(Period_Long.func(day),WeighChange_Small.func(dW));
Eat_LotLot.func_Max(r2);
double r3 = min(Period_Middle.func(day),WeighChange_Small.func(dW));
Eat_Normal.func_Max(r3);
double r4 = min(WeighChange_High.func(dW));
Eat_Little.func_Max(r4);
double r5 = min(Period_Long.func(day),BMI_High.func(bmi));
Eat_Little.func_Max(r5);
double r6 = min(Period_Long.func(day),BMI_HighHigh.func(bmi));
Eat_LittleLittle.func_Max(r6);
double source_calorie =
(Eat_LittleLittle.func_X() * Eat_LittleLittle.func_Y() +
Eat_Little.func_X() * Eat_Little.func_Y() +
Eat_Normal.func_X() * Eat_Normal.func_Y() +
Eat_Lot.func_X() * Eat_Lot.func_Y() +
Eat_LotLot.func_X() * Eat_LotLot.func_Y() )
/
(Eat_LittleLittle.func_Y() +
Eat_Little.func_Y() +
Eat_Normal.func_Y() +
Eat_Lot.func_Y() +
Eat_LotLot.func_Y() ) ;
printf("\n source_calorie = %f\n",source_calorie);
double diff_weight = (source_calorie - consumption_calorie)/7.0 / 1000.0;
weight += diff_weight;
age += 1.0/365.0;
consumption_calorie = 66.5 + weight * 13.8 + 172.0 * 5.0 - age * 6.8;
consumption_calorie += weight/66.5 * 708.0;
}
}
