Не могу свести к минимуму из CLPFD на работу - PullRequest
3 голосов
/ 23 сентября 2011

Я и друг пишем программу, которая должна решить проблему CLP. Мы хотим использовать метод минимизации для оптимизации решения, но он не будет работать, потому что он все время говорит, что число, которое мы получаем из суммы (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).

1 Ответ

4 голосов
/ 24 сентября 2011

Я немного изменил ваш код для адаптации к 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).

Является ли эта выходная выборка правильным подмножеством ожидаемого результата?

...