2011-04-05 52 views
3

我现在只是拿起Prolog,所以我不熟悉做大多数事情的正常方式。如何从SWI-Prolog中的某个查询生成最大结果的列表中找到输入?

基本上我有一个规则,从输入给出的值:

ScoreFromInput(Input, Score) :- ... 

和我有投入,这只是数字的列表。我很难找出如何找到产生最大分数的输入。

这就是我现在所拥有的,但我认为这无限递归:

bestInput(BestInput) :- 
    %#Bind the list of valid inputs 
    legalInputs(ValidInputs), 
    %# -1000 is a dummy score, it should get replaced on the first call to bestInputHelper 
    bestInputHelper(ValidInputs,-1000,BestInput). 

%#I think this rule should work if the first input in the list is not the best one 
bestInputHelper([Input|RestOfInputs],BestScore,BestInput):- 
    bestInputHelper(RestOfInputs,RestBestScore,BestInput), 
    ScoreFromInput(Input,BestScore), 
    RestBestScore > BestScore. 

%#And this one if it is the best input 
bestInputHelper([Input|RestOfInputs],BestScore,Input):- 
    bestInputHelper(RestOfInputs,RestBestScore,_RestBestInput), 
    ScoreFromInput(Input,BestScore), 
    RestBestScore =< BestScore. 

这是我到目前为止,但我想有这样做的一个更直接的方式。任何帮助表示赞赏!谢谢!

+0

有关Prolog命名的一件事是以小写字母(大写或下划线开始变量名称)开始谓词。所以我在我的答案中将ScoreFromInput更改为scoreFromInput。 – hardmath 2011-04-05 15:00:04

+0

@hardmath:啊,是的,谢谢你指出。在我的实际计划中,情况就是这样。我只是在这里将事物转换为“输入”和“得分”,以便他们的目的对不熟悉我的计划的人很清楚,我想我错过了这一点。 – 2011-04-05 18:03:21

回答

2

一个简单的方法来说明它是一个输入是最好的,如果没有更好的输入:

best_input(Best) :- 
    legal_inputs(Inputs), 
    member(Best, Inputs), 
    input_score(Best, Score), 
    \+ (member(Better, Inputs), input_score(Better, S), S > Score). 

要看到什么是错用自己的代码,尝试例如SWI-Prolog的的图形追踪:

?- gtrace, best_input(Best). 

而please_use_readable_names inSteadOfUnreadableOnes。

3

尽管克里斯不熟悉Prolog,他所概括的方法可能是一种更有效的方式,以比mat最高的分数来找到输入。而不是做二次比较,像克里斯这样的方法可能会线性扫描可能的输入。

这里maxScoreOfList/3将返回最佳项目Z和有效输入列表的最佳分数B作为第三个参数。谓词将在空列表上失败。需要

maxScoreOfList(Z,B,[H|T]) :- 
    scoreFromInput(H,S), 
    maxScoreOfListAux(Z,B,H,S,T). 

A“辅助者”的功能如下,其示出了加入一些额外的参数,以便达到输入列表的末尾时的“特技”时,输出Z和B可被结合到找到“迄今为止”的最佳项目和分数:

maxScoreOfListAux(Z,B,Z,B,[ ]). 
maxScoreOfListAux(Z,B,X,S,[H|T]) :- 
    scoreFromInput(H,Q), 
    ( S >= Q 
    -> (Y = X, R = S) 
    ; (Y = H, R = Q) 
    ), 
    maxScoreOfListAux(Z,B,Y,R,T). 
+0

啊,有趣的做事方式!感谢您的替代方法。幸运的是,我的程序处理的是足够小的二次算法输入(最大24),但我可以肯定地看到这对于更大的输入更有用。另外,我想这是做我的代码要做的正确方法。谢谢! – 2011-04-05 18:08:59

相关问题