HƯỚNG DẪN FuzzyLogic

Joe

Thành viên VIP
21/1/13
2,969
1,311
113
Hi

What is fuzzy? Fuzzy is in lay language "unclear", "blurred", "vague". Fuzzy Logic is a logic that expresses an statement which is relatively near, but not exactly to the core. It's the nature of human whose expression is usually blurred, unclear and sometimes quite ambiguous. For example: "I don't feel good". The rating of "don't feel good" becomes ambiguous and unsharp, too. Such an "expression" would lead to the question that would be "why you don't feel good?", or "what's wrong?". And the answer for the question is just "a bit" more precise, but still quite ambiguous (e.g. "I drank yesterday too much", or "I got a bad night", etc.). Such an ambiguity is the logic of "free rating" and "free rating" lets no room for an alternative.

Lotfi Zadeh, an American Mathematician, introduced Fuzzy Logic in 1920:
It is based on the observation that people make decisions based on imprecise and non-numerical information, fuzzy models or sets are mathematical means of representing vagueness and imprecise information, hence the term fuzzy.
Impreciseness and Vagueness are the foundation of Fuzzy Logic.

Fuzzy Programming (FP)

It doesn't mean that one has to code "precisely" in Zadeh's FL in order to have FL. Because FL is itself "imprecise" the fuzziness that leads to the goal is decisive. Hence Fuzzy Programming can be materialized with conventional "technique", too. As said, the goal is decisive. The way how to achieve the goal is secondary, peripheral. And that can be done the best in any OOPL such as JAVA or PYTHON or C/C++. CongdongJava is a JAVA community and so Fuzzy Programming is here in JAVA. Fuzzy Programming is useful and so some case the best to reduce the overload (response time) and the excessive use of memory (performance.)

Let start with an example. To forecast the weather as the laymen we need to see the sky, observe the sun and feel the temperature:

- If the sky is blue, the sun shines and it's hot. No rain is predicted.
- If the sky is cloudy, the sun is observable behind the clouds and it's warm. No rain is predicted.
- If the sky is VERY cloudy, the sun is unseen behind the sky and it's windy-warm. It COULD be rainy as our prediction.
- If the sky is dark, NO the sun is seen behind the sky and it's windy-cool. Rain is expected.

All the four conditional predictions are vague and imprecise. They base on our "experiences" which are quite individual. It's kinda "empirical" science. Or to be exact: Fuzzy Logic or FL. The decision is made on vague values or vague experiences. To make FL understandable computer scientists and mathematicians try to formulate and to systematize the logics. The Set Theory was developed.


(Source: braungardt.trialectics.com)

And Lotfi Zadeh made it computable. Here is an explanation for the newbies


and for the advanced


To implement FL we need to consider FL as a REAL Programming Language (PL) which is slightly different to True-False PL like C, C++, JAVA, etc. What are the differences beside the True-False foundation? they are the floating values (vague) and the imprecise expressions. The True-False world knows the floating values, too (as float or a double) but it cannot expresses the "rates of a value" like you see in the Video for newbies with the Car-Automatic-Braking System. To materialize such an approach like FL we have to devise some different types of data and variables which are in C/C++ or JAVA like a "struct" or a POJO. CongdongJava as its name says a JAVA community POJO is our concern. The conversion between True-False world and Fuzzy World is called "defuzzy".

  • DATA: FuzzyData is our POJO which consists of either 3 doubles (PYRAMID) or 4 doubles (TRAPEZOID)
  • VARIABLE: FuzzyVariable is the other POJO which composes none to n FuzzyData.
  • EXPRESSION: only IF without ELSE (no alternative)

This image gives you an impression how the FuzzyVariable 'power' with FuzzyData looks like:

power.gif

The codes for JAVA:
CSS:
// FuzzyVariable with FuzzyData
<distance[dPL(75.0, 100.0, 400.0, 400.0),dPM(35.0, 50.0, 75.0, 100.0),dPS(0.0, 2.0, 35.0,50.0),dZE(-2.0, 0.0, 0.0, 2.0),dNS(-50.0, -35.0, -2.0, 0.0),dNM(-100.0, -75.0, -50.0, -35.0),dNL(-400.0, -400.0, -100.0, -75.0)]>
//
<angle[aNL(-4.0, -4.0, -0.314, -0.2616),aNS(-0.314, -0.2616, -0.0628, 0.0),aNE(-4.0, -4.0, -0.0628, 0.0),aZE(-0.0628, 0.0, 0.0, 0.0628),aPO(0.0, 0.0628, 4.0, 4.0),aPS(0.0, 0.0628, 0.2616, 0.314),aPL(0.2616, 0.314, 4.0, 4.0)]>
//
<power[pNL(-16.0, -15.0, -15.0, -14.0),pNM(-6.0, -5.0, -5.0, -4.0),pNS(-2.0, -1.0, -1.0, 0.0),pZE(-1.0, 0.0, 0.0, 1.0),pPS(0.0, 1.0, 1.0, 2.0),pPM(4.0, 5.0, 5.0, 6.0),pPL(14.0, 15.0, 15.0, 16.0)]>
// FuzzyLogic
angle = this:currentTheta
distance = this:distanceToTarget
if (distance is dNL) then power is pNL
if (distance is dPL) then power is pPL
if (distance is dNL and (angle is aNL or angle is aPL)) then power is pNM
if (distance is dPL && (angle is aNL || angle is aPL)) then power is pPM
if (distance is dNM) then power is pNM
if (distance is dPM) then power is pPM
if (distance is dNM && (angle is aNL || angle is aPL)) then power is pNS
if (distance is dPM && (angle is aNL || angle is aPL)) then power is pPS
if (distance is dNS) then power is pNS
if (distance is dPS) then power is pPS
if (distance is dZE && angle is aZE) then power is pZE
if ((distance is dZE || distance is dPS || distance is dNS) && angle is aNE) then power is pPS
if ((distance is dZE || distance is dPS || distance is dNS) && angle is aPO) then power is pNS
//
The following images show you how a Crane works with FuzzyLogic. Excerpt of the Crane Controller (FuzzyController.java)
Java:
/**
Copyright (C) 2000  Edward S. Sazonov (esazonov@usa.com)
Modifications 12/19/2003 by Nazario Irizarry (naz-irizarry@excite.com)

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@version 2000 Original, Edward S. Sazonov (esazonov@usa.com)
@version 12/19/2003 Modifications,  Nazario Irizarry (naz-irizarry@excite.com)
@version  5/21/2020 to SWING and to suit Joe's FuzzyLogic package Joe Nartca
*/
import java.awt.Color;
//
import fuzzylogic.FuzzyEngine;
//
public class FuzzyController extends Thread {
    // declare FuzzyEngine
    private FuzzyEngine engine;
    private volatile boolean running = true;
    private LoadSway loadsway;

    public FuzzyController(LoadSway loadsway) throws Exception {
        this.loadsway = loadsway;
        engine = new FuzzyEngine(loadsway, "LoadSway");
        start();
    }

    public void run() {
        try {
            int mode = loadsway.fuzzyMode.getSelectedIndex();
            engine.resetVariables( ); // reset FuzzyVariables
            while (running) {
                // execute the Script
                engine.execute(loadsway.fName);
                // defuzzy FuzzyVariabel back to JAVA
                loadsway.trolleyVelocity = engine.defuzzy("power", mode);
                //
                if (loadsway.pendulum.ropeLength < 80.0) loadsway.pendulum.ropeLength += 2.0;
                Thread.sleep(200); // sleep 200 msec.
            }
        } catch (Exception ex) {
            loadsway.fuzzyJButton.setForeground(Color.blue);
            ex.printStackTrace();
        }
    }

    public void abort() {
        running = false;
    }
}
The example LoadSway was developed originally 20 years ago by Edward S. Sazonov. And I have taken the GUI idea and the FL data and ported to SWING and to run on my OWN developed FuzzyLogic. LoadSway works as following:
  • Button "Fuzzy control" runs with FuzzyLogic
  • Button "Manual control" is under your control and you have to navigate the Magnetic Carrier with the keys North-South-West-East
  • Comboboxes allow you to determine the position of the package (ship, ground, random).
Download the loadsway.zip and play with it and to see how FuzzyLogic works. The package contains the sources (LoadSway.java, FuzzyController.java, Pendulum.java, loadsway.jar and fuzzylogic.jar). Include the fuzzylogic.jar into your CLASSPATH and run java -jar loadsway.jar and you could see the wonder of the FuzzyLogic world

loadwsay_1.png
loadwsay_2.png
loadwsay_3.png
loadwsay_4.png
loadwsay_5.png



APPENDIX
The original codes of Edward S. Sazonov and the FuzzyEngine.0-2-src.zip:
Java:
//Copyright (C) 2000  Edward S. Sazonov (esazonov@usa.com)
// Modifications 12/19/2003 by Nazario Irizarry (naz-irizarry@excite.com)

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

package org.sazonov.fuzzy.craneExample;
/**
* Implements the fuzzy controller.  Defines 3 linguistic variables.
* Angle and distance are input variables. Power is the output variable.
* Power is used to drive velocity in the example.
*
* @version 2000 Original, v0.1, Edward S. Sazonov (esazonov@usa.com)
* @version 12/19/2003 Modifications, v0.2,  Nazario Irizarry (naz-irizarry@excite.com)
*/

import java.awt.Color;

import org.sazonov.fuzzy.engine.RuleBlock;
import org.sazonov.fuzzy.engine.FuzzyState;
import org.sazonov.fuzzy.engine.LinguisticVariable;
import org.sazonov.fuzzy.engine.Factory;

class FuzzyController extends Thread {
    private LoadSwayPanel loadSwayPanel = null;
    private FuzzyState fuzzyState = null;
    private RuleBlock fuzzyRules;
    private LinguisticVariable angle = null;
    private LinguisticVariable power = null;
    private LinguisticVariable distance = null;
    private boolean running;

    public FuzzyController(LoadSwayPanel loadsway) {
        running = true;
        loadSwayPanel = loadsway;

        Factory factory = Factory.getFactory();

        fuzzyState = factory.makeFuzzyState();
        angle = factory.makeLinguisticVariable("angle");
        angle.add(factory.makeMemberFunction("negativeLarge", -4.0, -4.0, -0.314, -0.2616));
        angle.add(factory.makeMemberFunction("negativeSmall", -0.314, -0.2616, -0.0628, 0.0));
        angle.add(factory.makeMemberFunction("negative", -4.0, -4.0, -0.0628, 0.0));
        angle.add(factory.makeMemberFunction("zero", -0.0628, 0.0, 0.0, 0.0628));
        angle.add(factory.makeMemberFunction("positive", 0.0, 0.0628, 4.0, 4.0));
        angle.add(factory.makeMemberFunction("positiveSmall", 0.0, 0.0628, 0.2616, 0.314));
        angle.add(factory.makeMemberFunction("positiveLarge", 0.2616, 0.314, 4.0, 4.0));
        distance = factory.makeLinguisticVariable("distance");
        distance.add(factory.makeMemberFunction("positiveLarge", 75.0, 100.0, 400.0, 400.0));
        distance.add(factory.makeMemberFunction("positiveMedium", 35.0, 50.0, 75.0, 100.0));
        distance.add(factory.makeMemberFunction("positiveSmall", 0.0, 2.0, 35.0, 50.0));
        distance.add(factory.makeMemberFunction("zero", -2.0, 0.0, 0.0, 2.0));
        distance.add(factory.makeMemberFunction("negativeSmall", -50.0, -35.0, -2.0, 0.0));
        distance.add(factory.makeMemberFunction("negativeMedium", -100.0, -75.0, -50.0, -35.0));
        distance.add(factory.makeMemberFunction("negativeLarge", -400.0, -400.0, -100.0, -75.0));
        power = factory.makeLinguisticVariable("power");
        power.add(factory.makeMemberFunction("negativeLarge", -16.0, -15.0, -15.0, -14.0));
        power.add(factory.makeMemberFunction("negativeMedium", -6.0, -5.0, -5.0, -4.0));
        power.add(factory.makeMemberFunction("negativeSmall", -2.0, -1.0, -1.0, 0.0));
        power.add(factory.makeMemberFunction("zero", -1.0, 0.0, 0.0, 1.0));
        power.add(factory.makeMemberFunction("positiveSmall", 0.0, 1.0, 1.0, 2.0));
        power.add(factory.makeMemberFunction("positiveMedium", 4.0, 5.0, 5.0, 6.0));
        power.add(factory.makeMemberFunction("positiveLarge", 14.0, 15.0, 15.0, 16.0));

        fuzzyState.register(angle);
        fuzzyState.register(distance);
        fuzzyState.register(power);


        try {
            loadSwayPanel.getFuzzyControlButton().setForeground(Color.green);
            String ruleText = loadsway.getFuzzyRules().getText();
            fuzzyRules = fuzzyState.createRuleExecutionSet(new java.io.StringReader(ruleText));
        } catch (Exception exception) {
            loadSwayPanel.getFuzzyControlButton().setForeground(Color.red);
            handleException(exception);
        }
        start();
    }

    private void handleException(Throwable throwable) {
        System.out.println("--------- UNCAUGHT EXCEPTION in FuzzyController ---------");
        throwable.printStackTrace(System.out);
    }

    public void run() {
        while (running) {
            CraneState cranestate = loadSwayPanel.getState();
            fuzzyState.reset();
            angle.setInputValue(cranestate.currentTheta);
            distance.setInputValue(cranestate.distanceToTarget);
            try {
                fuzzyRules.executeRules();
            } catch (Exception exception) {
                loadSwayPanel.getFuzzyControlButton().setForeground(Color.red);
            }
            try {
                loadSwayPanel.setTrolleyVelocity(power.defuzzify());
            } catch (Exception exception) {
                System.out.println("Exception: " + exception.getMessage());
            }
            double d = loadSwayPanel.getPendulum().getRopeLength();
            if (d < 80.0)
                loadSwayPanel.getPendulum().setRopeLength(d + 2.0);

//            loadSwayPanel.getImageCanvas().repaint();
            try {
                Thread.sleep(200L);
            } catch (InterruptedException interruptedexception) {
                /* empty */
            }
        }
    }

    void abort() {
        running = false;
    }
}
 

Attachments

Sửa lần cuối:

Joe

Thành viên VIP
21/1/13
2,969
1,311
113
(cont.)
The FuzzyLogic Programming Language set (script)
PHP:
          FuzzyLogic Keywords, Operatots, Syntax and Operations

All keywords (e.g. if, is, then, while, etc. ) must be in LOWER case

FuzzyVariables (FV) and FuzzyData (FD) MUST be registered BEFORE Fuzzy-
Expressions (FE) or FuzzyScript (FS) can be executed. Like any Programming
Language variable and datanames must be unique. FD must be declared BEFORE
FV.

The keyword 'this' refers to JavaObject which is the Container of FuzzyEngine
(i.e. where FE is instantiated). Registered and Unregistered can be referred by
FuzzyEngine. If Unregistered JavaObject is referred, all the Object's
contents (i.e. objects, primitives) are put in their initial states (or values)
and they could be null or 0. Calculable value is ALWAYS double (or Double as
Java Object). Returned value of a referenced method must be ALWAYS a double.

Registered JavaObjects must be instantiated, before they are registered.
Otherwise Exception will arise when they are referred.

Reference to JavaVariables (or fields): JavaObjectName:JavaVariableName
                                    or: this:JavaVariableName

Reference to JavaMethods: JavaObjectName.JavaMethodName(Parm1, ...)
                      or: this.JavaMethodName(Parm1, ...)

When a script is successfully executed a "FuzzyByteCodes" file with the suffix
".fbc"  will be created in the same directory of the script. And whenever the
script is re-invoked the .fbc file is used for the execution.
NOTE: if the script is modified the existed fbc file MUST BE DELETED so that
      the modification can be executed.
--------------------------------------------------------------------------------
Register and Shorthand Register are mutual EXCLUSIVE !

------------------Register FuzzyData and FuzzyVariable--------------------------
[FDname:left, top, right]
[FDname:left, ltop, rtop, right]
{FVname:FDname, FDname, ..., FDname}

-------------------------Shorthand Register-------------------------------------
<!fvName[fdName(left, top, right),...,fdName(left, ltop, rtop, right)]!>

---------------------------Java Primitives--------------------------------------
double varName              // 0.0
string varName              // null string
double varName = 13.6       // init to 13.6
string java = "java"        // init with "java"
double d = this.getDouble() // init d with the returned from method getDouble()

--------------------------Buil-in Functions-------------------------------------
clear FV                    // clear all FV-FuzzyData of FV
reset FV                    // FV and all its FDs
compute a = b+c             // simple math.operations with NON-FuzzyVariable
compute a = b-c            // only with JAVA Primitives: int, long, double.
compute a = b*c             // NO byte, char, short, float, Array
compute a = b/c             // NO embedded such as (a+b)*(c/d)
compute s = "Hi there"
concate s += "this here"
concate a += b              // a and be can be any other primitive

--------------------------Operations--------------------------------------------
FV = val                    // FV sample = val
FV + val                    // + FV sample with val
FV - val                    // - FV sample from val
FV * val                    // * FV sample by val
FV / val                    // / FV sample by val

---------------Operation with JavaVariable--------------------------------------
FV = MyApp:temp             // set FV sample to JavaVariable temp of JavaClass MyApp
MyApp:temp = val            // set JavaVariable to val 
MyApp:temp + val            // add JavaVariable with val
MyApp:temp - val            // sub JavaVariable from val 
MyApp:temp * val            // mul JavaVariable by val 
MyApp:temp / val            // div JavaVariable by val

-----------------------Operators and Syntax-------------------------------------
//                             double-slash starts a comment and ends at end of the Line
[..] {..} <!..!>            // FuzzyData/FuzzyVariable declarators
+ - * / = : .               // Math operation, Java:Field, Java.method
&& ||                       // same and, or
> == < >= <=                // in conjuction with while/endwhile and case/endcase only

--------------------------Statements--------------------------------------------
if FV is FD then FVr is FDr     // assign valuated result to FDr of FVr
if (FV is FD) then FVr is FDr

if FV1 is FD1 or FV2 is FD2 then FV3 is FD3
if FV1 is FD1 || FV2 is FD2 then FV3 is FD3

if FV1 is FD1 and FV2 is FD2 then FV3 is FD3
if FV1 is FD1 && FV2 is FD2 then FV3 is FD3

if (FV1 is FD1) or (FV2 is FD2) then FV3 is FD3
if (FV1 is FD1 or FV2 is FD_2) and FV3 is FD3 then FV4 is FD4
if ((FV1 is FD1 or FV2 is FD_2) and FV3 is FD3) then FV4 is FD4

--------------------------Statements--------------------------------------------
if FV some FD ...             // fuzzySample**2 of FD
if FV very FD ...             // SQRT(fuzzySample) of FD
if FV not  FD ...             // (1-fuzzySample) of FD

if ... then FVr some FDr      // assign result**2 to FDr of FVr
if ... then FVr very FDr      // assign SQRT(result) to FDr of FVr
if ... then FVr not  FDr      // assign 1-result to FDr of FVr

--------------------------Statements--------------------------------------------
                              // a condition value can be a return of a method
while *                       // endless while like in java: while (true)
  ...
endwhile
while temp < 19 || temp > 20  // similar to JAVA loop while { ... }
  ....
endwhile

while temp < 19 or temp > 20  // same with && and other comparators ==, >=, <=
  ....
endwhile

case temp > 19 && temp < 20
  ....
endcase

case temp > 19 and temp < 20 // similar to JAVA if (...) { ... }
  ....
endcase

---------------------------Keywords---------------------------------------------
while                       // Conditional Loop like while (...) { ... }
endwhile                    // must close the while Loop
case                        // Conditional block like if (...) { ... }
endcase                     // must close the case block
break                       // break while / case
exit                        // exit FuzzyScript back to JAVA
this                        // refer to the JavaApp that run this FuzzyEngine
reset                      
clear                      
some                        // is the POWER of 2 of a FuzzySample
very                        // is the SQRT of a FuzzySample
not                         // is the inverse of a FuzzySample (or: 1-FuzzySample)
and
or
if
then
is
-------------------------------OnPlanning------------------------------
print
read

-----------------------------------------------------------------------
 
Sửa lần cuối:

Joe

Thành viên VIP
21/1/13
2,969
1,311
113
(cont.)

I hope that you have watched the Youtube and know why FuzzyLogic is useful and is always with our daily life when we make decisions. However, the videos are quite theoretical, too abstract. Almost as vague as Fuzzy itself. Let's start to make FL "accessible" by computer. FuzzyLogic Programming set (script) is the start and it lets you be aware that a FL script looks like an interpretive language such as JavaScript or PYTHON. First of all: let define a FuzzyData (FD). A POJO of java if you so will.

FuzzyData.png

A FuzzyVariable (FV), as mentioned previously, composes none or a set of FuzzyData (FD). For example, the "rating degree" of "distance" of the LoadSway (see example)

distance.gif

Now you can see that FV distance composes of 7 FDs (from dNL or NegativeLarge to dPL or PositiveLarge) which are either Trapezoid or Pyramid. When a "sample" is made this sample could be within one of the FD realm or fully outside of all. The inside is called a FuzzySample and has a value between 0, +1.0 (double in Java). All outsides have the -1.0 value (minus one).

FuzzySample.png

Assume that 3 samples were taken on FD dNL (DistanceNegativeLarge) then evaluation is:
Java:
if (distance is dNL) then power is pNL // pNL stands for PowerNegativeLarge
and the result is available (because all samples are NOT -1.0). The defuzzification of FV power gives a double between 0.3 and 1.0 (plus one). An "available" means HERE: the evaluation of FV distance produces a positive value (non -1.0). A "crisp" Prgroamming Language calls it as "true" :))
 
Sửa lần cuối:

Joe

Thành viên VIP
21/1/13
2,969
1,311
113
(cont.)

With the "available" from the IF-left side then an "availability" can be "added" to the IF-right side as a result. The difference between CRISP and FUZZY evaluation is the precision. If the comparison is exact (equal, less, bigger, etc.) then the result is true, otherwise it is false. The fuzzy comparison achieves a result if the compared value is in the realm of defined data (pyramid or trapezoid) and NO alternative is envisaged.

FuzzyValue.png

If a FuzzyValue is "defuzzified" it could be a value of either the left side or the right side (cutting point on the left and right diagonal line) and that is ambiguous. To achieve the most proximal value the defuzzification process is similar to the Finite Element Analysis which is very familiar in the Civil Engineering. The defuzzification is the computing of the area (surface) of the samples on the FuzzyData (more about Defuzzification: click HERE).

As said, the Finite Element Analysis depends on the number of elements (samples). The more samples you have the more precise the result will be. There are two ways to compute the Defuzzification process:
  1. Area calculation
  2. Barycenter calculation (or Centroid)

(Source: Wikipedia)

or


(Source:i.stack.imgur.com)
 

Joe

Thành viên VIP
21/1/13
2,969
1,311
113
(cont.)

We have now the basics of FuzzyLogic: FuzzyData (FD), FuzzyVariable (FV) and FuzzyExpression (FE)
Java:
if FV is FDa then FV is FDb
With the example Distance and suppose that the crane magnet head is at the distance -45 to the goal the FE could be as following:
Java:
if Distance is NegativeMedium or Distance is NegativeSmall then Power is NegativeSmall
distance.gif

power.gif

The evaluation of Distance -45 must be firstly fuzzified. Both NegativeMedium (NM) and NegativeSmall (NS) have the Trapezoid realm. Meaning:
  • -45 is on the right side of the MN AND on the left side of MS. The Fuzzification will be​
FuzzyEvaluation.png

The Set Theory can be applied, for example:
Java:
if FV is FDa then FV not FDb
With the operation not, some and very we can define the rate of the "availability" which is a Fuzzy Value and is between 0 and 1.0 (double).
  • not: 1 - availability
  • some: availability * availability. The result is smaller than availability.
  • very: SQRT(availability). The result is larger than availability.
In our example the result for Power
Java:
if Distance is NegativeMedium or Distance is NegativeSmall then Power some NegativeSmall
yields 0.4 * 0.4 = 0.16, the fuzzified value for Power is 0.16

With the knowledge I have showed you how FL works it is an easy task to implement a FuzzyEngine which can be developed with the minimal FL requirements (see the work of Edward S. Sazonov). I have worked in a different way. Instead of different FL objects and Stack-Technique (see FuzzyRule.java) I work with the Interpretative Technique which is more flexible and simpler if new rules or new options are needed.
 
Sửa lần cuối:

Joe

Thành viên VIP
21/1/13
2,969
1,311
113
(cont.)

The problems of working with FuzzyLogic are manifold. The first reason is that some people think FL is UNSCIENTIFIC even they apply FL daily in their decision making. The second problem is that FL is not an official field that is systematically taught in the school or university. Set Theory (ST) and FL are known for decades but there is NO COMMON possibility to work with ST or FL.

But I believe that the main reason is the lack of a workable ST-FL Programming Language . Without a Programming Language developers are left alone with their ST-FL initiative. NO company, NOR Government support ST-FL Programming Language stays in the backyard as a private property where only a few of people appreciates it. The next obstacle is the lack of integration into the mainstream computing environment. PYTHON or JAVA, for example, is an interpretative OOPL and both are capable to coop with other (OO)PL. Most of the FL packages (incl. Sazonov FL package and mine) are the APIs of a certain OOPL (here:JAVA). In my FL package I have attempted to create a FL language with its own language elements beside the if-then (while-endwhile, case-endcase, compute, concate(nate) and all elementary arithmetic operations) and some accesses to the bearing JAVA platform (method invocation and parameters transferring between FL and JAVA). Example: the Airconditioning of a house.
Java:
// Temperature states
[cold: -20d, -5d, 5d]
[cool: 2d, 10d, 20d]
[fair: 19d, 20d, 22d]
[warm: 21d, 23d, 25d]
[hot:  24d, 30d, 50d]
// AirCon regulator states
[min: -10d, -6d, -3d]
[low: -4d, -2d, 0]
[OFF: -0.5d, 0, 0.5d]
[high: 0d, 2d, 4d]
[max:  3d, 6d, 10d]
// FuzzyVariables
{AirCon: min, low, OFF, high, max }
{room: cold, cool, fair, warm, hot }
{temp: cold, cool, fair, warm, hot }
// declare FuzzyPrimitives
double fTemp = this:temp
double fStep = this:step
string str = "Hello world"
double x = 0
this.print("RoomTemp:", fTemp)
// concate String String
concate str += " Fuzzy is Here"
this.print(str)
//
clear AirCon
// loop until found...
while fTemp < 20 || fTemp > 21
  room = fTemp
  if room is cold then AirCon is max
  if room is cool then AirCon is high
  if room is fair then AirCon is OFF
  if room is warm then AirCon is low
  if room is hot  then AirCon is min
  // simulate the method adjust
  // double x = temp < 5d? 1d:temp < 20d?0.5d:temp < 25d? -0.5:-1d;
  // step = d + x;
  x = -1
  case fTemp < 25
    x = -0.5
    this.print("Less than 25 RoomTemp:", fTemp)
  endcase
  case fTemp < 20
    x = 0.5
    this.print("Less than 20 RoomTemp:", fTemp)
  endcase
  case fTemp < 5
    x = 1
    this.print("Less than 5 RoomTemp:", fTemp)
  endcase
  this.print("Before compute fStep:", fStep)
  // compute FV + FuzzyPrimitive double
  compute fStep = AirCon + x
  this.print("After compute fStep:", fStep)
  // set AirCon with defuzzied FV
  AirCon = fStep
  this:step = fStep
  this.print("RoomTemp:", room)
  // FuzzyExpressions
  if room is cold and AirCon is min then temp is cold
  if room is cool and AirCon is min then temp is cold
  if room is fair and AirCon is min then temp is cold
  if room is warm and AirCon is min then temp is cool
  if room is hot  and AirCon is min then temp is fair
 
  if room is cold and AirCon is low then temp is cold
  if room is cool and AirCon is low then temp is cold
  if room is fair and AirCon is low then temp is cool
  if room is warm and AirCon is low then temp is fair
  if room is hot  and AirCon is low then temp is warm
 
  if room is cold and AirCon is OFF then temp is cold
  if room is cool and AirCon is OFF then temp is cool
  if room is fair and AirCon is OFF then temp is fair
  if room is warm and AirCon is OFF then temp is warm
  if room is hot  and AirCon is OFF then temp is hot
 
  if room is cold and AirCon is high then temp is cool
  if room is cool and AirCon is high then temp is fair
  if room is fair and AirCon is high then temp is warm
  if room is warm and AirCon is high then temp is hot
  if room is hot  and AirCon is high then temp is hot
 
  if room is cold and AirCon is max then temp is fair
  if room is cool and AirCon is max then temp is warm
  if room is fair and AirCon is max then temp is hot
  if room is warm and AirCon is max then temp is hot
  if room is hot  and AirCon is max then temp is hot
  // end of FuzzyExpression
  this:temp = temp
  fTemp = temp
  this.print("fTemp:", fTemp)
endwhile
this.achieve(fStep, fTemp)
And the "bearing" JAVA app
Java:
import fuzzylogic.FuzzyEngine;
// Joe Nartca (C)
public class AirConditioning {
  public AirConditioning( ) { }
  private void go(String... args) throws Exception {
    String script = "script/airconditioning.txt";
    outside = -10d;
    step = 0d;
    if (args.length > 0) {
      try {
        outside = Double.parseDouble(args[0]);
        if (args.length > 1) script = args[1];
      } catch (Exception ex) {
        script = args[0];
        outside = -10d;
      }
    } else {
      java.util.Random ran = new java.util.Random();
      step = (double)ran.nextInt(10);
      outside = (double)ran.nextInt(40);
      if (ran.nextInt(2) > 0) outside = -outside;
      if (ran.nextInt(2) > 0) step = -step;
    }
    // preset Room Temperature between -10 to 35 Celsius
    temp = outside < -10d? -10d:(outside > 32)? 32:outside;
    // FuzzyLogic..............................
    FuzzyEngine eng = new FuzzyEngine(this, "AirConditioning");
    // the values between 20d and 22d are the so-called LEARNED values
    long t = System.nanoTime();
    eng.execute(script);
    System.out.printf("Processing time:%05.3f milliSec.\n", ((double)(System.nanoTime()-t))/1000000);
  }
  private void print( ) {
    System.out.printf("Invoke by FuzzyScript: Outside %2.2f Celsius, Room %2.2f Celsius, AirCon %2.2f\n",
                      outside, temp, step);
  }
  private void print(String msg) {
    System.out.println("Invoke by FuzzyScript: "+msg);
  }
  private void print(String msg, double d) {
    temp = d; // set the new temperature
    System.out.println("Invoke by FuzzyScript: "+msg+d);
  }
  private double achieve(double fs, double fr) {
    System.out.printf("Invoke by FuzzyScript: Outside:%2.2f, AirCon:%2.2f ("+
                      (fs > 0?"warming":"cooling")+"), RoomTemp:%2.2f\n", outside,fs, fr);
    return step;
  }
  public static void main(String... args) throws Exception {
    AirConditioning air = new AirConditioning();
    air.go(args);
  }
  private double temp, step, outside;
  //
}
The bearing Java app provides the "FL app" the fundamental IO methods (print, etc.). In the near future I will implement the elementary FL-IOs (read/write/print). Let's scrutinize the "FuzzyLogic app" AirConditioning.
  • the first part starting with [cold: ...] and ending with {temp: ....} is the data and variables declaration. [...] is the FuzzyData declaration and {...} is the FuzzyVariable declaration.
  • the next part where "ftemp = this:temp", etc. is the inter-working between Fuzzy values (or samples) with the JAVA primitive (here: temp). The reserved word "this" refers to the bearing JAVA app (here: AirConditioning) as an Object. "concate" and "compute" are the two built-in FL methods.
  • the invocation "this.print(str)" invokes the implemented print(String str) of the bearing JAVA app. FL interpreter can distinguishes different methods of the bearing JAVA app even with the same name (e.g. see the print method of AirConditioning).
  • the FL language elements "while....endwhile" and "case...endcase" work similarly to the Java while(...) {...} and if (...) { ...}. However without the "else".
And here is the Interplay between FL and JAVA

FL_App.png

If the loop is done outside FL it has to be done with Java-style. Example:
Java:
    while (temp < 20d || temp > 21d) {
      eng.execute("script/air_house.txt");
    }
and the script "air_house.txt" could be
Java:
// set Samples to Java Global Variables
room = OldHouse:temp
AirCon = OldHouse.nextStep(fvT)
OldHouse.print(fvA) // fvA is ClassName in OldHouse
// FuzzyExpressions
if room is cold and AirCon is min then temp is cold
if room is cool and AirCon is min then temp is cold
....

if room is warm and AirCon is max then temp is hot
if room is hot  and AirCon is max then temp is hot
// end of FuzzyExpression
this.print(fvT, fvA)
To quicken the execution of a FL app I have implemented the FuzzyByteCodes which are automatically generated during the interpretative phase and saved under the same script name with the suffix ".fbc"

FL_App_1.png

FL_App_2.png
 
Sửa lần cuối:

Joe

Thành viên VIP
21/1/13
2,969
1,311
113
(cont.)

With the interleaving with JAVA methods FuzzyEngine could run on JVM and accesses JAVA implemented methods. Or in other words: FuzzyEngine uses JVM and JAVA codes as an integral part (similar to Kotlin whereas Kotlin is an OOPL that runs on JVM).

Back to the Set Theory and FuzzyLogic. The principal Fuzzy Statement is the
Java:
if FV1 is FD1 then FV2 is FD2
As I have previously explained such a conditional statement just gives ONE result which exists in a defined realm of data. There is NO alternative (as an 'else'). The SET Theory comes into play with the conjunction of conditional queries. AND (&&) and OR (||) are the 'joints'. Both writing ways (AND or &&, OR or ||) are valid within FuzzyEngine.
Java:
if FV1 is FD1 && FV2 is FD2 then FV3 is FD3
if (FV1 is FD1 && FV2 is FD2) || FV3 is FD3 || FV4 is FD4 then FV5 is FD5
The usage of brackets '(' and ')' is only obligatory when AND and OR are mixed in a conditional FuzzyExpression (see the 2nd FuzzyExpression). But it is also useful for the clarity. However, if brackets are used they must be in pair, otherwise Exception will be thrown. The other SET rules "NOT", "SOME" and "VERY" are implementations of the Implement, the Exclusive and the Inclusive.

The Calculation of the result is either Bisection (surface) or Centroid (barycenter). The more a section is divided into little surfaces the preciser the section or the centroid will be. It's kinda "Finite Elements Analysis". A very complex calculation procedure.

FuzzyData as you see in the lecture of Prof. S Chakraverty is an area, a continuous realm. The realm is limited by a boundary which is expressed by 3 or 4 floating values (here: double in JAVA) and represented in a X-Y coordinate: as a pyramid is limited by 3 'double' values, or a Trapezoid by 4 'doubles'. Values that lie within the realm have a coordinate: on the X-axis is the "human-understandable" value and on the Y-axis is the "fuzzified" value which is between 0 and 1.0. The reason why floating value is used is the sheer-unlimited continuous stretching. Example: between 0 and 1.0 we can have 0.1 or 0.01 or 0.001, etc. It's the precision via the number of "finite elements".

And FuzzyData represents the vagueness, the fuzziness of a state. Vagueness is usually expressed in Probability. Example: 1% of this or that could be good. The 1% or 0.01 is the PROBABILITY of the "goodness" in this case. Hence: 0.1 or 0.01 or 0.001, etc. the scaling is UNLIMITED and can be only represented by a 'float' or a 'double' in a high-level programming language.

FuzzyVariable is a subject, an article that represents an object. A table (visible) or an illness (abstract) can be represented by a FuzzyVariable whose state composes of some FuzzaData realms. A FuzzyVariable is only reliable if its FuzzyData represent the practice-oriented data. And that is also the main problem of FuzzyLogic to define reliable FuzzyVariables with practice-oriented FuzzyData.
 
Sửa lần cuối:

Joe

Thành viên VIP
21/1/13
2,969
1,311
113
(cont.)

The FuzzyData is "Practice-oriented" when its data cover a certain area which is either computable or experienceable. For example:
  • computable: Data area for a "slow-speed" is between 10 - 50 kmh
  • experienceable: Data area for a "little-tired" is an individual experience which is NOT computable nor measureable.
In reality we human usually make decisions that based either on guessing (experienceable) or on knowing (computable or measureable). But sometime we made a wrong decision because we have failed to lay out some practice-oriented (fuzzy) data. LOVE is for example a very fuzzy decision. And the result could end up in a tragedy for him/herself (e.g. divorce) and for the innocents (e.g. children). Exactly like that, FuzzyLogic with "weak" FuzzyData could lead to the nonsense or the very wrong result.

As long as we privately fuzzify around it could be fun (for everyone.) But in our world today we have to deal with myriad events and information that require to be processed almost immediately or to make a decision that bases one some of the events and information. In such a situation FuzzyLogic could be a great assistant. Marketing blitz for a product launching, for self-driving car (autonomous vehicle) or for a flying drone. As you could learn from the Video for beginner about the Brake-and-Drive of a car, it could be for a self-driving car a real challenge. And such a challenge can be solved satisfactorily by FuzzyLogic. An ad-hoc brake-and-drive with CRISP logic true-false could make the car jerking and that is certainly unacceptable for everyone -driver and passengers as well.

The LoadSway app designed by Sazonov is so excellent that I use all the data and the algorithm that runs the Crane grabber. The only thing I have done is to modernize the GUI (from AWT to SWING), to optimize the codes and to run with my own FL engine (you can download the loadsway.zip and Sazonov's original FL package for your studying). And hereunder some explanations of the LoadSway controlling process of an autonomous Crane.
  • Pendulum: the angle calculation between the (FuzzyVariable) Distance and the rope length. The result is the very alive "swinging" crane grabber (like the pendulum of a wall clock).
  • FuzzyController: the bearing thread in JAVA that runs the FuzzyEngine after every 150 mSec.
  • LoadSway: the app with the "Trolley" thread that move forwards and backwards the crane grabber. A restart after every 100 mSec. (waiting for the Canvas repaint).
It depends on the distance to the destination (goal) that the Trolley is slown-downed or accelerated (see Trolley Thread). The positioning algorithm is made in this thread. The Trolley velocity (or speed) is computed by FuzzyEngine which relies on 2 FuzzyVariables: Distance and Angle. The defuzzified output is FuzzyVariable Power.The LoadSway is just an example that an autonomous crane grabber can be driven by FuzzyLogic. The "manual" option (see Button "Manual control") gives you an opportunity to navigate manually the trolley and the grabber. And you could see how "difficult" it could be to do that manually.

Another example: You want to launch a Marketing blitz for a new product -says: a new design of Trousers. All you have are a survey about the customer consuming behavior, their color penchant and the visiting frequency of your website. And you want to put the new design on your website...but what colors for the Trousers and when ? You have 4 FuzzyVariables: ClientBehavior, TrousersColor and VisitingFrequency with experienceable FuzzyData and the output is the defuzzification of ProductLaunch. Experienceable is here because ClientBehavior and Taste (TrousersColor) are usually erratic or irrational and depends fully on the number of surveyees and (personal) experiences. In a little village with 100 persons a number of 50 surveyees is already "great", but even in small town of 1000 denizens the number 50 surveyees is quite insuffucient and unreliable. Then the VisitingFrequency is also incalculable. Who visits the website? Men, boys, girls, old people or teenagers? Also: the VisitingFrequency FuzzyVariable must be drawn from statistics and statistics is the probability which is "computable". So, we have two experienceable and one computable FuzzyVariable.

Marketing_1.png

The FUzzyExpression could be as following:
Java:
if ClientBehavior is SomeInterest and VisitingFrequency is rare then ProductLaunch is TooEarly
if ClientBehavior is SomeInterest and VisitingFrequency is OftenWithInterest then ProductLaunch is OK
Suppose that you have to make a choice of TrousersColor together with the ProductLaunch, and you have only yellow trousers in stock. The FuzzyExpression could be as following:
Java:
if ClientBehavior is SomeInterest and (VisitingFrequency is rare or TrousersColor is Yellow) then ProductLaunch is TooEarly
if ClientBehavior is SomeInterest and (VisitingFrequency is rare or TrousersColor is Yellow) then ProductLaunch is TooEarly
if VisitingFrequency is OftenWithInterest or TrousersColor is red or TrousersColor is blue then ProductLaunch is OK
NOTE: the FL Sources are available for every CongdongJava Member. If any CongdongJava member has interest on the FL-Sources he or she just needs to inbox me.

Have fun with FuzzyLogic
Joe
 
Sửa lần cuối: