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用于生成 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命令“破解”了。做这个的最好方式是什么?如果我使用标签,那么这些值不会是随机的?如果经常违反约束,那么搜索将非常低效。做这个的最好方式是什么?

4

1 回答 1

3

在 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 (N 2 ) 方法转换为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我当然假设你:- use_module(library(clpfd)).已经在你的 ~/.swiplrc.

于 2016-04-23T17:00:29.063 回答