生成连续数字对 - Prolog

时间:2017-02-13 23:30:00

标签: list prolog

我有一些代码可以获取7个链的给定数字和解的列表。然而,即使只有一个也需要花费大量的时间来解决(好吧,我还没有解决1个问题而且它已经有很多时间了)。我想知道是否有更好/更有效的编码方式。

这就是我所做的,没有列表中的数字“L”。 (列表看起来像这样:L= [[1,2],[2,3],...]

length(L,LEN),

interval(N1,1,LEN),
interval(N2,1,LEN),
interval(N3,1,LEN),
interval(N4,1,LEN),
interval(N5,1,LEN),
interval(N6,1,LEN),
interval(N7,1,LEN),

nth1(N1,L,A),
nth1(N2,L,B),
nth1(N3,L,C),
nth1(N4,L,D),
nth1(N5,L,E),
nth1(N6,L,F),
nth1(N7,L,G),

nth1(2,A,A2),
nth1(1,B,B1),
A2 = B1,

nth1(2,B,B2),
nth1(1,C,C1),
B2 = C1,

nth1(2,C,C2),
nth1(1,D,D1),
C2 = D1,

nth1(2,D,D2),
nth1(1,E,E1),
D2 = E1,

nth1(2,E,E2),
nth1(1,F,F1),
E2 = F1,

nth1(2,F,F2),
nth1(1,G,G1),
F2 = G1,

nth1(2,G,G2),
nth1(1,A,A1),
G2 = A1,

R = (A,B,C,D,E,F,G).

1 个答案:

答案 0 :(得分:3)

如果我理解你的意图正确,你可以写得更短

use_module(library(clpfd)).

q(L,R) :- 
  [A,B,C,D,E,F,G] ins 1 .. 7,
  R = [[A,B],[B,C],[C,D],[D,E],[E,F],[F,G],[G,A]],
  permutation(L, R),
  label([A,B,C,D,E,F,G]).

示例:

  

3? - q([[1,7],[2,3],[5,4],[3,1],[7,6],[6,5],[4,2] ],X)。
  X = [[1,7],[7,6],[6,5],[5,4],[4,2],[2,3],[3,1]] ; < / b>
  X = [[2,3],[3,1],[1,7],[7,6],[6,5],[5,4],[4,2]] ; < / b>
  X = [[5,4],[4,2],[2,3],[3,1],[1,7],[7,6],[6,5]] ; < / b>
  X = [[3,1],[1,7],[7,6],[6,5],[5,4],[4,2],[2,3]] ; < / b>
  X = [[7,6],[6,5],[5,4],[4,2],[2,3],[3,1],[1,7]] ; < / b>
  X = [[6,5],[5,4],[4,2],[2,3],[3,1],[1,7],[7,6]] ; < / b>
  X = [[4,2],[2,3],[3,1],[1,7],[7,6],[6,5],[5,4]] ; < / b>
  假。

但你的问题真的不清楚。

更新:我们可以使用

创建我们上面使用的任何长度的列表类型
vars(N, Vars):-
    length(Vars, N).

pairs(Vars, N, Pairs):-   % assuming vars(N, Vars)
    N #> 0,
    append(Vars,[A],[A|B]),   % |B| = N
    maplist( pair, Vars, B, Pairs).

pair( A, B, [A,B]).

这样q/2可以概括为

gen_q(L,R) :- 
  length( L, N),
  vars( N, Vars),
  Vars ins 1 .. N,
  pairs( Vars, N, R),
  permutation(L, R),
  label(Vars).

但是对于更大输入的计算可行性完全是另一回事。 permutation/2的蛮力可能必须用更具体的东西取而代之。

此外,所产生的N结果包含清晰的模式;在找到第一个之后,没有必要重新进入搜索以生成它们。