使用CLP(FD)约束两个列表以总共N个连续元素开始

时间:2016-12-15 14:32:24

标签: prolog clpfd

我正在尝试使用CLP(FD)将两个列表约束为import numpy as np import matplotlib.pyplot as plt L = 20 # one side of lattice N = L*L # number of sites in the lattice xs = np.zeros((L, L), float) for n in range(100): for i in range(L): for j in range(L): xs[i,j] = np.random.uniform(0.1, 0.9) plt.imshow(xs) plt.colorbar() plt.savefig('temp.png') 个连续元素(N)。以下是一个示例:让EL1为两个大小为6的列表,这些元素属于域L2[0, 1]和{{1}然后,谓词E = 1将提供以下可能的解决方案:

N = 3

对于大小为3的列表,可接受以下内容:

constraint(+L1, +L2, +N)

我最终想把它推广到任意数量的列表和域,但这是我能想到的最小的等价问题。

到目前为止我的(失败)尝试:

L1 = [1, 1, 1, 0, _, _], L2 = [0, _, _, _, _, _];
L1 = [1, 1, 0, _, _, _], L2 = [1, 0, _, _, _, _];
L1 = [1, 0, _, _, _, _], L2 = [1, 1, 0, _, _, _];
L1 = [0, _, _, _, _, _], L2 = [1, 1, 1, 0, _, _].

虽然它有效,但请注意我通过回溯生成解决方案,而不是利用CLP(FD)来执行脏工作。我试图弄清楚如何实现这一目标,而且我已经在查看像L1 = [1, 1, 1], L2 = [0, _, _]; L1 = [1, 1, 0], L2 = [1, 0, _]; L1 = [1, 0, _], L2 = [1, 1, 0]; L1 = [0, _, _], L2 = [1, 1, 1]. 这样的谓词,以及像:- use_module(library(clpfd)). constseq([], _, 0). constseq([L|_], A, 0) :- L #\= A. constseq([A|Ls], A, N) :- N1 #= N - 1, constseq(Ls, A, N1). constraint(L1, L2, N) :- SL1 + SL2 #= N, constseq(L1, 1, SL1), constseq(L2, 1, SL2). main(L1, L2) :- length(L1, 6), length(L2, 6), constraint(L1, L2, 3). 这样的怪物,但是我内心的某些东西告诉我必须有一个更简单的解决方案...

2 个答案:

答案 0 :(得分:3)

exactly/3的SICStus link-to-source启发,这是我的最新尝试:

constseq_(_, [], _, 0).
constseq_(X, [Y|L], F, N) :-
  X #= Y #/\ F #<=> B,
  N #= M+B,
  constseq_(X, L, B, M).

constseq(L, E, N) :-
  constseq_(E, L, 1, N).

答案 1 :(得分:0)

我按如下方式编写(使用ECLiPSe library(ic)):

:- lib(ic).
:- lib(ic_global).

constraint(Xs, Ys, N) :-
    Xs #:: 0..1,
    Ys #:: 0..1,
    sum(Xs) + sum(Ys) #= N,
    ordered(>=, Xs),
    ordered(>=, Ys).

给出了所需的解决方案:

?- length(Xs,6), length(Ys,6), constraint(Xs,Ys,3), labeling(Xs), labeling(Ys).
Xs = [0, 0, 0, 0, 0, 0]
Ys = [1, 1, 1, 0, 0, 0]
Yes (0.00s cpu, solution 1, maybe more) ? ;
Xs = [1, 0, 0, 0, 0, 0]
Ys = [1, 1, 0, 0, 0, 0]
Yes (0.00s cpu, solution 2, maybe more) ? ;
Xs = [1, 1, 0, 0, 0, 0]
Ys = [1, 0, 0, 0, 0, 0]
Yes (0.00s cpu, solution 3, maybe more) ? ;
Xs = [1, 1, 1, 0, 0, 0]
Ys = [0, 0, 0, 0, 0, 0]
Yes (0.00s cpu, solution 4)