2016-04-23 70 views
2

我有以下生成随机值:其中约束不和不保持

:-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被用来产生一和零,其中在conindexes位置的元素中1的一个随机向量。

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

length_conindexes_notconrandomvector/3被用来产生一个随机向量,其中不是所有的conindexes的是那些。

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

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

+0

要使这种关系有意义,请添加种子参数。 – false

+1

你是什么意思? – user27815

+1

如果您不添加种子,您的定义不是关系。 – false

回答

3

在SWI-Prolog中,我会尽全力用CLP(B)约束。

例如:

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

注意,我还采取自由打开ø(N )用于取入所需的 元件成ø(方法N × log N)  one。

例子查询:

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

它始终是最好的造型分出一部分到自己的断言,我们称之为核心 关系。为了获得具体的解决方案,可以例如使用  random_labeling/2

 
?- 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 . 

CLP(B)的random_labeling/2以这样的方式实现的,每个溶液是同样 可能


我当然假设你在  ~/.swiplrc:- use_module(library(clpfd)).了。

+1

再次感谢您的回答。 – user27815

+1

当涉及多个变量时,SWI-Prolog的CLP(B)往往不能很好地扩展,但在这种情况下,我们很幸运:您需要的公式具有相当小的BDD,因此这个比例非常好。通过一些练习,您很快就能判断CLP(B)何时适用,何时使用CLP(FD)或其他方法更好。在之前发布的一些任务中,基于其他技术的SAT解算器可能比基于BDD的CLP(B)系统更好。正如我所看到的,重点是要掌握可应用于不同任务的不同技术。 – mat