Cip*_*er0 6 artificial-intelligence prolog design-decisions
我不确定我到底要问的是什么.我希望能够制作一些代码,这些代码可以轻松地获取初始和最终状态以及一些规则,并确定到达那里的路径/选择.
例如,想想像星际争霸这样的游戏.要建造一个工厂,我需要建造一个军营和一个指挥中心.所以,如果我什么都没有,我想要一个工厂,我可能会说 - >指挥中心 - >军营 - >工厂.每件事都需要时间和资源,这应该在路径中加以注意和考虑.如果我想要我的工厂在5分钟,那么如果我想要它在10点那么选项会更少.
此外,引擎应该能够计算可用资源并有效地利用它们.这三座建筑物可能需要600块矿物,但是当它有200块(或者是它的成本)时,发动机应该规划指挥中心.
这最终将需要类似于5分钟的10名海军陆战队员,6:30的步兵武器升级,10分钟的30名海军陆战队员,11号工厂等等......
那么,我该如何做这样的事呢?我的第一个想法是使用一些程序性语言并从头开始做出所有决定.我可以模拟系统和分支并做出不同的选择.最终,一些选择很快就会使得以后无法达到目标(如果我建立20个供应仓库,我可能不会按时建造那个工厂.)
那么我认为不是为此设计的函数式语言?我试着写一些序言,但我一直遇到时间和距离计算等问题.而且我不确定退回"计划"的最佳方法.
我以为我可以写:
depends_on(factory, barracks)
depends_on(barracks, command_center)
builds_from(marine, barracks)
build_time(command_center, 60)
build_time(barracks, 45)
build_time(factory, 30)
minerals(command_center, 400)
...
build(X) :-
depends_on(X, Y),
build_time(X, T),
minerals(X, M),
...
Run Code Online (Sandbox Code Playgroud)
这是我感到困惑的地方.我不确定如何构造这个函数和一个查询来获得任何接近我想要的东西.我不得不以某种方式考虑在建造时间和其他可能的额外黄金路径中收集矿物的比率.如果我在10分钟内只需要1个海军陆战队员,我希望发动机能够产生很多计划,因为有很多方法可以在10分钟内结束1个海军陆战队员(可能会在很多人之后将其切断,不知道你是如何做到这一点的. ).
我正在寻找有关如何继续沿着这条路走下去或就其他选择提出建议的建议.我找不到任何比河内塔和人工智能的例子更有用的东西,所以即使是一些很好的文章解释如何使用prolog做真实的东西也会很棒.如果我能以一种有用的方式设置这些规则如何让我得到"计划"prolog想出的方法(解决查询的方法)除了写入像河内例子的所有塔一样的stdout吗?或者这是首选方式?
我的另一个问题是,我的主要代码是ruby(可能还有其他语言),与prolog通信的选项是从ruby中调用我的prolog程序,从prolog中访问虚拟文件系统,或某种数据库结构(不太可能) ).我正在使用SWI-Prolog atm,我会更好地在Ruby中以程序方式执行此操作,还是使用像prolog或haskall这样的函数式语言来构建它是否值得进行额外的集成?
如果不清楚我很抱歉,我感谢任何帮助的尝试,我会重新说出不清楚的事情.
对于首次尝试Prolog的过程语言用户,您的问题是典型且非常常见的.这很容易解决:你需要根据你世界连续状态之间的关系来思考.你的世界状态包括例如过去的时间,可用的矿物质,你已经建造的东西等.这样的状态可以用Prolog术语很容易地表示,并且可以看例如像time_minerals_buildings(10, 10000, [barracks,factory])).鉴于这种状态,您需要描述该州可能的继承状态.例如:
state_successor(State0, State) :-
State0 = time_minerals_buildings(Time0, Minerals0, Buildings0),
Time is Time0 + 1,
can_build_new_building(Buildings0, Building),
building_minerals(Building, MB),
Minerals is Minerals0 - MB,
Minerals >= 0,
State = time_minerals_buildings(Time, Minerals, Building).
Run Code Online (Sandbox Code Playgroud)
我使用显式命名约定(State0- > State)来表明我们正在谈论连续状态.你当然也可以将统一纳入条款头.示例代码纯粹是假设的,在最终的应用程序中看起来可能会有所不同.在这种情况下,我描述新状态的经过时间是旧状态的时间+ 1,新的矿物质量减少了构建所需的量Building,并且我有一个谓词can_build_new_building(Bs, B),这在新建筑物B可以假设建筑物Bs已经建成,可以建造.我认为它通常是一个非确定性的谓词,并且会在回溯时产生所有可能的答案(=可以构建的新建筑物),并且我将其作为练习来定义这样的谓词.
鉴于这样一个谓词state_successor/2,它将世界状态与其直接可能的后继者联系起来,您可以轻松定义导致所需最终状态的状态路径.在最简单的形式中,它看起来类似于描述连续状态列表的以下DCG:
states(State0) -->
( { final_state(State0) } -> []
; [State0],
{ state_successor(State0, State1) },
states(State1)
).
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用迭代深化来搜索解决方案:
?- initial_state(S0), length(Path, _), phrase(states(S0), Path).
Run Code Online (Sandbox Code Playgroud)
此外,您可以跟踪已经考虑过的状态,避免重新探索它们等.
您与所发布的示例代码混淆的原因主要是build/1没有足够的参数来描述您想要的内容.你需要至少两个论点:一个是世界的当前状态,另一个是这个给定状态的可能继承者.鉴于这种关系,您可以轻松描述您需要的其他所有内容.我希望这回答了你的问题.