Prolog 程序的复杂性?

Posted

技术标签:

【中文标题】Prolog 程序的复杂性?【英文标题】:Complexity in Prolog programs? 【发布时间】:2010-12-19 03:14:55 【问题描述】:

在 Prolog 中,使用回溯来解决问题。它是一种声明性范例,而不是一种命令性范例(如 C、php 或 Python)。在这种语言中,是否值得考虑复杂性?

正如某人在this question 中指出的那样,您认为问题的自然方式似乎是 O(N^2)。

【问题讨论】:

当然,我想是的。有列表,您可以遍历它们。这是递归完成的事实并不意味着我们不能说存在 O(n) 复杂度。 【参考方案1】:

您绝对可以分析 Prolog 程序的复杂性,就像任何其他语言一样。您链接的那个特定问题可能是 O(n^2)。但并不是所有的 Prolog 程序都会有这种复杂性。例如,您可以在 Prolog 中轻松编写 SAT 求解器,而该问题是 NP-Complete。

【讨论】:

【参考方案2】:

这完全取决于问题。

例如据我所知,对数字列表求和是 O(N)。

sum([],0).
sum(List,Total) :-
   sum(List,0,Total).

sum([],Total,Total).
sum([Head|Rest],Accumulator,Total) :-
    SoFar is Head + Accumulator,
    sum(Rest,SoFar,Total).

唯一的动作是加法(“is”)和递归调用,它们的值都应该是 1。它们都将执行 ~ 列表中的每个项目一次,因此总操作应该是 ~ 2N,即 O(N)。

【讨论】:

【参考方案3】:

分析任何语言的复杂性很重要,无论是序言还是任何命令式语言。不过我可以给你一些提示来加快你的序言程序

    始终始终尝试使您的程序尾递归。这将确保您的程序不会耗尽堆栈。 尝试在您知道不需要任何进一步答案的程序中使用 cut and fail。 尝试使用累加器。 查看 CLPFD,它有助于大大减少搜索空间,从而加快您的程序。从本质上讲,它会在您的程序回溯之前消除错误的选择,并浪费时间探索这些选择。 始终先写出最佳结果规则。 (这实际上取决于问题,但通常最好的情况规则是第一位的)。

【讨论】:

以上是关于Prolog 程序的复杂性?的主要内容,如果未能解决你的问题,请参考以下文章

Linux g++ 在 C++ 中嵌入 Prolog 逻辑引擎

使用 DCG 编写简单的“消除过程”Prolog 代码

Java的嵌入式Prolog解释器/编译器

Prolog中的广度优先搜索

定义复杂的事实 - Einsteins Zebra

F# 和模糊逻辑