Prolog 在约束存在和不存在的情况下生成随机值

Prolog 在约束存在和不存在的情况下生成随机值,prolog,clpfd,clpb,Prolog,Clpfd,Clpb,我有以下资料: :-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),One

我有以下资料:

:-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\u conindexes\u conrandomvector/3
用于生成1和0的随机向量,其中conindexes位置的元素为1s

 ?-length_conindexes_conrandomvector(4,[0,1],R).
 R = [1, 1, 0, 1].
length\u conindexes\u notconrandomvector/3
用于生成一个随机向量,其中并非所有conindexes都是一个

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

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

在SWI Prolog中,我会使用CLP(B)约束来完成所有这些

例如,1:

注意,我还将用于获取所需元素的O(N2)方法转换为O(N×logn)方法

查询示例:

?- length_conindices_notconrandomvector(4, [0,1], Rs). Rs = [X1, X2, X3, X4], sat(1#X1*X2). CLP(B)的
random_labeling/2
的实现方式是,每个解决方案都是相等的



1我当然假设你有
:-使用你的
~/.swiplrc

中已有的模块(库(clpfd))。
要使这些关系有意义,请添加一个seed参数。什么是有意义的?如果你没有添加seed,你的定义就不是一个关系。再次感谢你给出了一个很好的答案。SWI Prolog的CLP(B)当涉及许多变量时,通常不能很好地进行缩放,但在这种情况下,我们很幸运:您需要的公式有一个非常小的BDD,因此可以很好地进行缩放。通过一点实践,您很快就能判断CLP(B)何时适用,何时使用CLP(FD)或其他方法更好。在您之前发布的一些任务中,基于其他技术的SAT解算器可能比基于BDD的CLP(B)系统运行得更好。在我看来,关键是要很好地掌握可用于不同任务的不同技术。 ?- length_conindices_notconrandomvector(4, [0,1], Rs). Rs = [X1, X2, X3, X4], sat(1#X1*X2). ?- length_conindices_notconrandomvector(4, [0,1], Rs), length(_, Seed), random_labeling(Seed, Rs). Rs = [0, 1, 1, 1], Seed = 0 ; Rs = [1, 0, 0, 1], Seed = 1 ; Rs = [1, 0, 1, 1], Seed = 2 ; Rs = [1, 0, 0, 1], Seed = 3 .