在Prolog中,可以随机选择解决方案



如果我有以下内容:

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 = cZ = 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的子集,因此请确保您使用声明性功能,例如  约束安全地交换目标,并增加您的代码!

最新更新