Prolog:随机标签

时间:2012-01-01 15:23:00

标签: prolog sicstus-prolog clpfd

我有一个使用约束在Sicstus Prolog中编写的程序。 我的目标是使用标签/ 2和其他一些方法来获得我的变量的随机实例化。

示例:

X #> 2, Y #= 2*X, Z #<10

如果我使用

List = [X,Y,Z],
labeling([], List)

获得的第一个结果是X = Y = Z = 0.您如何看待为X,Y和Z返回一组随机值的最佳方法?

4 个答案:

答案 0 :(得分:6)

我对最近的SICStus版本中的标签选项知之甚少,但是对于SWI-Prolog的库(clpfd),有选项random_variable(Seed)和random_value(Seed),你可以使用它们作为例如标签([random_variable(10),random_value(10)],List)。也许你可以让SICStus的作者整合类似的选项?

答案 1 :(得分:4)

在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中的值(枚举)。

希望它有所帮助;)

答案 2 :(得分:1)

我选择在Jekejeke Prolog中使用新的谓词random_labeling / 1 与CLP(FD)隐式地从知识库中获取随机数生成器 可以通过sys_random 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。另请参见此处:

  ECLiPSe Prolog中的

indomain / 2   random:以随机顺序尝试枚举。回溯时   先前测试的值将被删除。此方法使用random / 1来   创建随机数,在使结果可重复之前使用seed / 1。   http://eclipseclp.org/doc/bips/lib/gfd_search/indomain-2.html

答案 3 :(得分:0)

你可以用 all_different([X,Y,Z])以获得不同的值 但是,在Sicstus中使用随机种子可能会很棘手,您可能需要定义一个函数来更改种子或再次启动随机函数。 检查下面 www.sics.se/sicstus/docs/3.7.1/html/sicstus_23.html