davidgrupp / Fuzzy-Logic-Sharp

Fuzzy Logic Sharp for .NET
Apache License 2.0
44 stars 24 forks source link

Error in membership function #4

Open damiantestkonto opened 3 years ago

damiantestkonto commented 3 years ago

In submited example I added for loop to iterate through all water temperatures:

var water = new LinguisticVariable("Water");
var cold = water.MembershipFunctions.AddTrapezoid("Cold", 0, 0, 20, 40);
var warm = water.MembershipFunctions.AddTriangle("Warm", 30, 50, 70);
var hot = water.MembershipFunctions.AddTrapezoid("Hot", 50, 80, 100, 100);

var power = new LinguisticVariable("Power");
var low = power.MembershipFunctions.AddTriangle("Low", 0, 25, 50);
var high = power.MembershipFunctions.AddTriangle("High", 25, 50, 75);

IFuzzyEngine fuzzyEngine = new FuzzyEngineFactory().Default();

var rule1 = Rule.If(water.Is(cold).Or(water.Is(warm))).Then(power.Is(high));
var rule2 = Rule.If(water.Is(hot)).Then(power.Is(low));
fuzzyEngine.Rules.Add(rule1, rule2);

// ------------------------ my edit ------------------------
for (int i = 0; i <= 100; i++)
{
    var result = fuzzyEngine.Defuzzify(new { water = i });
    Console.WriteLine($"water = {i}    result= {result}");
}
// ------------------------ my edit ------------------------

Which give me:

water = 0      result = 50
water = 1      result = 50
water = 2      result = 50
water = 3      result = 50
water = 4      result = 50
water = 5      result = 50
water = 6      result = 50
water = 7      result = 50
water = 8      result = 50
water = 9      result = 50
water = 10     result = 50
water = 11     result = 50
water = 12     result = 50
water = 13     result = 50
water = 14     result = 50
water = 15     result = 50
water = 16     result = 50
water = 17     result = 50
water = 18     result = 50
water = 19     result = 50
water = 20     result = 50
water = 21     result = 50
water = 22     result = 50
water = 23     result = 50
water = 24     result = 50
water = 25     result = 50
water = 26     result = 50
water = 27     result = 50
water = 28     result = 50
water = 29     result = 50
water = 30     result = 50
water = 31     result = 50
water = 32     result = 50
water = 33     result = 50
water = 34     result = 50
water = 35     result = 50
water = 36     result = 50
water = 37     result = 50
water = 38     result = 50
water = 39     result = 50
water = 40     result = 50
water = 41     result = 50
water = 42     result = 50
water = 43     result = 50
water = 44     result = 50
water = 45     result = 50
water = 46     result = 50
water = 47     result = 50
water = 48     result = 50
water = 49     result = 50
water = 50     result = 50
water = 51     result = 49.193548387096776
water = 52     result = 48.4375
water = 53     result = 47.72727272727273
water = 54     result = 47.05882352941176
water = 55     result = 46.42857142857144
water = 56     result = 45.833333333333336
water = 57     result = 45.27027027027027
water = 58     result = 44.73684210526316
water = 59     result = 44.23076923076923
water = 60     result = 43.75000000000001
water = 61     result = 43.29268292682927
water = 62     result = 42.857142857142854
water = 63     result = 42.44186046511628
water = 64     result = 42.04545454545455
water = 65     result = 41.666666666666664
water = 66     result = 41.30434782608696
water = 67     result = 40.95744680851064
water = 68     result = 40.625
water = 69     result = 40.30612244897959
water = 70     result = 40
water = 71     result = 39.705882352941174
water = 72     result = 39.42307692307693
water = 73     result = 39.15094339622641
water = 74     result = 38.888888888888886
water = 75     result = 38.63636363636364
water = 76     result = 38.39285714285714
water = 77     result = 38.1578947368421
water = 78     result = 37.931034482758626
water = 79     result = 37.71186440677966
water = 80     result = 37.5
water = 81     result = 37.5
water = 82     result = 37.5
water = 83     result = 37.5
water = 84     result = 37.5
water = 85     result = 37.5
water = 86     result = 37.5
water = 87     result = 37.5
water = 88     result = 37.5
water = 89     result = 37.5
water = 90     result = 37.5
water = 91     result = 37.5
water = 92     result = 37.5
water = 93     result = 37.5
water = 94     result = 37.5
water = 95     result = 37.5
water = 96     result = 37.5
water = 97     result = 37.5
water = 98     result = 37.5
water = 99     result = 37.5
water = 100    result = 37.5

Why there are no result between 50 and 75? Also, there are no result between 25 and 50.

maciejewiczow commented 2 years ago

Same here, tried using this library in my uni assignment but kept getting wrong answers. Something is not right here

davidgrupp commented 2 years ago

I believe you need to do fuzzyEngine = new FuzzyEngineFactory().Default(); for each iteration. It was pointed out in another issue the engine only works once. I haven't re-run your test with this to verify.

whippet71 commented 2 years ago

I have modified the code to create a new FuzzyEngine in each iteration, but the results still don't seem right. Using:

var water = new LinguisticVariable("Water");
var cold = water.MembershipFunctions.AddTrapezoid("Cold", 0, 0, 20, 40);
var warm = water.MembershipFunctions.AddTriangle("Warm", 30, 50, 70);
var hot = water.MembershipFunctions.AddTrapezoid("Hot", 50, 80, 100, 100);

var power = new LinguisticVariable("Power");
var low = power.MembershipFunctions.AddTriangle("Low", 0, 25, 50);
var high = power.MembershipFunctions.AddTriangle("High", 25, 50, 75);

FuzzyRule[] rules = new FuzzyRule[2];
rules[0] = Rule.If(water.Is(cold).Or(water.Is(warm))).Then(power.Is(high));
rules[1] = Rule.If(water.Is(hot)).Then(power.Is(low));

for (int i=0; i<=100; i+=10)
{
    IFuzzyEngine fuzzyEngine = new FuzzyEngineFactory().Default();
    fuzzyEngine.Rules.Add(rules[0], rules[1]);
    Console.WriteLine("Temp: {0} Cold: {1} Warm: {2} Hot: {3} Result: {4}", i, cold.Fuzzify(i), warm.Fuzzify(i), hot.Fuzzify(i), fuzzyEngine.Defuzzify(new { water = i }));
}

Console.ReadLine();

gives the following results:

Temp: 0 Cold: 1 Warm: 0 Hot: 0 Result: 50 Temp: 10 Cold: 1 Warm: 0 Hot: 0 Result: 50 Temp: 20 Cold: 1 Warm: 0 Hot: 0 Result: 50 Temp: 30 Cold: 0.5 Warm: 0 Hot: 0 Result: 50 Temp: 40 Cold: 0 Warm: 0.5 Hot: 0 Result: 50 Temp: 50 Cold: 0 Warm: 1 Hot: 0 Result: 50 Temp: 60 Cold: 0 Warm: 0.5 Hot: 0.3333333333333333 Result: 43.75000000000001 Temp: 70 Cold: 0 Warm: 0 Hot: 0.6666666666666666 Result: 40 Temp: 80 Cold: 0 Warm: 0 Hot: 1 Result: 37.5 Temp: 90 Cold: 0 Warm: 0 Hot: 1 Result: 37.5 Temp: 100 Cold: 0 Warm: 0 Hot: 1 Result: 37.5

So, I understand the results at low temperatures - the membership of the "high" function is one, so it chooses the centre of the "high" triangle, which is 50. But at high water temperatures, I would expect the result to be the centre of the "low" triangle, which is 25. But instead we get 37.5 - so it seems to be computing the centre of both the high and low triangles, which is incorrect.