【问题标题】:Generating random values where a constraint does and does not hold在约束成立和不成立的情况下生成随机值
【发布时间】:2016-04-23 12:04:30
【问题描述】:

我有以下几点:

:-use_module(library(clpfd)).

list_index_value(List,Index,Value):-
  nth0(Index,List,Value).

length_conindexes_conrandomvector(Length,Conindexs,Randomvector):-
  length(Randomvector,Length),
  same_length(Conindexs,Ones),
  maplist(=(1),Ones),
  maplist(list_index_value(Randomvector),Conindexs,Ones),
  term_variables(Randomvector,Vars),
  maplist(random_between(0,1),Vars).

length_conindexes_notconrandomvector(Length,Conindexes,Randomvector):-
  length(Randomvector,Length),
  length(Conindexes,NumberOfCons),
  same_length(Conindexes,Values),
  sum(Values,#\=,NumberOfCons),
  maplist(list_index_value(Randomvector),Conindexes,Values),
  term_variables(Randomvector,Vars),
  repeat,
  maplist(random_between(0,1),Vars).

length_conindexes_conrandomvector/3 用于生成一个由 1 和 0 组成的随机向量,其中 conindexes 位置的元素为 1。

 ?-length_conindexes_conrandomvector(4,[0,1],R).
 R = [1, 1, 0, 1].

length_conindexes_notconrandomvector/3 用于生成一个随机向量,其中并非所有的索引都是 1。

?- length_conindexes_notconrandomvector(3,[0,1,2],R).
R = [1, 0, 1] ;
R = [0, 1, 1] ;
R = [1, 1, 0] 

这我觉得我已经用repeat 命令“破解”了。做这个的最好方式是什么?如果我使用标签,那么这些值不会是随机的?如果经常违反约束,那么搜索将非常低效。最好的方法是什么?

【问题讨论】:

  • 要使此类关系有意义,请添加种子参数。
  • 有意义是什么意思?
  • 如果不添加种子,则定义不是关系。

标签: prolog clpfd clpb


【解决方案1】:

在 SWI-Prolog 中,我将使用 CLP(B) 约束来完成所有这些操作。

例如1

:- use_module(library(clpb)).

length_conindices_notconrandomvector(L, Cs, Rs):-
        L #> 0,
        LMax #= L - 1,
        numlist(0, LMax, Is),
        pairs_keys_values(Pairs, Is, _),
        list_to_assoc(Pairs, A),
        maplist(assoc_index_value(A), Cs, Vs),
        sat(~ *(Vs)),
        assoc_to_values(A, Rs).

assoc_index_value(A, I, V) :- get_assoc(I, A, V).

请注意,我还冒昧地将用于获取所需元素的 O(N2) 方法转换为 O( N×log N) 一个。

查询示例:

?- length_conindices_notconrandomvector(4, [0,1], Rs)。 Rs = [X1,X2,X3,X4], 坐(1#X1*X2)。

始终建议将建模部分分成自己的谓词,我们称之为核心关系。要获得具体的解决方案,您可以例如使用random_labeling/2

?- length_conindices_notconrandomvector(4, [0,1], Rs), 长度(_,种子), 随机标签(种子,卢比)。 Rs = [0, 1, 1, 1], 种子 = 0 ; Rs = [1, 0, 0, 1], 种子 = 1 ; Rs = [1, 0, 1, 1], 种子 = 2; Rs = [1, 0, 0, 1], 种子 = 3。

CLP(B) 的 random_labeling/2 以这样一种方式实现,即每个解决方案同样可能


1我当然假设您的~/.swiplrc 中已经有:- use_module(library(clpfd)).

【讨论】:

  • 再次感谢您的精彩回答。
  • SWI-Prolog 的 CLP(B) 在涉及许多变量时通常不能很好地扩展,但在这种情况下我们很幸运:您需要的公式有一个非常小的 BDD,所以它的扩展性很好好吧。稍加练习,你很快就能判断出 CLP(B) 何时适用,何时使用 CLP(FD) 或其他方法更好。在您之前发布的一些任务中,基于其他技术的 SAT 求解器可能比基于 BDD 的 CLP(B) 系统表现更好。在我看来,关键是要很好地掌握可用于不同任务的不同技术。
猜你喜欢
  • 2016-08-25
  • 2012-04-06
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
相关资源
最近更新 更多