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

Fuzzy Logic Dot Net Sample Part Two

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (12投票s)

2003年8月8日

7分钟阅读

viewsIcon

112107

downloadIcon

2167

C# 中的模糊逻辑库

引言

这是 Fuzzy Dot Net 系列文章的第三部分,重点介绍 Fuzzy Dot Net 示例应用程序的最终版本。您还记得在前一篇文章中,Fuzzy Dot Net 示例应用程序被设计为一个简化的中央供暖模型。这样做是为了展示模糊逻辑技术如何在输入数字不确定时用于做出决策。这是通过使用模糊数来实现的,模糊数代表一系列数字,通常有一个标识符或名称来区分它们。这些模糊数存储在模糊集中,我之前说过,模糊集允许我们使用一种近乎英语的思维方式来处理集合中的信息,这种方式称为规则。在这个版本的 Fuzzy Logic 示例应用程序中,我们将更详细地了解这些集和规则是如何在实践中使用的。

Fuzzy Dot Net 示例应用程序第二部分

从视觉上看,程序中最明显的变化是移除了 Heater Settings Tab。这是因为代码现在使用模糊逻辑来计算将应用于加热器的增量或减量值。另一个需要注意的变化是,Start Settings Tab 上的 Ideal Temperature 不再是只读的,因为对代码的更改现在允许代码计算加热器值是应该减小还是增大。目前的准确度可以达到三单位的浮动。这可以进一步优化,但我认为稍微偏离一点会更现实,因为像温度这样精细的东西,除非您对环境有完全的控制,否则几乎不可能百分之百达到要求的温度,而在这个房间的例子中,情况并非如此。

运行示例应用程序

与应用程序的先前版本一样,可以单独通过选项卡设置热量损失量。但这次您可以更改您希望房间保持的理想温度,尽管如上所述,这总会存在一定的故意误差。

示例应用程序中的模糊逻辑

应用程序中改变的第一个地方是添加了两个新的模糊集。它们是:

    heaterControl.Name = "Heater Control";
    FuzzyNumber temp36 = new FuzzyNumber( "PositionOne", 0, 2 );
    FuzzyNumber temp37 = new FuzzyNumber( "PositionTwo", 1, 4 );
    FuzzyNumber temp38 = new FuzzyNumber( "PositionThree", 3, 6 );
    FuzzyNumber temp39 = new FuzzyNumber( "PositionFour", 5, 8 );
    FuzzyNumber temp40 = new FuzzyNumber( "PositionFive", 7, 10 );
    FuzzyNumber temp41 = new FuzzyNumber( "PositionSix", 9, 12 );
    FuzzyNumber temp42 = new FuzzyNumber( "PositionSeven", 11, 14 );
    heaterControl[ 0 ] = temp36;
    heaterControl[ 1 ] = temp37;
    heaterControl[ 2 ] = temp38;
    heaterControl[ 3 ] = temp39;
    heaterControl[ 4 ] = temp40;
    heaterControl[ 5 ] = temp41;
    heaterControl[ 6 ] = temp42;

    heaterDifference.Name = "Heater Difference";
    FuzzyNumber temp43 = new FuzzyNumber( "Light", 0, 8 );
    FuzzyNumber temp44 = new FuzzyNumber( "MediumLight", 5, 13 );
    FuzzyNumber temp45 = new FuzzyNumber( "Medium", 10, 18 );
    FuzzyNumber temp46 = new FuzzyNumber( "MediumLarge", 15, 23 );
    FuzzyNumber temp47 = new FuzzyNumber( "Large", 20, 28 );
    FuzzyNumber temp48 = new FuzzyNumber( "LargeHeavy", 25, 33 );
    FuzzyNumber temp49 = new FuzzyNumber( "Heavy", 28, 43 );
    heaterDifference[ 0 ] = temp43;
    heaterDifference[ 1 ] = temp44;
    heaterDifference[ 2 ] = temp45;
    heaterDifference[ 3 ] = temp46;
    heaterDifference[ 4 ] = temp47;
    heaterDifference[ 5 ] = temp48;
    heaterDifference[ 6 ] = temp49;

这些集的想法是,heaterControl 集就像加热器上的控制旋钮。集的成员命名反映了这一点,因为集的每个成员代表了刻度盘上的一个刻度。刻度盘显然可以朝一个方向转动以增加加热器的输出,朝另一个方向转动以向环境/房间吹入更凉的空气。

加热器差集是一个内部集,不代表现实世界中的任何事物,而是旨在帮助计算应用于加热器控制的最终结果。如果您愿意,它是计时器返回的值与此反映在控制器上的实际变化量之间的桥梁。代码可能会更好地解释这一点。

    if( doorSet.IsTerm( "Warm" ) == true )
    {
        doorSet.FuzzySetValue = 0.0;
    }

    if( doorSet.IsTerm( "Cool" ) == true )
    {
        heaterDifference.FuzzySetValue +=
             heaterDifference.ValueFromTerm( "Light" );
        doorSet.FuzzySetValue = 0.0;
    }

    if( doorSet.IsTerm( "Cooler" ) == true )
    {
        heaterDifference.FuzzySetValue +=
             heaterDifference.ValueFromTerm( "MediumLight" );
        doorSet.FuzzySetValue = 0.0;
    }

对于检测到的每个术语或标识符,加热器差值都会更新一个固定量。但是,事情一如既往地更加复杂。您可能已经从加热器差集的定义中注意到这些值是重叠的。这就引出了模糊逻辑的经典问题:当一个值不再那么“冷”但又不够“更冷”时会发生什么?也就是说,当它可能同时属于两者时,在这种情况下值为 7。现在,在这个点上,值为 7 时,doorSet 的值将是“冷”和“更冷”。有几种方法可以处理这种情况,第一种是我选择的方式,即每次值落入一个范围时,将加热器差值变量增加一次。更准确的方法是使用多个 if else 语句来测试值(在此情况下为 doorSet)是否在两个范围内有效。例如:

    if( doorSet.IsTerm( "Cool" ) == true 
     && doorSet.IsTerm( "Cooler" ) == true )

第三种方法是根据每个范围内的成员值来分配这些值,因此高成员值将分配给变量大部分或全部的值,该值属于“冷”范围,但仅分配“更冷”范围值的一小部分。

下一部分代码是我们如何将加热器差集中的值转换为加热器控制集所需的正确控制值。这是通过简单的 if 语句完成的,这些语句演示了模糊逻辑规则思想的一个简单版本。

    /// if difference is Light then Control is position One
    if( heaterDifference.IsTerm( "Light" ) == true )
    {
        heaterControl.SetToTerm( "PositionOne" );
    }

    /// if difference is medium light then control is Position Two
    else if( heaterDifference.IsTerm( "MediumLight" ) == true )
    {
        heaterControl.SetToTerm( "PositionTwo" );
    }

请注意,在此次测试中使用了 else if 结构,因为加热器控制不是累积设计的。

接下来我们来到最后一部分,正如我在上一篇文章结束时提到的,这是我们需要将我们一直在使用的模糊数转换为一个变量,该变量可用于调整加热器集的加热。这是此代码中唯一一次使用正常变量或使用模糊逻辑术语中的“清晰”变量。

    if( ( double )this.idealTemperature.Value >=  heaterSet.FuzzySetValue )
    {
        heaterSet.FuzzySetValue += heaterControl.ValueFromTerm(
             heaterControl.GetTerm() );
    }
    else
        heaterSet.FuzzySetValue -= heaterControl.ValueFromTerm(
             heaterControl.GetTerm() );

idealTempaterature 变量在这里用于简单地决定是增加还是减少 Heater Control。

问题

下载的代码有一个主要问题,这让我非常恼火,但我似乎无能为力。每当在 Developer Studio 2003 中打开项目时,程序顶部的图形都会被 GUI 丢失,如果您尝试添加它,环境会抱怨输入值不正确。这纯属胡扯,非常恼人,这意味着每次打开项目时,您都必须从用户控件中删除 FuzzyGraphic,然后将 FuzzyGraphic 添加到用户控件并将其重新定位在窗体上。然后您必须打开窗体代码并删除添加的变量(FuzzyGraphic1),然后查找并替换 FuzzyGraphic1,将其替换为 FuzzyGraphic2。我希望这只是我系统上的问题,但到目前为止,我没有任何理由相信它不是。

最后

这就是本节的内容,它应该可以作为模糊逻辑及其使用入门。至于下一步,我需要做一些研究并编写一些实验代码,看看会走向何方。

历史

  • 2003 年 8 月 8 日:初始发布。

  • 2003 年 8 月 20 日:更新下一篇文章链接

  • 2004 年 9 月 15 日:重建演示代码

注意

系列中的最后一篇文章包含库的最新代码。不会进行向后兼容的尝试,我将按我自己的意愿更改库。

下一篇文章链接

参考文献

  • Tom Archer ( 2001 ) C# 内幕,Microsoft Press
  • Jeffery Richter (2002) Applied Microsoft .NET Framework Programming, Microsoft Press
  • Charles Peltzold ( 2002 ) 使用 C# 编程 Microsoft Windows,Microsoft Press
  • Robinson 等 ( 2001 ) 专业 C#,Wrox
  • Bart Kosko ( 1994 ) 模糊思维,Flamingo
  • Buckley & Eslami ( 2002 ) 模糊逻辑与模糊集导论,Physica-Verlag
  • Earl Cox ( 1999 ) 模糊系统手册,AP Professional
© . All rights reserved.