65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 模糊逻辑 API

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.73/5 (27投票s)

2020年8月5日

MIT

3分钟阅读

viewsIcon

59384

downloadIcon

340

如何在纯 CLR 对象上通过模糊逻辑概念执行推理

此 API 利用 C# POCO(Plain Old CLR Object)对象,并结合 .NET Framework 中定义的 Expression 对象来执行模糊逻辑概念的推理。

1) 开始之前:抽象

如果您想深入研究模糊逻辑理论(如数学定理、公理和德摩根定律),强烈建议您查阅其他参考资料以满足您的好奇心和/或研究需求。通过这篇博客文章,您将只能获得一个在实际应用中执行模糊逻辑的实用示例;因此,本文的重点不是进行只有实际目的的哲学性对话。此 API 的新版本更新使用了与并行Yield的交互,以提高性能;另一个改进是修复了错误,例如:XML 输出中缺少属性、推理输出为小数(遵循最普遍的逻辑理论),以及校准输出值以提高准确性。重要提示:所有构造函数保持不变,对任何开发者的项目都没有影响。

2) 模糊逻辑概念

这张来自 tutorialspoint 网站的图表总结了模糊逻辑的真正概念:在模糊逻辑中,没有什么是绝对真或绝对假;在 0 和 1 之间,存在一个超出布尔逻辑极限的区间。

From: https://tutorialspoint.org.cn/fuzzy_logic/fuzzy_logic_introduction.htm

3) 使用 API

3.1) 核心流程

核心概念的第一个要求是:去模糊化。换句话说,通过在模糊逻辑引擎中构建的精确输入表达式来生成模糊逻辑结果(请参阅下图,来自维基百科的参考)。

From: https://es.wikipedia.org/wiki/Defuzzificaci%C3%B3n

模糊逻辑引擎的规则是:将任何复杂的布尔表达式(精确输入)分解成较小的布尔部分规则,以解决逻辑布尔问题(关于此复杂布尔表达式使用的理论,请参阅如多值逻辑或/经典逻辑等文章)。

基于上述说明性示例,让我们创建一个 `Model` 类来表示诚实的人物,如正直、真理和正义感百分比评估,以及一个识别诚实度配置文件的布尔表达式对象,考虑到成为诚实的人的最低百分比。

[Serializable, XmlRoot]
public class HonestAssesment
{
    [XmlElement]
    public double Integrity { get; set; }

    [XmlElement]
    public double Truth { get; set; }

    [XmlElement]
    public double JusticeSense { get; set; }

    [XmlElement]
    public double MistakesAVG
    {
        get
        {
            return (Integrity + Truth - JusticeSense) / 3;
        }
    }
}

//Crisp Logic expression that represents Honesty Profiles:
static Expression<Func<HonestAssesment, bool>> _honestyProfile = (h) =>
(h.IntegrityPercentage > 75 && h.JusticeSensePercentage > 75 && 
                               h.TruthPercentage > 75) || //First group
(h.IntegrityPercentage > 90 && h.JusticeSensePercentage > 60 && 
                               h.TruthPercentage > 50) || //Second group
(h.IntegrityPercentage > 70 && h.JusticeSensePercentage > 90 && 
                               h.TruthPercentage > 80) || //Third group
(h.IntegrityPercentage > 65 && h.JusticeSensePercentage == 100 && 
                               h.TruthPercentage > 95); //Last group

分解的布尔表达式是 System.Linq.Expressions.Expression 类派生的一种能力,它将任何代码块转换为表示性字符串;辅助此工作的派生类是 BinaryExpression:布尔表达式将被切成较小的布尔表达式的二叉树,其规则将优先考虑包含“OR”的条件表达式的切片,然后按“AND”条件表达式切片。

//First group of assessment:
h.IntegrityPercentage > 75;
h.JusticeSensePercentage > 75;
h.TruthPercentage > 75;

//Second group of assessment:
h.IntegrityPercentage > 90;
h.JusticeSensePercentage > 60;
h.TruthPercentage > 50;

//Third group of assessment:
h.IntegrityPercentage > 70;
h.JusticeSensePercentage > 90;
h.TruthPercentage > 80;

//Last group of assessment:
h.IntegrityPercentage > 65;
h.JusticeSensePercentage == 100;
h.TruthPercentage > 95;

此 .NET Framework 中的功能是弥补评估值(评估配置文件所获得的或接近达到任何四个定义估值组的值)的关键,例如:

HonestAssesment profile1 = new HonestAssesment()
{
    IntegrityPercentage = 90,
    JusticeSensePercentage = 80,
    TruthPercentage = 70
};
string inference_p1 = FuzzyLogic<HonestAssesment>.GetInference
                      (_honestyProfile, ResponseType.Json, profile1);

查看 `HitsPercentage` 和 `InferenceResult` 属性。对配置文件 1 的推理,诚实度为 0.67(1 表示极其诚实)。- `inference_p1` `string` 变量(JSON)的结果。

{
    "ID":"72da723b-b879-474c-b2cc-6a11c5965b25",
    "InferenceResult":"0.67",
    "Data":
        {
            "IntegrityPercentage":90,
            "TruthPercentage":70,
            "JusticeSensePercentage":80,
            "MistakesPercentage":20
        },
    "PropertiesNeedToChange":["IntegrityPercentage"],
    "ErrorsQuantity":1
}
HonestAssesment profile2 = new HonestAssesment()
{
    IntegrityPercentage = 50,
    JusticeSensePercentage = 63,
    TruthPercentage = 30
};
string inference_p2 = FuzzyLogic<HonestAssesment>.GetInference
                      (_honestyProfile, ResponseType.Xml, profile2);

对配置文件 2 的推理,诚实度为 33%,即“有时诚实”,如 tutorialspoint 图所示。-- `inference_p2` `string` 变量(XML)的结果。

<?xml version="1.0" encoding="utf-8"?>
<InferenceOfHonestAssesment>
  <PropertiesNeedToChange>IntegrityPercentage</PropertiesNeedToChange>
  <PropertiesNeedToChange>TruthPercentage</PropertiesNeedToChange>
  <ErrorsQuantity>2</ErrorsQuantity>
  <ID>efb7249e-568f-44d4-a8b3-ce728a243273</ID>
  <InferenceResult>0.33</InferenceResult>
  <Data>
    <IntegrityPercentage>50</IntegrityPercentage>
    <TruthPercentage>30</TruthPercentage>
    <JusticeSensePercentage>63</JusticeSensePercentage>
  </Data>
</InferenceOfHonestAssesment>
HonestAssesment profile3 = new HonestAssesment()
{
    IntegrityPercentage = 46,
    JusticeSensePercentage = 48,
    TruthPercentage = 30
};
var inference_p3 = FuzzyLogic<HonestAssesment>.GetInference(_honestyProfile, profile3);

对配置文件 3 的推理,诚实度为 0%,即“极其不诚实”,如上图所示。-- `inference_p3` API Model 变量(如图像下方的 `Inference

From: https://github.com/antonio-leonardo/FuzzyLogicApi

HonestAssesment profile4 = new HonestAssesment()
{
    IntegrityPercentage = 91,
    JusticeSensePercentage = 83,
    TruthPercentage = 81
};
List<HonestAssesment> allProfiles = new List<HonestAssesment>();
allProfiles.Add(profile1);
allProfiles.Add(profile2);
allProfiles.Add(profile3);
allProfiles.Add(profile4);
string inferenceAllProfiles = FuzzyLogic<HonestAssesment>.GetInference
                              (_honestyProfile, ResponseType.Xml, allProfiles);

所有配置文件的推理,以 XML 格式。

<?xml version="1.0" encoding="utf-8"?>
<InferenceResultOfHonestAssesment>
  <Inferences>
    <PropertiesNeedToChange>IntegrityPercentage</PropertiesNeedToChange>
    <ErrorsQuantity>1</ErrorsQuantity>
    <ID>8d79084c-9402-4683-833d-437cad86ef4a</ID>
    <InferenceResult>0.67</InferenceResult>
    <Data>
      <IntegrityPercentage>90</IntegrityPercentage>
      <TruthPercentage>70</TruthPercentage>
      <JusticeSensePercentage>80</JusticeSensePercentage>
    </Data>
  </Inferences>
  <Inferences>
    <PropertiesNeedToChange>IntegrityPercentage</PropertiesNeedToChange>
    <PropertiesNeedToChange>TruthPercentage</PropertiesNeedToChange>
    <ErrorsQuantity>2</ErrorsQuantity>
    <ID>979d4ebe-6210-46f4-a492-00df88591d17</ID>
    <InferenceResult>0.33</InferenceResult>
    <Data>
      <IntegrityPercentage>50</IntegrityPercentage>
      <TruthPercentage>30</TruthPercentage>
      <JusticeSensePercentage>63</JusticeSensePercentage>
    </Data>
  </Inferences>
  <Inferences>
    <PropertiesNeedToChange>IntegrityPercentage</PropertiesNeedToChange>
    <PropertiesNeedToChange>JusticeSensePercentage</PropertiesNeedToChange>
    <PropertiesNeedToChange>TruthPercentage</PropertiesNeedToChange>
    <ErrorsQuantity>3</ErrorsQuantity>
    <ID>9004cb7a-b75d-4452-9d9a-c8836a5531eb</ID>
    <InferenceResult>0</InferenceResult>
    <Data>
      <IntegrityPercentage>46</IntegrityPercentage>
      <TruthPercentage>30</TruthPercentage>
      <JusticeSensePercentage>48</JusticeSensePercentage>
    </Data>
  </Inferences>
  <Inferences>
    <ErrorsQuantity>0</ErrorsQuantity>
    <ID>36545dae-1dde-4bfd-a528-ae42a7a0748f</ID>
    <InferenceResult>1.00</InferenceResult>
    <Data>
      <IntegrityPercentage>91</IntegrityPercentage>
      <TruthPercentage>81</TruthPercentage>
      <JusticeSensePercentage>83</JusticeSensePercentage>
    </Data>
  </Inferences>
</InferenceResultOfHonestAssesment>

3.2) 设计模式

“模糊逻辑 API”采用单例设计模式开发,结构为一个私有构造函数,它有两个参数:一个 Expression 对象和一个 POCO 对象(在泛型参数中定义);但开发者只需一行代码即可获得推理结果。

//Like an inference object...
Inference<ModelToInfere> inferObj = FuzzyLogic<ModelToInfere>.GetInference
                                    (_honestyProfileArg, modelObj);

//... get as xml string...
string inferXml = FuzzyLogic<ModelToInfere>.GetInference
                  (_honestyProfileArg, ResponseType.Xml, modelObj);

//...or json string.
string inferJson = FuzzyLogic<ModelToInfere>.GetInference
                   (_honestyProfileArg, ResponseType.Json, modelObj);

3.3) 依赖项

要将模糊逻辑 API 作为程序集或内部类添加到您的 Visual Studio 项目中,您需要安装 System.Linq.Dynamic DLL,可以通过 nuget 引用来安装,或在 Nuget 包管理器控制台中执行命令(`Install-Package System.Linq.Dynamic`)。


奖项

荣获 Code Project 2019 年 6 月最佳文章奖。

© . All rights reserved.