2

我和一个朋友正在编写一个应该解决 CLP 问题的程序。我们想使用最小化来优化解决方案,但它不起作用,因为它一直说我们从 sum(P,#=,S) 得到的数字介于两个数字之间(例如 5..7)。我们还没有找到一种很好的方法来从中提取任何数字或以任何方式对其进行操作,因此正在寻求您的帮助。

问题似乎来自我们的 gen_var 方法,该方法说列表的每个元素必须介于 0 和 1 之间,因此有些数字显示为“0..1”,而不是正确设置。

即使我们得到像“5..7”这样的数字,是否有任何方法可以使用最小化,或者有任何方法可以操纵该数字以便我们只得到 5?S(列表中元素的总和)是我们试图最小化的。

gen_var(0, []).
gen_var(N, [X|Xs]) :-
        N > 0,
        M is N-1,
        gen_var(M, Xs),
    domain([X],0,1).

find([],_).
find([H|T],P):- match(H,P),find(T,P).

match(pri(_,L),P):-member(X,L), nth1(X,P,1).

main(N,L,P,S) :- gen_var(N,P), minimize(findsum(L,P,S),S).
findsum(L,P,S):- find(L,P), sum(P,#=,S).
4

1 回答 1

4

我稍微修改了您的代码,以适应 SWI-Prolog CLP(FD),它似乎可以工作(有点)。但我认为最小值总是0!

:- use_module(library(clpfd)).

gen_var(0, []).
gen_var(N, [X|Xs]) :-
    N > 0,
    M is N-1,
    gen_var(M, Xs),
    X in 0..1 .

find([], _).
find([H|T], P):-
    match(H, P),
    find(T, P).

match(pri(_,L),P):-
    member(X, L),
    nth1(X, P, 1).

findsum(L,P,S) :-
    find(L, P),
    sum(P, #=, S).

main(N, L, P, S) :-
    gen_var(N, P),
    findsum(L, P, S),
    labeling([min(S)], P).

这个输出样本是预期结果的正确子集吗?

?- main(3,A,B,C).
A = [],
B = [0, 0, 0],
C = 0 ;
A = [],
B = [0, 0, 1],
C = 1 ;
于 2011-09-23T21:29:07.903 回答