0

私はこのコードを使用して複数の順列を生成しようとしています:

:- use_module(library(clpfd)).

p(N, Indexes) :-
    M in 1..N,
    M #=< N,
    length(Indexes, M),
    Indexes ins 1..N.

それは私にすべての結果を返しますが、最終的にはクラッシュしますERROR: Out of global stack

4

3 に答える 3

5

コードで何が起こるかというと、リストの長さはを呼び出すことによって暗黙的に設定されlength/2ます。これは、長さ0のリストから始まります。これはM0にバインドされ、制約がウェイクアップされM in 1..Nて失敗します。次に、成功した長さ1​​のリストを返し、次に再び成功した長さ2のリストをバックトラックします。その後、さらにバックトラックするlength/2と、リストはどんどん長くなりますがM in 1..N、リストが大きくなりすぎてメモリが不足するまで、ウェイクアップは常に失敗します。

あなたがする必要があるのはlength/2、例えば、交換することによって、コールの内側ではなく、コールの前に選択ポイントを配置することです

M #=< N,

(とにかく冗長な制約です)

indomain(M),

これはあなたに与えます:

[debug] [1]  ?- p(2,I).
I = [_G3025],
_G3025 in 1..2 ;
I = [_G3102, _G3105],
_G3102 in 1..2,
_G3105 in 1..2.

[debug] [1]  ?- 
于 2012-03-05T07:04:13.713 に答える
3

複数の順列が何を意味するのかは私にはわかりません。しかし、おそらくあなたのプログラムは制約から始まりbetween/3、それから制約を含むでしょうall_different/1

p(N, Indices) :-
    between(1,N,M), % or maybe rather between(0,N,M).
    length(Indices, M),
    Indices ins 1..N,
    all_different(Indices).

次に、を使用labeling/2して実際のソリューションを生成します。

于 2012-03-05T17:34:15.970 に答える
1

twintererはすでに質問に答えているので、(適切な)順列を取得するためのより簡単な方法を追加するだけです(役に立つかもしれませんか?):

permutations_n(N, P) :-
  numlist(1, N, L),
  permutation(L, P).

テスト:

?- permutations_n(3, X).
X = [1, 2, 3] ;
X = [1, 3, 2] ;
X = [2, 1, 3] ;
X = [2, 3, 1] ;
X = [3, 1, 2] ;
X = [3, 2, 1] ;
于 2012-03-05T10:29:09.117 に答える