我正在考虑构建一个应用程序,该应用程序的核心是数千个if ... then ... else语句。该应用程序的目的是能够预测奶牛在任何景观中如何移动。它们受到太阳,风,食物来源,突发事件等的影响。
如何管理此类应用程序?我想在经过数百个IF语句之后,程序将如何响应并调试导致某种反应的结果将意味着每次必须遍历整个IF语句树,这将是无法预测的好。 />
我已经阅读了一些有关规则引擎的内容,但是我看不出它们如何克服这种复杂性。
#1 楼
逻辑编程语言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已经好几年了,所有示例在语法上可能都不正确但这个想法应该是正确的。
评论
-1:我认为Prolog不可能是正确的答案。是的,在Prolog中获得if-else规则可能很容易。但是当然,您将不得不做其他事情。不管它是什么(IO,GUI,Web开发等等),Prolog都将是一个痛苦。
–马丁·托马
2014年10月13日在20:19
请访问learnprolognow.com,将prolog嵌入另一种语言比以前容易得多。
– Zachary K
2014年11月16日15:01
@ZacharyK:链接已断开。
–RenniePet
16年2月2日在12:13
@MartinThoma:您能解释一下您的评论吗? Prolog IMHO的主要问题是缺少1.一种声明式的搜索控制方式和2.输入方式。但是,如果您的应用程序在很大程度上不依赖于这两个应用程序,那么我不会先验地在此处使用Prolog出现问题
– S.N.
16-09-28在19:59
#2 楼
解决if web问题,您可以创建一个规则引擎,其中每个特定的规则都将被独立编码。对此的进一步改进将是创建特定于域的语言(DSL)来创建规则,但是仅DSL只能将问题从一个代码库(主代码)转移到另一个代码库(DSL)。没有结构,DSL的性能将不会比本地语言(Java,C#等)更好,因此,在找到一种改进的结构化方法后,我们将重新讨论它。基本问题是遇到建模问题。每当您遇到这样的组合情况时,就清楚地表明,描述这种情况的模型抽象过于粗糙。您很可能在单个实体中合并了应该属于不同模型的元素。
如果继续分解模型,最终将完全消除这种组合效应。但是,当走这条路时,很容易迷失在设计中,甚至造成更大的混乱,这里的完美主义不一定是您的朋友。
有限状态机和规则引擎只是解决此问题的一个示例可以分解并使其更易于管理。这里的主要思想是摆脱诸如此类的组合问题的好方法,通常是创建一个设计并以嵌套的抽象层次重复该设计,直到您的系统令人满意地执行为止。类似于如何使用分形来创建复杂的图案。无论使用显微镜还是从高空俯瞰的系统,规则都保持不变。
将其应用于域的示例。
您正在尝试模拟奶牛在地形中的移动方式。尽管您的问题缺少详细信息,但我想您可能会在其中包含大量决策片段(例如
if cow.isStanding then cow.canRun = true
),但是例如在添加地形详细信息时,您会陷入困境。因此,对于您要采取的每项操作,您都必须检查一下可以想到的各个方面,并为下一个可能的操作重复进行这些验证。首先,我们需要可重复的设计,在这种情况下,这将是FSM对模拟的变化状态进行建模。因此,我要做的第一件事就是实现一个参考FSM,定义一个状态接口,一个过渡接口,以及一个过渡上下文,它可以包含可供其他两个人使用的共享信息。不管上下文如何,一个基本的FSM实现都会从一个转换切换到另一个转换,这是规则引擎进入的地方。规则引擎干净地封装了要进行转换时必须满足的条件。这里的规则引擎可以像规则列表一样简单,每个规则列表都有一个返回布尔值的评估函数。要检查是否应该进行过渡,请对规则列表进行迭代,如果其中任何一个评估为false,则不会进行过渡。转换本身将包含行为代码,用于修改FSM的当前状态(和其他可能的任务)。现在,如果我开始在GOD级别将模拟实现为单个大型FSM,最终会出现很多可能的状态,转换等。if-else混乱看起来像是固定的,但实际上只是散布着:每个IF现在都是一个针对上下文的特定信息执行测试的规则(此时,几乎包含所有内容),并且每个IF主体都位于过渡代码中。
输入分形分解:第一步是为每头母牛创建FSM,其中状态是母牛自身的内部状态(站立,奔跑,行走,放牧等),并且它们之间的过渡会受到环境的影响。该图可能不完整,例如,只能从站立状态访问放牧,而拒绝其他任何转换,因为该模型根本不存在。在这里,您可以有效地将数据分为两种不同的模型:奶牛和地形。每个都有自己的属性集。这种故障将使您简化整体发动机设计。现在,您不再需要用一个规则引擎来决定所有事情,而是可以使用多个更简单的规则引擎(每个转换一个)来决定非常具体的细节。许多游戏公司正在使用诸如此类的有限状态机来决定这些方面。
因为我为FSM重新使用了相同的代码,所以这基本上是FSM的配置。还记得我们之前提到的DSL吗?如果您要编写很多规则和转换,这就是DSL可以发挥很多作用的地方。
深入了解
现在上帝不再需要处理所有问题管理奶牛内部状态的复杂性,但我们可以将其进一步推向前进。例如,管理地形仍然涉及很多复杂性。在这里,您可以确定细目所在的地方。例如,如果在您的上帝中最终要管理地形动态(长草,泥泞,干泥巴,短草等),我们可以重复相同的模式。没有什么可以阻止您通过将所有地形状态(长草,短草,泥泞,干燥等)提取到新的地形FSM中(在状态之间进行转换以及简单的规则)将这种逻辑嵌入到地形本身中的。例如,要进入浑浊状态,规则引擎应检查上下文以查找液体,否则是不可能的。现在上帝变得更简单了。
您可以通过使FSM具有自治性并为每个线程分配一个线程来完善FSM系统。最后一步不是必需的,但它允许您通过调整委派决策的方式(启动专用FSM或仅返回预定状态)来动态更改系统的交互。
记住我们提到过渡还可以做“其他可能的任务”吗?让我们通过添加不同模型(FSM)彼此通信的可能性来探索这一点。您可以定义一组事件,并允许每个FSM为这些事件注册侦听器。因此,例如,如果一头母牛进入地形十六进制,则该十六进制可以为过渡变化注册侦听器。这里有些棘手,因为每个FSM都是在非常高的级别实现的,而对它所包含的特定领域一无所知。但是,您可以通过让母牛发布事件列表来实现此目的,并且如果母牛看到它可以做出反应的事件,则该单元可以进行注册。良好的事件家庭层次结构是一项不错的投资。因此,如果母牛开始放牧,则该地形可以记录放牧时间,并且一段时间后可以从长草过渡到短草,从而表明这里没有东西可以吃了。
您可以推动通过对草的营养水平和生长周期进行建模,可以更深入地了解……您猜中了……将草丛FSM嵌入到地形补丁自己的模型中。
如果您将主意推向了足够高的水平,由于几乎所有方面都是自我管理的,因此无事可做,从而腾出时间花在更敬虔的事情上。
回顾
如上所述,这里的FSM并不是解决方案,而只是一种说明这种问题的解决方案的方法,并不是说每个人的代码,而是如何对问题建模。还有其他可能的解决方案,而且可能比我的FSM主张更好。但是,“分形”方法仍然是解决此难题的好方法。如果操作正确,您可以在重要的位置动态分配更深的层次,而在重要的位置提供更简单的模型。您可以将更改排队,并在资源变得更可用时应用它们。在一个动作序列中,计算养分从牛到草块的转移可能并不那么重要。但是,您可以记录这些过渡并在以后应用更改,或者通过简单地替换规则引擎或为不属于该字段直接字段的元素的更简单的朴素版本完全替换FSM实现,以近似的推测来近似。兴趣(位于该领域另一头的那头母牛),以便进行更详细的互动来获得关注并获得更大的资源份额。所有这些都没有重新审视整个系统;由于每个零件都很好地隔离,因此可以更容易地创建插入式替换来限制或扩展模型的深度。通过使用标准设计,您可以在此基础上构建并最大化在DSL等临时工具上的投资,以定义事件的规则或标准词汇,再次从很高的层次开始,并根据需要进行改进。
我将提供一个代码示例,但这是我现在所能做的。
评论
我接受了这个答案,因为在解释解决方案上比其他方法要好一个数量级。如果有更好的答案,我可能会改变我接受的答案。您的解决方案似乎也足够激进,可以有所作为。但是,我仍然在理解如何定义不同模型应如何交互的规则方面仍然遇到问题。你可以举一个例子吗?
–大卫
11年8月29日在18:45
-1我不明白为什么不能仅通过决策树来解决? (再加上使用该模型并将其转换为可运行代码的DSL)?
–黑暗之夜
2011年9月1日上午10:09
神对FSM?
–约翰·克罗马蒂(John Cromartie)
2012年9月17日下午2:46
正是在决策树和规则引擎仅用于其中的方面而没有内在价值的情况下,这些决策树和规则引擎仅是结束计算的一种手段。您一直在医疗软件中看到这一点。话虽这么说,如果您要对实际行为建模,则应尝试这样做。在很多情况下,一个问题中唯一找到的逻辑就是成千上万个这样的结果(如果没有那么多的话)。这是有效的,这就是为什么我们有工具来解决这一问题。
–deleted_user
2012年9月17日下午2:51
在游戏编程领域,这已被证明非常成功。更改规则或属性并让行为显现出来,然后检查一个值以决定如何执行它,会更快,更容易。
– Ben Leggiero
17年1月16日在19:36
#3 楼
听起来您正在谈论的所有这些条件语句实际上应该是配置程序的数据,而不是程序本身的一部分。如果您可以这样处理它们,则可以通过更改程序的配置来随意修改程序的工作方式,而不必每次都要改善模型时都必须修改代码并重新编译。根据问题的性质,有很多不同的方法可以对现实世界进行建模。您的各种条件可能会成为应用于模拟的规则或约束。而不是像这样的代码:
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);
}
}
或者,如果您可以开发一个在给定许多输入的情况下对奶牛行为进行建模的线性程序,每个约束可能会变成方程组中的一条线。然后,您可能会将其转换为可以迭代的马尔可夫模型。
很难说出适合您的情况的正确方法,但是我认为如果您这样做会更轻松将约束视为程序的输入而不是代码。
评论
请描述“ cow.apply(rule);”的方式与配置文件一起使用?
– Kromster
2011年8月26日下午5:45
@Krom,在不知道我们实际上在谈论哪种系统的情况下,很难用具体的说法说出来。上面我的观点是将成千上万的条件视为程序的输入,这样您就不必为每个条件编写代码,并且可以在不更改程序的情况下更改条件。但是可以,如果可以将条件视为数据,则可以将它们与程序分开存储在某种文档或配置文件中。
–卡莱布
11年8月26日在11:23
@Krom-简单。您将阅读规则,然后将其应用于给定的母牛。
–猎犬
2011年8月26日13:05
将代码移动到配置文件并不总是一个好方法。魔术很难调试。
–瑞奇·克拉克森(Ricky Clarkson)
2012-03-25 18:02
#4 楼
没有人提到这一点,所以我想我要明确地说:成千上万的“ If ..那么..Else”规则是设计不良的标志。
虽然特定于域的数据表示形式看起来像这些规则,但是您绝对确定您的实现应类似于特定于域的表示形式吗?
评论
不一定是真的。有些问题只能通过巨大的决策树来解决。但是,对于那些由if-then-else文字树组成的解决方案,当然是一种设计不良的解决方案。存在更灵活和可维护的方式来执行此操作。
– SF。
2011年8月26日在7:50
我认为这就是问题的重点。 OP有一个特定于他的领域的问题,在幼稚的实现中,将需要成千上万个……然后……否则。他直觉这很麻烦,并向此社区询问有关执行此操作的更好方法。提出问题的唯一事实是一个很好的信号,表明它已经被理解,您的答案虽然正确,但对问题没有任何帮助。
– Newtopian
2011年8月29日在1:54
@Newtopian一个高级的用户或程序员会理解这一点,并且显而易见。但是,天真的用户或程序员可能不会意识到这一点。我在知情的情况下指出了这里大多数人显而易见的含义-我确认OP是正确的,因为他认为这将是有问题的,并且绝对不应该立即或天真地实施。
–蓝莓田
11年8月29日在4:22
我同意,您可以用多态性和DI代替。如果您有成千上万的其他东西,那么您的设计就很糟糕。
– DarthVader
2012年8月30日在16:23
#5 楼
请使用适合该任务的软件/计算机语言。 Matlab通常用于建模复杂的系统,实际上您可以在其中拥有成千上万的条件。不使用if / then / else子句,而是通过数值分析。 R是一种开放源代码的计算机语言,其中充满了工具和软件包来执行此操作。但这意味着您还必须用更多数学术语重述模型,以便可以在模型中同时包含主要影响和影响之间的相互作用。如果还没有的话,请按照有关建模和仿真的课程学习。您应该做的最后一件事是考虑根据if-then-else来编写类似的模型。我们有蒙特卡洛·马尔科夫链,支持向量机,神经网络,潜在变量分析,...请不要忽视自己可用的建模工具所提供的财富,将自己抛在100年前。
评论
我很惊讶这个问题很少受到关注。数值分析和建模是if-else机器的核心。但是,如果应用程序必须严格遵守规则,则可能会容忍误报。 (想想银行业务)
–阿伦·何塞(Arun Jose)
15年10月15日在17:50
#6 楼
规则引擎可能会有所帮助,因为如果有那么多的if / then规则,将它们全部放在程序外部的某个位置可能会很有帮助,用户可以在无需编辑编程语言的情况下对其进行编辑。此外,可视化工具可能可用。您还可以查看逻辑编程解决方案(例如Prolog)。您可以快速修改if / then语句的列表,并进行诸如查看是否输入的任何组合都会导致某些结果之类的事情等。在一阶谓词逻辑中,它可能比过程代码(或面向对象的代码)。
#7 楼
我突然意识到:您需要使用决策学习树(ID3算法)。
很可能有人用您的语言实现了它。如果没有,您可以移植现有的库
评论
遵循上面给出的DSL思想。尝试弄清楚如何将问题抽象为某种形式的符号代数,然后加以实现。
– Zachary K
2011年8月26日上午10:13
#8 楼
这更多是社区Wiki的答案,汇总了其他答案建议的各种建模工具,我只是添加了资源的其他链接。我认为不需要重新声明您应该对数千条硬编码的if / else语句使用不同的方法。
DSL编程(特定于域的语言)
Markov模型/ Markov决策过程
Renet / Rete算法
专家系统
Matlab,(维基百科)
R
#9 楼
每个大型应用程序都包含数千个if-then-else
语句,这还不算其他流控制,尽管这些应用程序很复杂,但它们仍在调试和维护中。此外,语句的数量也不会使流变得不可预测。异步编程可以。如果您同步使用确定性算法,则每次都会有100%可预测的行为。
您可能应该更好地解释您打算在Stack Overflow或Code Review上做什么,以便人们可以提出建议您可以使用的精确重构技术。您可能还想问一些更精确的问题,例如“如何避免嵌套过多的
if
语句<给出一段代码>”。评论
大多数应用具有2-3级嵌套和1行条件。如果问题需要决策树向下嵌套50个级别,并且许多条件都是30个或更多变量的逻辑复合,那该怎么办?
– SF。
2011年8月26日在7:52
尽管“每个大型应用程序...”都是正确的,但很显然,OP所谈论的是条件表达式的长序列,这些条件表达式本质上构成了模型中的规则。大量嵌套的if语句充其量很快很快就变得笨拙,因此需要一种更好的方法。
–卡莱布
2011年8月26日15:15
@Caleb:您说得对,现在很清楚,问题的开头有一个确切的例子。我写答案时还没有编辑问题。这解释了我和同时发布的其他两个答案的实际不一致。
– Arseni Mourzenko
11年8月26日在16:43
#10 楼
通过精心设计使您的应用程序可管理。通过将各种业务逻辑划分为单独的类/模块来设计应用程序。编写单元测试,分别测试这些类/模块。这至关重要,将帮助您确保按预期实现业务逻辑。#11 楼
可能不会有一种单一的方法来解决问题,但是,如果您尝试分离出发现大量的if语句并应用解决方案的不同区域,则可以逐个管理它的复杂性解决每个较小的问题。请参阅诸如“重构”中讨论的规则之类的技术,以将大型条件分解为可管理的块-例如,具有公共接口的多个类可以替换case语句。
早退也是一个很大的帮助。如果有错误条件,请通过引发异常或返回而不是让它们嵌套来使这些错误在函数的开头消失。
如果将条件分解为谓词函数,则可能更容易跟踪它们。另外,如果可以将它们转换为标准格式,则可以将其转换为动态构建的数据结构,而不是采用硬编码的数据结构。
#12 楼
我建议您使用规则引擎。对于Java,jBPM或Oracle BPM可能会有用。规则引擎基本上允许您通过XML配置应用程序。
评论
+1我最近一直在使用Drools和Mvel作为表达规则的语言,而这正是您所需要的。尽管它非常快。
–贾琳
2011年8月26日下午5:14
流口水是一个不错的选择。我个人现在正在使用Oracle BPM。还有Feugo。提供了许多开放源代码和专有工具。
–Sid
11年8月26日在20:15
#13 楼
无论是用“如果-那么”程序代码还是为业务应用程序设计的众多规则解决方案来描述,“规则”都无法很好地解决该问题。机器学习提供了许多对这种情况进行建模的机制。从根本上讲,人们必须制定一些方案来对影响因素(例如太阳,风,食物来源,突发事件等)进行离散表示。 “系统”(即牧场中的奶牛)。尽管人们误以为可以创建一种真正有价值的功能表示形式,而不是离散的,但现实世界(包括人类神经系统)中没有计算机基于真实价值或基于真实价值进行计算。
一旦有了相关因素的数值表示,就可以构建几个数学模型中的任何一个。我建议一个二部图,其中一组节点代表奶牛,另一组节点代表牧场的某些单位面积。在任何情况下,一头奶牛都会占据一定面积的牧场。对于每头母牛,便存在与当前和所有其他牧场单位相关的效用值。如果模型以奶牛寻求优化(无论对奶牛意味着什么)为前提,其牧场单位的效用值,则奶牛将逐个单位努力优化。
细胞自动化对于执行模型效果很好。真正有价值的数学世界中激发牛运动的基础数学是场梯度模型。奶牛从感知到的实用价值较低的位置移动到感知到的实用价值较高的位置。
如果将环境变化注入系统,那么它就不会移动到稳定状态的奶牛定位解决方案。它也将成为可以应用博弈论各方面的模型;但这并不一定会增加这种情况。
该模型的优点是,在模型运行时,通过在二等图中减去“母牛”单元格并将其添加,可以轻松地屠宰母牛或获得新母牛。
#14 楼
我认为您不应定义太多if-else语句。从我的角度来看,您的问题有多个组成部分:它应该是异步的或多线程的,因为您有许多个性不同,配置不同的母牛。每头母牛问自己下一步要走什么方向。在我看来,同步代码对于解决此问题是一个糟糕的工具。
决策树的配置不断变化。它取决于实际母牛的位置,天气,时间,地形等。除了构建复杂的if-else树以外,我认为我们应该将问题减少到风向或方向-权重函数:
图1-方向-一些规则的权重函数
奶牛应始终朝总重量最大的方向行驶。因此,您可以为每头奶牛添加一套规则(具有不同的方向-权重函数),而不是构建较大的决策树,并在每次询问方向时简单地处理结果。您可以通过每次位置更改或时间的流逝来重新配置这些规则,或者可以将这些详细信息作为参数添加,每个规则都应得到。这是一个实施决策。获得方向的最简单方法是,以0°到1°的步长添加一个简单的回路(从0°到360°)。之后,您可以计算每个360度方向的总权重,并通过max()函数运行以获得正确的方向。
您不一定需要神经网络才能执行此操作,每个规则只有一类,奶牛可能是一类,可能是地形等一类……而场景是一类(例如3头规则不同的母牛和1个特定地形)。
图2 -Cow应用程序异步决策节点和连接
红色表示消息传递方向-通过规则的权重图
蓝色表示决策后的方向和位置更新
绿色表示输入方向和位置更新后更新
用黑色表示输入信息
注意:您可能需要一个消息传递框架来实现类似的内容
因此,如果让学习牛变得不成问题,您就不必不需要神经网络或遗传算法。我不是AI专家,但是我想如果您想让母牛适应真实的母牛,那么您可以简单地通过遗传算法和适当的规则来做到。如果我了解得很好,则需要使用随机规则设置的牛群。之后,您可以将真实奶牛的行为与模型种群的行为进行比较,并保持10%的牛逼近真实牛。之后,您可以根据保留的10%向奶牛工厂添加新的规则配置约束,并向种群中添加新的随机奶牛,依此类推,直到获得行为与真实奶牛一样的模型奶牛...
#15 楼
我要补充的是,如果您确实有成千上万个IF ... THEN规则,则可能会被过度指定。值得一提的是,我参加过的神经网络建模讲座通常以说明“一组简单的规则”如何产生相当复杂且合理的现实匹配行为(在这种情况下为实际的神经元行为)开始。那么,您确定需要成千上万的条件吗?我的意思是,除了天气,食物来源位置,突发事件,放牧和地形等4-5个方面,您真的还会有更多变量吗?当然,如果您尝试组合这些条件进行所有可能的排列,那么您很容易拥有成千上万的规则,但这不是正确的方法。也许是一种模糊逻辑风格的方法,其中各种因素对每头母牛的位置产生偏见,再结合到总体决策上,这将使您可以用更少的规则来做到这一点。我也同意其他所有人的观点,规则集应与一般代码流分开,以便您可以轻松调整它而无需更改程序。您甚至可以提出竞争规则集,并查看它们如何与真实的奶牛运动数据进行对比。听起来很有趣。
#16 楼
已经提到了专家系统,这是AI的一个领域。为了进一步扩展这些内容,阅读推理引擎可能会对此有所帮助。使用Google搜索可能会更有用-编写DSL很容易,您可以使用诸如Gold Parser之类的解析器轻松地做到这一点。困难的部分来自建立决策树并有效地执行决策。许多医疗系统已经在使用这些引擎,例如英国的NHS Direct网站。
如果您是.NET'er,那么Infer.NET可能对您有用。
#17 楼
自从您观察母牛的运动以来,它们就被卡在360度方向上(母牛不能飞翔。)您的行进速度也很高。可以将其定义为向量。现在如何处理太阳位置,山坡,嘈杂的噪音?
每个度数都将是表示希望朝那个方向前进的变量。假设一条小树枝以90度的角度向奶牛的右边靠拢(假设奶牛的脸朝0度倾斜)。向右走的欲望将下降,向右走的欲望270(左)将上升。经历所有刺激,增加或减少它们对奶牛向某个方向行驶的渴望的影响。一旦施加了所有刺激,母牛将朝着最高欲望的方向前进。
您还可以应用渐变,因此刺激不必是二进制的。例如,小山不是在一个方向上笔直。母牛可能是在山谷中或在山上的道路上,其平坦的笔直向前,斜度为45 *,斜度为90 *。在180 *陡峭的山坡上。
然后您可以调整事件的权重及其影响的方向。而不是ifs的列表,您有一个测试来寻找最大值。另外,当您想添加刺激时,只需在测试前应用刺激即可,而不必处理越来越多的复杂性。
然后说母牛可以向任何360度方向移动让我们将其分解为36个方向每个角度为10度
然后说母牛可以沿任何360度方向前进,只需要将其分解为36个方向即可。每个都是10度。取决于您需要的具体程度。
#18 楼
使用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年9月16日在21:44
因为建议“使用OOP。请程序员帮助”。与提供“拨打更多电话!”的建议一样值得当被问到“如何使我的销售额翻两番?”。这不是严格错误,但也无济于事。
– JensG
2014年11月16日12:14
我拒绝了,因为这是一个错误的答案。技术上您的答案与OOP无关。名为COW_METHODS的类似乎不过是松散相关方法的集合而已。关注点分离在哪里?与此问题相关,这如何帮助申请者?
–oɔɯǝɹ
15年1月30日在19:08
评论
您需要看一下DSL编程:en.wikipedia.org/wiki/Domain-specific_language此外,您还可以创建一些数据驱动的元规则引擎。例如,您可以根据数据生成模型(例如,数据挖掘KDD)谷歌的“专家系统”和“网”;祝你好运。
将硬编码的if / then语句从源代码中移到驱动模拟的外部数据中。
我会在文本文件中绑定一些值,然后使用循环遍历包含名称的HashMap。
David-关于程序员的问题,当发布超过15个答案时,将转换为CW。我们无法控制谁发布第16个答案。