如果我有以下内容:
a(X) :- X = 1; X = 2; X = 3; X = 4.
我可以按确定性顺序产生解决方案:
?- a(X).
X = 1 ;
X = 2 ;
X = 3 ;
X = 4.
是否有任何方法要求系统以非确定性的随机顺序生产解决方案?例如:
?- a(X).
X = 4 ;
X = 1 ;
X = 3 ;
X = 2.
我知道我可以找到所有解决方案,然后随机选择一个解决方案(findall(X, a(X), Y), random_member(Z, Y).
),但这在我的情况下太贵了。
可能更清晰的示例:
p(X,Y,Z) :-
(X = a; X = b; X = c; X = d), % (D1)
(Y = a; Y = b; Y = c), % (D2)
(Z = a; Z = b; Z = c; Z = d). % (D3)
确定性时,使用?- p(X,Y,Z).
生成解决方案X = d, Y = c, Z = d
将始终通过47个以前的解决方案(4 * 3 * 4 = 48
)。但是,如果以非确定性顺序选择析取,则系统可以在D1处选择X = d
,D2,Y = c
,Z = d
在D3处将其作为第一个解决方案。
这是用于约束AI生成的内容的,因此现实世界中有更多变量。
从您在评论中所说的话,我的印象是,对于您的使用而言,一个更重要的问题是:
解决方案可以是以随机顺序创建吗?
(这是因为您说您不能全部创建它们,然后选择一个随机 一个。)
to 创建以不同的顺序,鲍里斯(Boris)暗示了一种很好的方法:只需重新排序 dispunctions !
例如,在您显示的情况下:
P(X,Y,Z): - (x = a; x = b; x = c; x = d),%(d1) (y = a; y = b; y = c),%(d2) (z = a; z = b; z = c; z = d)。%(D3)
您可以(自动)通过交换订单(例如:(X = c ; X = b ; etc.)
)以及这些摘要中的每个摘要可以以不同的 顺序产生解决方案(
但是,首先将其重写为等价版本可能会更容易:
P(X,Y,Z): - 成员(x,[a,b,c,d]), 成员(y,[a,b,c]), 成员(z,[a,b,c,d])。
以这种方式,更容易 shuffle 列表并使用随机列表生成解决方案。
例如,您可以将其更改为:
P(X,Y,Z): - Random_member (x,[a,b,c,d]), random_member (y,[a,b,c]), Random_member (z,[a,b,c,d])。 Random_member(X,LS0): - Random_permunt(LS0,LS), 成员(x,ls)。
现在,您将得到类似:
的答案? - p(x,y,z)。x = d,y = z,z = b;x = z,z = d,y = b;x = d,y = b,Z = C;ETC。
请注意,将随机性纳入您的代码的方式是不纯净:现在,您的程序中存在隐式的全局状态,并且您不再可以轻松地复制描述测试用例时所需的结果。对于此类程序。一个解决方案保存逻辑purity 必须使此  state 显式,例如,将随机  seed 作为参数之一,所以每个运行都是完全可重现的。
请注意,重新排序连词和/或类似的目标仅适用于 pure 和单调 prolog的子集,因此请确保您使用声明性功能,例如  约束安全地交换目标,并增加您的代码!