你好,我有一个这样的清单:
[[3,[a,b,c,d]],[2,[a,b,d]],[5,[d,e,f]]]
列表清单...... 我想在内部列表中找到最小数量 在这种情况下,我想返回D = 2和L = [a,b,d]
我试过这段代码:
minway([[N|L]],N,L).
minway([[M|L1]|L2],D,_):- M<D, minway(L2,M,L1).
minway([[M|_]|L2],D,L):- M>=D, minway(L2,D,L).
但我收到了错误:
</2: Arguments are not sufficiently instantiated
Exception: (8) minway([[3,[a,b,c,d]],[2,[a,b,d]],[5,[d,e,f]]], _G7777, _G7778) ?
creep
这句话:
minway([[3,[a,b,c,d]],[2,[a,b,d]],[5,[d,e,f]]],D,L).
结果需要:
D=2.
L=[a,b,d].
我的问题在哪里? 以及如何解决它?
tnx很多
答案 0 :(得分:2)
首先,切换到更好的数据表示:而不是[Key,Value]
,使用Key-Value
!
然后,基于定义minway_/3
iwhen/2
,
ground/1
,
keysort/2
,和
member/2
,如下:
minway_(Lss, N, Ls) :-
iwhen(ground(Lss), (keysort(Lss,Ess), Ess = [N-_|_], member(N-Ls, Ess))).
使用SICStus Prolog 4.5.0的示例查询:
| ?- minway_([3-[a,b,c,d],2-[a,b,d],5-[d,e,f],2-[x,t,y]], N, Ls).
N = 2, Ls = [a,b,d] ? ;
N = 2, Ls = [x,t,y] ? ;
no
答案 1 :(得分:0)
有几个基本问题。
一个问题在于您的列表表示。您的谓词似乎假设,例如,[3, [a,b,c]]
表示为[3 | [a,b,c]]
,但事实并非如此。列表[3 | [a,b,c]]
是以3
为首的列表,[a,b,c]
为列表的其余部分或尾部。换句话说,[3 | [a,b,c]]
是[3, a, b, c]
。
所以,你的基本情况是:
minway([[N,L]], N, L).
第二个问题出在你的其他谓词条款中。 D
没有起点。换句话说,它从未给出一个值,所以你得到一个实例化错误。如果其中一个变量没有值,则无法比较N > D
。
当从头开始做最小值或最大值时,常见的方法是首先假设第一个元素是候选结果,然后如果在递归的每一步找到更好的元素,则替换它。这也意味着你需要在每次递归调用时随身携带最后一个候选者,这样就增加了额外的参数:
minway([[N,L]|T], D, R) :-
minway(T, N, L, D, R).
minway([], D, R, D, R). % At the end, so D, R is the answer
minway([[N,L]|T], Dm, Rm, D, R) :-
( N < Dm
-> minway(T, N, L, D, R) % N, L are new candidates if N < Dm
; minway(T, N, Dm, Rm, D, R) % Dm, Rm are still best candidate
).
在Prolog中,你可以稍微简化一下,因为Prolog有一个更通用的术语比较运算符,@<
,@>
等,这对于比较更复杂的术语是明智的。例如,[2, [d,e,f]] @< [3, [a,b,c]]
为真,因为2 < 3
为真。然后我们可以写:
minway([H|T], D, R) :-
minway(T, H, D, R).
minway([], [D, R], D, R).
minway([H|T], M, D, R) :-
( H @< M
-> minway(T, H, D, R)
; minway(T, M, D, R)
).
答案 2 :(得分:0)
您可以使用最小谓词来做到这一点。 Findall可能会非常有帮助。
min([X],X).
min([H|T],Min):-
min(T,TMin),
H>TMin,
Min is TMin.
min([H|T],Min):-
min(T,TMin),
H=<TMin,
Min is H.
minway(List,D,L):-
findall(Value,member([Value,_],List),VList),
min(VList,Min),
D=Min,
findall(EList,member([Min,EList],List),L).
?-minway([[3,[a,b,c,d]],[2,[a,b,d]],[5,[d,e,f]]],D,L).
D = 2,
L = [[a, b, d]]
答案 3 :(得分:0)
尝试库(汇总):
?- aggregate_all(min(X,Y),
member([X,Y], [[3,[a,b,c,d]],
[2,[a,b,d]],
[5,[d,e,f]]]),
min(D,L)).
D = 2,
L = [a, b, d].
另请参见:
可追溯谓词上的聚合运算符
https://www.swi-prolog.org/pldoc/man?section=aggregate