2016-04-23 68 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