【问题标题】:Finding the maximum sublist in Prolog在 Prolog 中查找最大子列表
【发布时间】:2015-02-24 20:21:30
【问题描述】:

我是 Prolog 的新手,正在尝试解决 maximum subarray problem 的实例。

我有以下相当优雅的 C++ 代码:

int maxSubArray(vector<int> List)
{
    int maxsofar = 0;
    int maxendinghere = 0;
    for (int i = 0; i < List.size(); i++)
    {
        maxendinghere = max(maxendinghere+List[i], 0);
        maxsofar = max(maxsofar, maxendinghere);
    }
    return maxsofar;
}

这是我的 Prolog 代码:

max(X,X,X).
max(X,Y,X) :- X>Y.
max(X,Y,Y) :- X<Y. %define max function

prev(L,T,H) :-
   reverse(L,[H|T1]),
   reverse(T,T1).  %split L to H(last element) and T(the remaining list)

f([],0,0).
f(L,M,N) :-
   f(L1,M1,N1),
   prev(L,L1,E),
   max(M1,N,M),
   max(K,0,N), 
   K is N1+E.

我尝试从f(L,M,N) 中获取最大和,其中L 是列表,M 是结果(最大和,也像 C++ 代码中的变量“maxsofar”)我想得到,@ 987654327@ 是 C++ 代码中作为“maxendinghere”的中间变量。我想从以前的列表L1 中得到L 的答案,变量的关系和C++ 代码一样。

但是,以下查询不起作用:

?- f([1,2,3],X,Y).
is/2: Arguments are not sufficiently instantiated

我不知道问题出在哪里。

【问题讨论】:

  • 您对f(L1, M1, N1) 的查询发生在L1 未实例化的情况下。看起来可能是逻辑错误或错字。这最终导致K is N1+E 被执行而N1E 中的一个或两个没有值,这会产生您看到的错误。另一方面,您可以用append 很好地定义prevprev(L, T, H) :- append(T, [H], L).
  • 您好,可以推断出prev(L,L1,E)L1E的功能。我还是一头雾水。
  • 哦,我明白了。这是顺序的问题!
  • 是的,Prolog 在子句中按顺序运行查询,并根据运算符优先级。
  • 我知道“优雅”是主观的,但是为什么你的 C++ 代码会忽略 List[0] 呢?

标签: prolog kadanes-algorithm


【解决方案1】:

这个答案显示了 的 Prolog 端口 基于:

:- use_module(library(clpfd))。

我们这样定义zs_maxmum/2

zs_maxmum(Zs, MSF) :-
   zs_maxmum_(Zs, 0,_, 0,MSF).

zs_maxmum_([], _,_, MSF,MSF).
zs_maxmum_([Z|Zs], MEH0,MEH, MSF0,MSF) :-
   max(0,MEH0+Z)  #= MEH1,
   max(MSF0,MEH1) #= MSF1,
   zs_maxmum_(Zs, MEH1,MEH, MSF1,MSF).

示例查询:

?- zs_maxmum([-2,1,-3,4,-1,2,1,-5,4], Max).
Max = 6.

?- zs_maxmum([-2,3,4,-5,8,-12,100,-101,7], Max).
Max = 100.

几点说明:

  • 我们实际上并不是对数组进行操作,而是对列表进行操作。
  • 我们接受任意子列表,包括[]。目标zs_maxmum([-2,-3,-4], 0) 成功。

【讨论】:

  • 可以从将其推广到任意值中受益,不一定从 0 开始。
猜你喜欢
  • 2013-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-19
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 2023-01-02
相关资源
最近更新 更多