一个人如何管理上千条IF ... THEN ... ELSE规则?


214

我正在考虑构建一个应用程序,该应用程序的核心是数千个if ... then ... else语句。该应用程序的目的是能够预测奶牛在任何景观中如何移动。他们受到太阳,风,食物来源,突发事件等的影响。

如何管理这样的应用程序?我想象在经过数百个IF语句之后,程序将如何响应并调试导致某种反应的结果将意味着每次必须遍历整个IF语句树,这将是无法预测的好。

我已经阅读了一些有关规则引擎的内容,但是我看不到它们如何克服这种复杂性。


22
您需要看一下DSL编程:en.wikipedia.org/wiki/Domain-specific_language此外,您还可以创建一些数据驱动的元规则引擎。例如,您可以根据数据生成模型(例如,数据挖掘KDD)
2011年

14
谷歌的“专家系统”和“网”;祝好运。
Steven A. Lowe

9
将硬编码的if / then语句从源代码中移到驱动模拟的外部数据中。
2011年

6
我会在文本文件中绑定一些值,然后使用循环遍历包含名称的HashMap。
James P.

2
David-关于程序员的问题,当发布超过15个答案时,将转换为CW。我们无法控制谁发布了第16个答案。
克里斯·

Answers:


73

逻辑编程语言Prolog可能就是您想要的。您的问题陈述不够具体,我无法评估它是否合适,但与您所说的相近。

Prolog程序由适用的事实和规则组成。这是一个简单的示例规则,其中规定:“如果母牛饿了,那么母牛就会移到某个位置,并且新位置的食物比旧位置的食物多”:

moves_to(Cow, Location) :-
  hungry(Cow),
  current_location(Cow, OldLoc),
  food_in(OldLoc, OldFood), food_in(Location, NewFood),
  NewFood > OldFood.

大写字母中的所有事物都是变量,您不知道其价值的事物。Prolog尝试查找满足所有条件的这些变量的值。此过程使用称为统一的强大算法完成,该算法是Prolog和类似逻辑编程环境的核心。

除规则外,还提供事实数据库。一个符合上述规则的简单示例如下:

current_location(white_cow, pasture).

current_location(black_cow, barn).
hungry(black_cow).

current_location(angry_bull, forest).
hungry(angry_bull).

food_in(barn, 3).
food_in(pasture, 5).
food_in(forest, 1).

请注意,white_cow和牧场等不是用大写字母写的。它们不是变量,而是原子。

最后,您进行查询并询问会发生什么情况。

?- moves_to(white_cow, Destination).
No.
?- moves_to(black_cow, Destination).
Destination = pasture
?- moves_to(Cow, Destination).
Cow = black_cow, Destination = pasture
Cow = angry_bull, Destination = barn
Cow = angry_bull, Destination = pasture

第一个查询询问白牛将移动到哪里。根据上述规则和事实,答案是否定的。这可以根据您的需要解释为“我不知道”或“它不会动”。

第二个查询询问黑牛在哪里移动。它移动到牧场吃。

最后一个查询询问所有母牛在哪里移动。结果,您获得了所有可能的意义(母牛,目的地)。在这种情况下,黑牛如预期般移至牧场。但是,愤怒的公牛有两个满足规则的选择,它既可以搬到牧场,也可以搬到谷仓。

注意:自从我上次写Prolog以来已经有好几年了,所有示例在语法上可能都不正确,但是这个想法应该是正确的。


10
-1:我认为Prolog不可能是正确的答案。是的,在Prolog中获得if-else规则可能很容易。但是,当然,您将不得不做其他事情。不管它是什么(IO,GUI,Web开发……),Prolog都会让人感到痛苦。
马丁·托马

4
看看learnprolognow.com,并将prolog嵌入另一种语言比以前要容易得多
Zachary K

@ZacharyK:链接已断开。
RenniePet

@MartinThoma:你能解释一下你的评论吗?Prolog IMHO的主要问题是缺少1.一种声明式的搜索控制方式和2.输入方式。但是,如果您的应用程序在很大程度上不依赖于这两个应用程序,那么我就不会在这里先验地看到使用Prolog的问题
SN

139

解决if web问题,您可以创建一个规则引擎,其中每个特定的规则都将被独立编码。对此的进一步改进将是创建特定于域的语言(DSL)以创建规则,但是仅DSL只能将问题从一个代码库(主代码)转移到另一个代码库(DSL)。如果没有结构,则DSL的性能将不会比本地语言(Java,C#等)更好,因此,在找到一种改进的结构方法之后,我们将重新讨论它。

基本问题是您遇到了建模问题。每当您遇到这样的组合情况时,就清楚地表明,描述这种情况的模型抽象过于粗糙。您很可能在单个实体中合并应该属于不同模型的元素。

如果您继续破坏模型,最终将完全消除这种组合效应。但是,当走这条路时,很容易迷失在设计中,甚至造成更大的混乱,这里的完美主义不一定是您的朋友。

有限状态机和规则引擎只是如何解决此问题并使之更易于管理的一个示例。这里的主要思想是摆脱诸如此类的组合问题的好方法,通常是创建一个设计并以嵌套的抽象层次重复该设计,直到您的系统令人满意地执行为止。类似于如何使用分形来创建复杂的图案。无论您是用显微镜还是从高鸟瞰图查看系统,规则都保持不变。

将其应用于您的域的示例。

您正在尝试模拟奶牛在地形中的移动方式。尽管您的问题缺少详细信息,但我想您可能会在其中包含大量决策片段,例如,if cow.isStanding then cow.canRun = true但是当您添加地形详细信息时您会陷入困境。因此,对于您要采取的每项措施,您都必须检查一下可以想到的各个方面,并为下次可能的措施重复进行这些验证。

首先,我们需要可重复的设计,在这种情况下,它将是用于模拟模拟变化状态的FSM。所以我要做的第一件事就是实现一个参考FSM,定义一个状态接口,一个过渡接口,以及一个过渡上下文可以包含可供其他两个人使用的共享信息。不管上下文如何,基本的FSM实现都会从一个过渡切换到另一个过渡,这是规则引擎进入的地方。规则引擎干净地封装了要进行过渡时必须满足的条件。这里的规则引擎可以像规则列表一样简单,每个规则都有一个返回布尔值的评估函数。要检查是否应该进行过渡,请对规则列表进行迭代,如果其中任何一个评估为false,则不会进行过渡。转换本身将包含行为代码,以修改FSM(和其他可能的任务)的当前状态。

现在,如果我开始将模拟作为单个大型FSM在GOD级别上实现,那么我最终会遇到很多可能的状态,转换等。if-else混乱看起来像是固定的,但实际上只是散布着:每个IF现在,一条规则针对上下文的特定信息(此时几乎包含了所有内容)执行测试,并且每个IF主体都位于转换代码中。

输入分形分解:第一步是为每头母牛创建FSM,其中状态是母牛自身的内部状态(站立,奔跑,行走,放牧等),并且它们之间的过渡会受到环境的影响。该图可能不完整,例如,只能从站立状态访问放牧,而拒绝其他任何转换,因为仅在模型中不存在。在这里,您可以有效地将数据分为两种不同的模型:奶牛和地形。每个都有自己的属性集。此故障将使您简化整体发动机设计。现在,您不再需要一个单独的规则引擎来决定所有事情,而是可以使用多个更简单的规则引擎(每个转换一个)来决定非常具体的细节。

因为我为FSM重新使用了相同的代码,所以这基本上是FSM的配置。 还记得我们之前提到的DSL吗?如果您要编写很多规则和转换,这就是DSL可以发挥很多作用的地方。

更深入

现在,上帝不再需要处理管理母牛内部状态的所有复杂性,但我们可以将其进一步推进。例如,管理地形仍然涉及很多复杂性。在这里,您可以确定细分是否足够。例如,如果在您的上帝中您最终要管理地形动态(长草,泥土,干泥,短草等),我们可以重复相同的模式。没有什么可以阻止您通过将所有地形状态(长草,短草,泥泞,干燥等)提取到新的地形FSM中(在状态之间进行转换以及简单的规则)将这种逻辑嵌入到地形本身中的。例如,要进入浑浊状态,规则引擎应检查上下文以查找液体,否则是不可能的。现在上帝变得更简单了。

您可以通过使FSM自治并为每个线程分配一个线程来完善FSM系统。最后一步不是必需的,但是它允许您通过调整委派决策的方式(启动专门的FSM或仅返回预定状态)来动态更改系统的交互。

还记得我们提到过过渡还可以完成“其他可能的任务”吗?让我们通过添加不同模型(FSM)相互通信的可能性来探索这一点。您可以定义一组事件,并允许每个FSM为这些事件注册侦听器。因此,例如,如果一头母牛进入地形十六进制,则该十六进制可以为过渡变化注册侦听器。这里有些棘手,因为每个FSM都是在非常高的级别实现的,而对它所拥有的特定领域一无所知。但是,您可以通过让母牛发布事件列表来实现此目的,并且如果母牛看到它可以做出反应的事件,则该单元可以进行注册。良好的事件家庭层次结构是一项不错的投资。

通过对草的营养水平和生长周期进行建模,您可以将其推得更深,您可以……猜到了……嵌入在地形补丁自己模型中的草FSM。

如果您将这个想法推进得足够远,那么上帝就几乎无所作为,因为所有方面几乎都是自我管理的,从而腾出了时间花在更敬虔的事情上。

概括

如上所述,这里的FSM并不是解决方案,仅是一种说明这种问题的解决方案的方法,并不是说每个人的代码,而是如何对问题建模。还有其他可能的解决方案,而且可能比我的FSM主张更好。但是,“分形”方法仍然是解决此难题的好方法。如果操作正确,您可以在重要的位置动态分配更深的层次,而在重要的位置提供更简单的模型。您可以将更改排队,并在资源变得更可用时应用它们。在一个动作序列中,计算养分从牛到草块的转移可能并不那么重要。但是,您可以记录这些过渡并在以后应用更改,或者通过简单地替换规则引擎,或者对不属于直接字段的元素使用更简单的朴素版本来完全替换FSM实现,​​以近似的估计来进行猜测。兴趣(位于该领域另一头的那头母牛),以便进行更详细的互动来获得关注并获得更大的资源份额。所有这些都没有重新审视整个系统;由于每个零件都很好地隔离,因此可以更容易地创建插入式替换来限制或扩展模型的深度。通过使用标准设计,您可以在此基础上构建并最大化在DSL等临时工具上的投资,以定义事件的规则或标准词汇,再次从很高的层次开始,并根据需要进行改进。由于每个零件都很好地隔离,因此可以更容易地创建插入式替换来限制或扩展模型的深度。通过使用标准设计,您可以在此基础上构建并最大化在DSL等临时工具上的投资,以定义事件的规则或标准词汇,再次从很高的层次开始,并根据需要进行改进。由于每个零件都很好地隔离,因此可以更容易地创建插入式替换来限制或扩展模型的深度。通过使用标准设计,您可以在此基础上构建并最大化在DSL等临时工具上的投资,以定义事件的规则或标准词汇,再次从很高的层次开始,并根据需要进行改进。

我将提供一个代码示例,但这是我现在所能做的全部。


1
我接受了这个答案,因为在解释解决方案上,它比其他方法要好一个数量级。如果有更好的答案,我可能会改变我接受的答案。您的解决方案似乎也足够激进,可以有所作为。但是,我仍然在理解如何定义不同模型应如何交互的规则方面仍然存在问题。你可以举一个例子吗?
大卫,

-1我不明白为什么不能仅通过决策树来解决?(再加上采用该模型并将其转换为可运行代码的DSL)?
2011年

14
神对FSM?
John Cromartie 2012年

1
决策树和规则引擎仅用于没有必要对现有方面进行建模的内在价值的情况下,因为它们仅是结束计算的一种手段。您一直在医疗软件中看到这一点。话虽这么说,如果您想对实际行为建模,则应该尝试这样做。在很多情况下,一个问题中唯一找到的逻辑就是成千上万个这样的结果,而这无穷无尽。这是有效的,这就是为什么我们有工具来解决这个问题。
Deleteduser 2012年

1
在游戏编程领域,这已被证明非常成功。更改规则或属性并让行为出现,然后检查一个值以决定如何执行它会更快,更容易。
Ben Leggiero

89

听起来您正在谈论的所有这些条件语句实际上应该是配置程序的数据,而不是程序本身的一部分。如果您可以这样处理它们,则可以通过更改程序的配置来随意修改程序的工作方式,而不必每次都要改进模型时都必须修改代码并重新编译。

根据问题的性质,有很多不同的方法可以对现实世界进行建模。您的各种条件可能会成为应用于模拟的规则或约束。而不是像这样的代码:

if (sunLevel > 0.75) {
   foreach(cow in cows) {
       cow.desireForShade += 0.5;
   }
}
if (precipitation > 0.2) {
   foreach(cow in cows) {
       cow.desireForShelter += 0.8;
   }
}

您可以改用如下代码:

foreach(rule in rules) {
   foreach (cow in cows) {
      cow.apply(rule);
   }
}

或者,如果您可以开发一个线性程序来模拟给定许多输入的奶牛行为,则每个约束可能会变成方程式系统中的一条线。然后,您可以将其转换为可以迭代的Markov模型。

很难说出什么是适合您的情况的正确方法,但是如果您认为约束是程序的输入而不是代码的输入,那么我认为它会更轻松。


4
请描述“ cow.apply(rule);”的方式 与配置文件一起使用?
2011年

8
@Krom,在不知道我们实际上在谈论哪种系统的情况下,很难用具体的说法说出来。我上面的观点是将成千上万的条件视为程序的输入,这样您就不必为每个条件编写代码,并且可以在不更改程序的情况下更改条件。但是可以,如果可以将条件视为数据,则可以将它们与程序分开存储在某种文档或配置文件中。
卡莱布

2
@Krom-简单。您将阅读规则,然后将其应用于给定的母牛。
拉姆猎犬,

5
将代码移动到配置文件并不总是一个好方法。魔术很难调试。
里奇·克拉克森

44

没有人提到这一点,所以我想我要明确地说:

成千上万的“ If .. Then .. Else”规则表明应用程序设计错误。

尽管特定于域的数据表示形式看起来像这些规则,但您是否绝对可以确定您的实现应类似于特定于域的表示形式?


18
不一定正确。有些问题只能通过庞大的决策树来解决。但是,对于那些由if-then-else文字树组成的解决方案,当然是一种设计不良的解决方案。存在更灵活和可维护的方式来执行此操作。
SF。

43
我认为这就是问题的重点。OP有一个特定于他的领域的问题,在幼稚的实现中,将需要成千上万的...那么...否则。他直觉这很麻烦,并向此社区询问有关执行此操作的更好方法。提出问题的唯一事实是一个很好的信号,表明已经理解了该问题,尽管您的回答正确,但对问题没有任何帮助。
Newtopian 2011年

@Newtopian一个高级的用户或程序员将理解这一点,并将其显而易见。但是,天真的用户或程序员可能不会意识到这一点。我在知情的情况下说过,这里大多数人显而易见的是-我确认OP是正确的,因为他认为这将是有问题的,并且绝对不应该立即或天真地实施。
blueberryfields

我同意,您可以用多态性和DI代替。如果您有成千上万个,那么您的设计就很糟糕。
DarthVader 2012年

17

请使用适合该任务的软件/计算机语言。Matlab通常用于建模复杂的系统,实际上您可以在其中拥有成千上万的条件。不使用if / then / else子句,而是通过数值分析。R是一种开放源代码的计算机语言,其中包含工具和程序包以执行相同的操作。但这意味着您还必须用更多数学术语重述模型,以便可以在模型中同时包含主要影响和影响之间的相互作用。

如果您还没有,请遵循有关建模和仿真的课程。您应该做的最后一件事是考虑根据if-then-else来编写类似的模型。我们拥有蒙特卡洛·马尔科夫链,支持向量机,神经网络,潜在变量分析,...请不要因为忽视现有建模工具上的财富而把自己抛在100年前。


我很惊讶这个问题很少受到关注。数值分析和建模是if-else机器的核心。但是,如果应用程序必须严格遵守规则,则可能无法容忍误报。(想想银行业务)
阿伦·何塞

13

规则引擎可能会有所帮助,因为如果有那么多的if / then规则,将它们全部放在程序外部的某个位置可能会很有帮助,用户可以在无需编辑编程语言的情况下对其进行编辑。此外,可视化工具可能可用。

您还可以查看逻辑编程解决方案(例如Prolog)。您可以快速修改if / then语句的列表,并进行诸如查看输入的任何组合是否会导致某些结果等工作。在一阶谓词逻辑中,它可能比过程代码(或面向对象的代码)。


11

我忽然忽然间:

您需要使用决策学习树(ID3算法)。

很有可能有人用您的语言实现了它。如果没有,您可以移植现有的库


遵循上面给出的DSL思想。尝试弄清楚如何将问题抽象为某种形式的符号代数,然后加以实现。
Zachary K


9

每个大型应用程序都包含数千个if-then-else语句,不包括其他流控制,尽管这些应用程序很复杂,但它们仍在调试和维护中。

另外,语句的数量不会使流程不可预测。异步编程可以。如果您同步使用确定性算法,则每次都会有100%可预测的行为。

您可能应该更好地解释在堆栈溢出或代码检查中 要做什么,以便人们可以建议您使用的精确重构技术。您可能还想问一些更精确的问题,例如“如何避免嵌套过多的if语句(给出一段代码)”。


1
大多数应用具有2-3级嵌套和1行条件。如果问题需要决策树向下嵌套50个级别,并且许多条件都是30个或更多变量的逻辑复合,那该怎么办?
SF。

尽管“每个大型应用程序...”都是正确的,但很显然,OP所谈论的是条件表达式的长序列,这些条件表达式本质上构成了模型中的规则。巨大的嵌套if语句组充其量很快就会变得笨拙,因此需要一种更好的方法。
卡莱布(Caleb)

@Caleb:你说得对,很明显现在,与这个问题开始的精确的例子。我写答案时还没有编辑问题。这解释了我和同时发布的其他两个答案的实际不一致。
2011年

2

通过精心设计使您的应用程序可管理。通过将各种业务逻辑划分为单独的类/模块来设计应用程序。编写单元测试,分别测试这些类/模块。这是至关重要的,它将帮助您确保按预期实现业务逻辑。


2

可能不会有单一的方法来设计解决问题的方法,但是,如果您试图将发现大量自己的if语句并应用解决方案的不同区域分开,则可以逐个管理它的复杂性每个较小的问题。

可以使用类似于“ 重构”中讨论的规则的技术,将大型条件分解为可管理的块-例如,具有公共接口的多个类可以替换case语句。

早退也有很大帮助。如果您有错误条件,请通过引发异常或返回而不是让它们嵌套来使这些错误在函数的开头消失。

如果将条件分解为谓词函数,则跟踪它们可能会更容易。另外,如果您可以将它们转换为标准格式,则可以将其转换为动态构建的数据结构,而不是采用硬编码的数据结构。


2

我建议您使用规则引擎。对于Java,jBPM或Oracle BPM可能会有用。规则引擎基本上允许您通过XML配置应用程序。


+1我最近一直在使用Drools和Mvel作为表达规则的语言,而这正是您所需要的。尽管它非常快。
2011年

流口水是一个不错的选择。我个人现在正在使用Oracle BPM。还有Feugo。提供了许多开放源代码和专有工具。
Sid

2

无论是用“如果-那么”程序代码或为业务应用程序设计的众多规则解决方案来描述,“规则”都无法很好地解决该问题。机器学习提供了许多对此类场景进行建模的机制。

从根本上讲,必须制定某种方案来表示影响“系统”(例如牧场中的母牛)的因素(例如,阳光,风,食物来源,突发事件等)。尽管人们误认为人们可以创建一种真正有价值的功能表示形式,而不是离散的,但现实世界(包括人的神经系统)中没有计算机基于真实价值或基于真实价值进行计算。

获得有关因素的数值表示后,您可以构建几个数学模型中的任何一个。我建议一个二部图,其中一组节点代表奶牛,另一组节点代表牧场的一些单位面积。在任何情况下,一头奶牛都会占据一定面积的牧场。对于每头母牛,便存在与当前和所有其他牧场单位相关的效用值。如果该模型以母牛为前提来优化(无论对母牛而言是什么意思)其牧场单位的效用值,则母牛会在一个单位到另一个单位之间努力优化。

蜂窝自动机非常适合执行模型。真正有价值的数学世界中激发牛运动的基础数学是场梯度模型。母牛从感知到的实用价值较低的位置移动到感知到的较高实用价值的位置。

如果将环境变化注入系统,那么它将不会移动到稳定状态的奶牛定位解决方案。它也将成为可以应用博弈论各方面的模型;但这并不一定会增加这种情况。

在此优势是,在模型运行时,通过在二部图中减去“母牛”单元格并将其添加,可以轻松地屠宰母牛或获得新母牛。


1

我认为您不应定义太多if-else语句。从我的角度来看,您的问题有多个组成部分:

  • 它应该是异步的或多线程的,因为您有许多具有不同个性,不同配置的母牛。每头母牛问自己下一步要走什么方向。在我看来,同步代码对于解决此问题是一个糟糕的工具。

  • 决策树的配置不断变化。它取决于实际母牛的位置,天气,时间,地形等。除了构建复杂的if-else树之外,我认为我们应该将问题减少到风向或方向-权重函数: 图1 图1-方向-一些规则的权重函数

    母牛应始终朝总重量最大的方向前进。因此,您可以为每头奶牛添加一套规则(具有不同的方向-权重函数),而不是构建较大的决策树,并在每次询问方向时简单地处理结果。您可以通过每次位置更改或时间的流逝来重新配置这些规则,也可以将这些详细信息作为参数添加,每个规则都应获得。这是一个实施决策。获得方向的最简单方法是,以0°到1°的步长添加一个简单的回路(从0°到360°)。之后,您可以计算每个360度方向的总权重,并通过max()函数运行以获得正确的方向。

  • 您不一定需要神经网络来执行此操作,每个规则只需要一个类别,奶牛可能只需要一个类别,也许地形就可以等等……而场景则需要一个类别(例如3头具有不同规则的母牛, 1个特定地形)。 图2 图2-Cow应用程序异步决策节点和连接

    • 红色表示消息传递方向-通过规则的权重图
    • 蓝色,用于决策后的方向和位置更新
    • 方向和位置更新后,用于输入更新的绿色
    • 黑色用于获取输入

    注意:您可能需要一个消息传递框架来实现这样的功能

    因此,如果不让学习母牛成为您的问题的一部分,则不需要神经网络或遗传算法。我不是人工智能专家,但是我想,如果您想使母牛适应真实的母牛,那么您可以简单地通过遗传算法和适当的规则来做到。如果我了解得很好,则需要使用随机规则设置的牛群。之后,您可以将真实奶牛的行为与模型种群的行为进行比较,并保持10%的牛走到最接近真实牛的路径。之后,您可以根据保留的10%向奶牛工厂添加新的规则配置约束,并向种群中添加新的随机奶牛,依此类推,直到您得到行为与真实奶牛一样的模型奶牛...


0

我要补充的是,如果您确实有成千上万个IF ... THEN规则,则可能会过度指定。值得一提的是,我参加过的神经网络建模讲座通常以说明“一组简单的规则”如何产生相当复杂且合理的现实匹配行为(在这种情况下,是实际的神经元在起作用)开始。那你确定您需要成千上万的条件?我的意思是,除了天气,食物来源位置,突发事件,放牧和地形等4-5个方面之外,您真的还会有更多变量吗?当然,如果您尝试组合这些条件进行所有可能的排列,那么您很容易拥有成千上万的规则,但这不是正确的方法。也许是一种模糊逻辑风格的方法,其中各种因素在每头母牛的位置上造成偏差,再加上整体决策,这将使您以更少的规则来做到这一点。

我也与其他所有人一样,认为规则集应与一般的代码流分开,以便您可以轻松地对其进行调整而无需更改程序。您甚至可以提出竞争规则集,并查看它们如何与真实的奶牛运动数据进行对比。听起来很有趣。


0

已经提到了专家系统,这是AI的一个领域。为了进一步扩展这些内容,阅读推理引擎可能会对此有所帮助。使用Google搜索可能会更有用-编写DSL很简单,您可以使用Gold Parser之类的解析器轻松地做到这一点。困难的部分来自建立决策树并有效地执行决策。

许多医疗系统已经在使用这些引擎,例如英国的NHS Direct网站

如果您是.NET使用者,那么Infer.NET可能对您有用。


0

由于您观察的是母牛的运动,它们被卡在360度方向上(母牛不能飞翔。)您的行进速度也很高。可以将其定义为向量。

现在您如何处理太阳位置,山坡,嘈杂的声音?

每个程度都是一个变量,表示希望朝那个方向前进。假设一条小树枝以90度的角度向奶牛的右边靠拢(假设奶牛的脸朝0度倾斜)。向右走的欲望会下降,向右走的欲望270(左)会上升。经历所有刺激,增加或减少它们对奶牛向某个方向行驶的渴望的影响。一旦施加了所有刺激,母牛将朝着最高欲望的方向前进。

您还可以应用渐变,因此刺激不必是二进制的。例如,小山不是在一个方向上笔直。母牛可能是在山谷中或在山上的道路上,其平坦的笔直向前,斜度为45 *,斜度为90 *。在180 *陡峭的山上。

然后,您可以调整事件的权重及其影响的方向。而不是ifs的列表,您有一个测试来寻找最大值。同样,当您想添加刺激时,您可以在测试前应用刺激,而不必处理越来越多的复杂性。

与其说牛将向任何360度方向走,不如说将其分解为36个方向。每个都是10度

与其说牛将向任何360度方向走,不如将其分解为36个方向。每个都是10度。根据您需要的具体程度而定。


-2

使用OOP。如何创建一堆处理基本条件并运行随机方法来模拟您所做的事情的类。

寻求程序员的帮助。

class COW_METHODS {

    Function = array('Action1','Action2',....'ActionX');

    function doAction() {
       execute(Function[random(1,5000]);
    }

    function execute(DynamicFunction) {
        exec(DynamicFunction());
    }

    Function Action1() {
        turnRight();
        eatGrass();
    }
    /*  keep adding functions for COW Methods ...  etc  */
    /*  and add classes for conditions inherit them as needed  */
    /*  keep an object to define conditions =  Singleton etc.  */
}

为什么这是最后的答案。直截了当,就是现在,成千上万的if else语句现在只是设计程序的一种方式。
wfbarksdale 2012年

1
因为当被问到“ 如何使我的销售额翻两番? ” 时,建议“ 使用OOP。请程序员帮忙。 ”与提供建议“ 拨打更多电话! ”的价值是一样的。这不是严格错误,但也无济于事。
JensG

2
我投了反对票,因为这是一个错误的答案。技术上 您的答案与OOP无关。所谓的类COW_METHODS似乎不过是松散相关方法的集合而已。关注点分离在哪里?与此问题相关,这如何帮助申请者?
oɔɯǝɹ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.