2011-03-15 185 views
0

好的,這個問題有點措辭不足,但我想要做的是使用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

你的問題是,你不能實例化已經實例化了一個不同的術語的變量。 因此,如果計數已經實例化(比如用2),則不能計數爲計數-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.在這種情況下,它禁止回溯(使用剪切)並檢查Value是否爲有效值。如果它是< 0,那是因爲你用Count = 0調用了rand_val/3,所以它確實從未發出隨機數。

如果它> 0,它只是統一了第三個和第四個參數(注意第四個參數是你期待的輸出值)。

現在到第二個子句: 首先它做一個succ(NCount,Count),其中NCount是一個新變量。它將通過Count(Count-1)的前身進行實例化。

然後我們計算一個隨機數。我正在使用SWI prolog,因此我隨機調用(Max)來獲得隨機數。這用它來實例化新變量X.

在這一點上,我們有中間結果(MValue)和X

最後我們做遞歸步驟,現在稱rand_val/4與新的計算值NCOUNT和n值之間選擇的最大值。

請注意,當我們從遞歸返回(它在rand_val/4的第一個子句中被綁定)時,變量Value被實例化。

+0

我將它複製到tuProlog的IDE,並且在運行rand_val(0,100,Res)時仍然得到「no」。我認爲最大/ 2不起作用。我可以創建一個max/3,但無法弄清楚如何做一個「返回值」的最大值(如果這是Prolog中的正確術語)。 – Makis 2011-03-16 07:45:42

+0

@Makis:也許TuProlog沒有實現最大的算術函數。在這種情況下,你可以寫下你自己的max/3謂詞:max(A,B,Max): - A> B - > Max = A; MAX = B中。然後,您將使用'max(X,MValue,NValue)'替換'NValue is max(X,MValue)' – gusbro 2011-03-16 13:04:23

+0

謝謝您的出色答案! – Makis 2011-03-17 06:35:54

2

我的序言很生鏽,所以我可能錯過了一些東西,但是代碼中的一個明顯問題是:Count is Count - 1

你寫的是一個等式(如在數學中)x = x - 1。顯然,這個方程沒有解決方案。這就是Prolog引擎的「否」意味着什麼。您可以嘗試將其重寫爲NextCount is Count - 1(並且稍後使用NextCount代替計數)。