Пролог: Случайная маркировка - PullRequest
9 голосов
/ 01 января 2012

У меня есть программа, написанная на Sicstus Prolog с использованием ограничений.Моя цель - использовать labeling / 2 и какой-то другой метод для получения случайных экземпляров моих переменных.

Пример:

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

Если я использую

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

Первый полученный результат будет X = Y = Z = 0. Как вы думаете, это лучший способ вернуть случайный набор значений для X, Y и Z?

Ответы [ 4 ]

6 голосов
/ 01 января 2012

Я не знаю много о параметрах маркировки в последних версиях SICStus, но с библиотекой (clpfd) SWI-Prolog, есть параметры random_variable (Seed) и random_value (Seed), их можно использовать, например, с маркировкой([random_variable (10), random_value (10)], список).Может быть, вы можете заставить авторов SICStus интегрировать подобные опции?

4 голосов
/ 18 декабря 2016

В 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).

См. Значение (Enum) в https://sicstus.sics.se/sicstus/docs/4.0.4/html/sicstus/Enumeration-Predicates.html.

Надеюсь, это поможет;)

1 голос
/ 29 декабря 2018

Я выбрал в Jekejeke Prolog новый предикат random_labeling / 1 в связи с CLP (FD), который неявно берет генератор случайных чисел из базы знаний, доступ к которому можно изменить и изменить с помощью флага Prolog sys_random.

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 из пролога ECLiPSe random: Попробуйте перечисление в случайном порядке.При возврате ранее проверенное значение удаляется.Этот метод использует random / 1 для создания случайных чисел, используйте seed / 1 прежде, чтобы сделать результаты воспроизводимыми.http://eclipseclp.org/doc/bips/lib/gfd_search/indomain-2.html

0 голосов
/ 06 июля 2012

вы можете использовать all_different ([X, Y, Z]), чтобы получить разные значения, однако, работа со случайным начальным числом в Sicstus может быть сложной, и вам может потребоваться определить функцию, чтобы изменить начальное число или запустить случайную функциюснова.проверьте ниже www.sics.se/sicstus/docs/3.7.1/html/sicstus_23.html

...