给定两个排序列表Xs和Ys,如何确保Xs中的任何X和Ys中的任何Y之间的绝对差异至少是两个?
带有预期答案的查询示例:
?- different([1,2,4],[5,6]). % 5-4 < 2
false
?- different([1,4],[2,6]). % 2-1 < 2
false
?- different([1,2,6],[4,8]). % 4-2 >= 2 and 6-4 >= 2 and 8-6 >= 2
true
?- different([],[4]).
true我怎样才能得到这个结果?有什么想法吗?谢谢!
编辑:下面是我现在的代码:
difference([], []).
difference([_|_], []).
difference([], [_|_]).
difference(L1, L2) :-
L1 = [X1|X2],
L2 = [Y1|_],
Dif is X1-Y1,
(-1>Dif|Dif>1),
difference(X2, L2).发布于 2016-02-28 12:50:26
首先,您可以使当前的代码更整洁、更易于阅读,如下所示:
different([], []).
different([_|_], []).
different([], [_|_]).
different([X|Xs], [Y|Ys]) :-
abs(X-Y) >= 2, % Prolog evaluates arithmetic expressions for compares
different(Xs, [Y|Ys]).在本例中,您已经完成了我在注释中提到的递归的一个级别,因为它只检查第一个列表的每个元素和第二个元素的第一个元素。它忽略了第二个列表中的所有其他元素。所以你需要把它进一步分解。您可以创建一个帮助谓词,它将列表中的每个元素与单个值进行比较。然后让您的主谓词用另一个列表中的每个元素调用这个助手谓词。然后,主谓词将类似于:
different([], []).
different([], [_|_]).
different([X|Xs], L) :-
different_element(X, L),
different(Xs, L).那么助手谓词将是:
% This predicate succeeds if the first argument has the desired difference
% to each of the elements of the second argument (a list)
%
different_element(_, []).
different_element(X, [Y|Ys]) :-
abs(X-Y) >= 2,
different_element(X, Ys).发布于 2016-03-01 16:20:26
在这个答案中,我们使用clpfd实现多功能性和最优(线性)算法复杂度。
diff_to_mdist([], _, _).
diff_to_mdist([_|_], [], _).
diff_to_mdist([X|Xs], [Y|Ys], D) :-
( X #=< Y-D, diff_to_mdist(Xs, [Y|Ys], D)
; X #> Y-D, X #>= Y+D, diff_to_mdist([X|Xs], Ys, D)
).
diff_to_mdist([X0,X1|Xs], [Y0,Y1|Ys], D) :-
X0 #> Y0-D, X0 #< Y0+D,
( X0 #< Y0, X0 #=< Y0-D, X1 #>= Y0+D, diff_to_mdist([X0,X1|Xs], [Y1|Ys], D)
; X0 #> Y0, Y0 #=< X0-D, Y1 #>= X0+D, diff_to_mdist([X1|Xs], [Y0,Y1|Ys], D)
).让我们使用gnu-prolog版本1.4.4并运行类似OP建议的查询!
| ?- diff_to_mdist([1,2,4], [5,6], 2).
no
| ?- diff_to_mdist([1,4], [2,6], 2).
no
| ?- diff_to_mdist([1,2,6], [4,8], 2).
true ? ;
no
| ?- diff_to_mdist([], [4], 2).
yeshttps://stackoverflow.com/questions/35673516
复制相似问题