Prolog:如何从一组随机数中选择最高值

时间:2011-03-15 14:02:45

标签: prolog

好的,这个问题措辞有点差,但我想做的是使用rand_int选择0到MAX之间的N个数字并选择最大值。

这就是我尝试这个的方法,但由于某些原因它不起作用:

rand_val(Count, Rng, Res) :-
    Count > 0,
    Count is Count - 1,
    rand_int(Rng, X),
    Res is max(X, Res),
    rand_val(Count, Rng, Res).

?- rand_val(2,100,Res).
-> no.

我是Prolog的新手(已经研究了几个小时),所以我可能只是误解了一些东西。

2 个答案:

答案 0 :(得分:2)

您的问题是您无法实例化已使用不同术语实例化的变量。 因此,如果Count已经被实例化(比如说2),你就不能做Count is Count - 1。

is / 2运算符需要左变量未实例化(或使用表达式的实际值实例化)和要完全计算的右表达式。 这同样适用于递归调用。将Res实例化为整数后,您无法将其值更改为另一个整数。

这是另一种实现:

rand_val(Count, Rng, Res):-
  rand_val(Count, Rng, -1, Res).

rand_val(0, _, Value, Value):-
  !,
  Value >= 0.
rand_val(Count, Rng, MValue, Value) :-
  succ(NCount, Count),
  X is random(Rng), %rand_int(Rng, X),
  NValue is max(X, MValue),
  rand_val(NCount, Rng, NValue, Value).

首先请注意,我写了两个谓词rand_val / 3和rand_val / 4。 前者是您想要的签名。 后者还有一个参数,它将保持当时发现的最大值。

第一个谓词只是调用rand_val / 4指定值-1作为找到的最大值。

现在rand_val / 4的第一个子句检查其输入参数“Count”是否为0.在这种情况下,它禁止回溯(使用cut)并检查Value是否为有效值。如果是< 0它是因为你用Count = 0调用了rand_val / 3,所以它实际上从未发出过随机数。

如果是> 0它只是统一了第三个和第四个参数(注意第四个参数是你期望作为输出的值)。

现在到第二个条款:  首先它执行succ(NCount,Count),其中NCount是一个新变量。它将使用Count(Count-1)的前身进行实例化。

然后我们计算一个随机数。我正在使用SWI prolog,所以我打电话给随机(Max)来获取随机数。这用它实例化新变量X.

此时我们选择中间结果(MValue)和X之间的最大值。

最后我们执行递归步骤,现在使用新的计算值NCount和NValue调用rand_val / 4.

请注意,当我们从递归返回时,变量Value被实例化(它被绑定在rand_val / 4的第一个子句中)。

答案 1 :(得分:2)

我的Prolog很生疏,所以我可能错过了一些内容,但代码中的一个明显问题是:Count is Count - 1

你所写的是一个等式(如数学)x = x - 1。显然,这个等式没有解决方案。这就是Prolog引擎所谓的“不”。您可能会尝试将其重写为NextCount is Count - 1(稍后使用NextCount而不是Count)。