Random 概率从句选择

Random 概率从句选择,random,prolog,Random,Prolog,我已经很久没有认真使用Prolog了,但是我在谷歌搜索或者在我的文本中都找不到这方面的任何参考。这可能是术语上的错误,所以如果我对此进行了删减,我深表歉意 如果我有一个可以有多种解决方案的程序: likes(mary, joe). likes(bob, joe). :- likes(X, joe) 是否有一种简单的内置方法让解算器以随机顺序运行匹配谓词,从而以随机顺序给出结果(或者,等效地,第一个解是随机的) 很明显,你可以用random这个词来表达你喜欢的复杂程度。我正在考虑在解算器的每一

我已经很久没有认真使用Prolog了,但是我在谷歌搜索或者在我的文本中都找不到这方面的任何参考。这可能是术语上的错误,所以如果我对此进行了删减,我深表歉意

如果我有一个可以有多种解决方案的程序:

likes(mary, joe).
likes(bob, joe).

:- likes(X, joe)
是否有一种简单的内置方法让解算器以随机顺序运行匹配谓词,从而以随机顺序给出结果(或者,等效地,第一个解是随机的)

很明显,你可以用random这个词来表达你喜欢的复杂程度。我正在考虑在解算器的每一步从一组有效谓词中进行统一的随机抽样。更复杂的事情,比如对有效解进行均匀随机抽样,也可以。这个问题是一般性的

我可能可以使用随机数生成器和元编程来构建一个程序来实现这一点。但是我想检查一下我是否遗漏了一些简单的东西。

在这种情况下,随机化解决方案是最简单的,因为你只有有限的解决方案,因此可以很容易地收集它们:

?- findall(X, likes(X, joe), Ps0), random_permutation(Ps0, Ps), member(P, Ps).

这将为所有像joe这样的人提供一个接一个的随机顺序。

匹配子句的线性选择是Prolog算法(或更好)的一个重要部分。每个匹配都是一个候选解决方案。我认为你不能期望Prolog这样为你随机化子句顺序

我想详细说明mat的回答:

:- meta_predicate randomize_preds(0).

randomize_preds(C) :-
   findall(C, retract(C), Cs),
   random_permutation(Cs, Rs),
   maplist(assertz, Rs).

:- dynamic likes/2.

likes(alice, joe).
likes(bob, joe).
likes(charlie, joe).
likes(dan, joe).
测试:


但这并不具有可伸缩性。您需要完整的解决方案集是可处理的,而在更现实的问题中可能不会这样。正如OP所说,这个问题是一般性的。这很容易扩展到数百万个解决方案,例如:
?-time(findall(X,介于(1,5,000,X),Xs))。
(在几秒钟内工作),这肯定涵盖了许多通过简单事实描述解决方案的现实世界问题。对不起,我在这里不清楚。我想说的是:一百万个解决方案远比不上Prolog表达能力带来的组合爆炸。这里有一个愚蠢的例子:生成{a random |完整的}位数组,其中设置位的数量为偶数。对于长度2N,有2^N个。他要求的随机算法需要时间O(2N)来生成一个;
findall
/
random_permutation
算法需要O(2^N)。如果解的数量与子句的数量成线性增长,我会编写一个简单的元解释器,在每个推理步骤中动态选择一个随机子句。是的,不幸的是,我的问题域是组合的。这就是为什么我的直觉是它必须在规则层面上随机,而不是解决方案。因此,没有简单的解决方案。谢谢。你没有遗漏任何简单的东西。Prolog引擎尝试谓词子句的顺序取决于它们在源文件中的出现顺序,对于在多个源文件中包含子句的谓词,有特殊规则(涉及多文件指令),但没有任何规则会以您想要的方式随机化。
3 ?- randomize_preds(likes(_,_)),findall(X,likes(X,joe),L).
L = [bob, alice, charlie, dan].

4 ?- randomize_preds(likes(_,_)),findall(X,likes(X,joe),L).
L = [alice, bob, dan, charlie].