制約を使用して Sicstus Prolog で書かれたプログラムがあります。私の目標は、labeling/2 およびその他の方法を使用して、変数のランダムなインスタンス化を取得することです。
例:
X #> 2, Y #= 2*X, Z #<10
私が使用する場合
List = [X,Y,Z],
labeling([], List)
得られる最初の結果は、X = Y = Z = 0 です。X、Y、Z の値のランダムなセットを返す最良の方法はどのように考えられますか?
制約を使用して Sicstus Prolog で書かれたプログラムがあります。私の目標は、labeling/2 およびその他の方法を使用して、変数のランダムなインスタンス化を取得することです。
例:
X #> 2, Y #= 2*X, Z #<10
私が使用する場合
List = [X,Y,Z],
labeling([], List)
得られる最初の結果は、X = Y = Z = 0 です。X、Y、Z の値のランダムなセットを返す最良の方法はどのように考えられますか?
最近の SICStus バージョンのラベリング オプションについてはよくわかりませんが、SWI-Prolog の library(clpfd) には、オプション random_variable(Seed) と random_value(Seed) があり、たとえば labeling([random_variable (10),random_value(10)], リスト)。SICStus の作成者に同様のオプションを統合してもらうことはできますか?
sicstus では、これは変数/値のカスタム選択で行われます。
あなたの場合、次のようにします。
labeling([value(mySelValores)], List)
mySelValores(Var, _Rest, BB, BB1) :-
fd_set(Var, Set),
select_best_value(Set, Value),
(
first_bound(BB, BB1), Var #= Value
;
later_bound(BB, BB1), Var #\= Value
).
select_best_value(Set, BestValue):-
fdset_to_list(Set, Lista),
length(Lista, Len),
random(0, Len, RandomIndex),
nth0(RandomIndex, Lista, BestValue).
https://sicstus.sics.se/sicstus/docs/4.0.4/html/sicstus/Enumeration-Predicates.htmlの value(Enum) を参照してください。
それが役に立てば幸い ;)
all_different([X,Y,Z]) を使用して異なる値を取得できますが、Sicstus でランダム シードを操作するのは難しい場合があり、シードを変更する関数を定義するか、ランダム関数を再度開始する必要がある場合があります。以下をチェックしてください www.sics.se/sicstus/docs/3.7.1/html/sicstus_23.html
sys_random Prolog フラグを介してアクセスおよび変更できるナレッジ ベースから暗黙的に乱数ジェネレーターを取得する CLP(FD) に関連する新しい述語 random_labeling/1 のために、Jekejeke Prolog を選択しました。
Jekejeke Prolog 3, Runtime Library 1.3.4
(c) 1985-2019, XLOG Technologies GmbH, Switzerland
?- use_module(library(finite/clpfd)).
% 20 consults and 0 unloads in 944 ms.
Yes
?- use_module(library(basic/random)).
% 0 consults and 0 unloads in 0 ms.
Yes
?- random_new(111,R), set_prolog_flag(sys_random,R),
X in 0..5, Y #= X*X, random_label([X,Y]),
write(X-Y), nl, fail; true.
4-16
3-9
5-25
1-1
2-4
0-0
Yes
?- random_new(111,R), set_prolog_flag(sys_random,R),
X in 0..5, Y #= X*X, random_label([X,Y]),
write(X-Y), nl, fail; true.
4-16
3-9
5-25
1-1
2-4
0-0
さらに述語 random_labeling/2 を計画しています。ただし、シードは必要ありませんが、代わりに Java java.util.Random インスタンスが必要です。これは種よりも汎用性があります。しかし、API を labeling/2 に変更し、いくつかのオプションを変更するのが最善の方法だと思います。
編集 29.12.2018: indomain/2 を採用するのは良い考えだと思うので、メモを取ります。現在、random_indomain/1 を実装しており、これから random_label/1 を実装しました。こちらもご覧ください:
indomain/2 from ECLiPSe Prolog random: ランダムな順序で列挙を試みます。バックトラックすると、以前にテストされた値が削除されます。このメソッドは random/1 を使用して乱数を作成し、前にシード/1 を使用して結果を再現可能にします。 http://eclipseclp.org/doc/bips/lib/gfd_search/indomain-2.html