[英]Solving a simple puzzle in prolog
我用 C 解決了一個難題,並嘗試在 Prolog 中做同樣的事情,但我在用這種語言表達事實和目標時遇到了一些麻煩。
這個問題的非常簡化的版本是:一個房間里有兩個杠桿。 每個杠桿控制一個可以在四個不同位置(我記為 0、1、2 或 3)向前或向后移動的機構。 如果你在同一個方向上移動一個機構四次,它會和以前一樣處於相同的位置。
杠桿 n°1 將機構 n°1 向前移動兩個位置。 杠桿 n°2 將機構 n°2 向前移動一個位置。
最初,機構 n°1 位於位置 2,機構 n°2 位於位置 1。問題是找到將兩個機構移動到位置 0 的最快方法,並獲得導致每個解決方案的杠桿順序。
當然,這里的問題是微不足道的,您只需拉動 n°1 的桿一次和拉動 n°2 的桿 3 次即可得到解決方案。
這是 C 語言中的一個簡單代碼,它給出了拉動拉桿的順序,通過拉動少於 5 個拉桿來解決這個問題:
int pos1 = 2, pos2 = 1;
int main()
{
resolve(0,5);
return 0;
}
void lever1(){
pos1 = (pos1 + 2) % 4;
}
void undolever1(){
pos1 = (pos1 - 2) % 4;
}
void lever2(){
pos2 = (pos2 + 1) % 4;
}
void undolever2(){
pos2 = (pos2 - 1) % 4;
}
void resolve(l, k){
if(k == 0){
return;
}
if(pos1 == 0 && pos2 == 0){
printf("Solution: %d\n", l);
return;
}
if(k>0){
k--;
lever1();
resolve(l*10+1,k);
undolever1();
lever2();
resolve(l*10+2,k);
undolever2();
}
}
到目前為止,我在 Prolog 中的代碼如下所示:
lever(l1).
lever(l2).
mechanism(m1).
mechanism(m2).
position(m1,2).
position(m2,1).
pullL1() :- position(m1, mod(position(m1,X)+2,4)).
pullL2() :- position(m2, mod(position(m2,X)+1,4)).
solve(k) :- solve_(k, []).
solve_(0, r) :- !, postion(m1, p1), postion(m2, p2), p1 == 0, p2 == 0.
solve_(k, r) :- k > 0, pullL1(), k1 is k - 1, append(r, [1], r1), solve_(k1, r1).
solve_(k, r) :- k > 0, pullL2(), k1 is k - 1, append(r, [2], r2), solve_(k1, r2).
我很確定這段代碼中存在多個問題,但我不確定如何解決它。 任何幫助將非常感激。
我認為這是一個非常有趣的問題。 我想你想要一個通用的解決方案 -> 一個杠桿可以移動多個機構。 如果問題與您的一樣,一個杠桿只控制一種機制,那么解決方案就很簡單了。 您只需移動每個杠桿一段時間,直到該機構處於狀態零。
但我想提供一個更通用的解決方案,以便一個杠桿可以移動多個機構。 但首先是一點數學。 別擔心,我最終也會做一個例子。
讓我們定義
作為 n 個杠桿和
是 m 機制。 然后讓我們用一個向量定義每個杠桿:
在哪里是步數移動向前。
對於我們定義的機制:
beeing機制的偏見->所以處於初始狀態和
是每個機制的狀態數量。 所以現在我們可以這樣描述我們的整個系統:
哪里是我們必須激活的次數 . 如果我們想將所有機制設置為零。 如果你不熟悉 符號這只是意味着 a%m = b%m。
我們可以改寫為:
其中 k 可以是任何自然數。 所以我們可以將我們的系統重寫為一個方程系統:
prolog 可以為我們解出這樣一個方程組。 (解決丟番圖方程系統有不同的解決方案,請參見https://en.wikipedia.org/wiki/Diophantine_equation )
好的,現在讓我們舉個例子:假設我們有兩個杠桿和三個具有 4 個狀態的機制。 拳頭杠桿將 M1 向前移動一個,將 M3 向前移動兩個。 第二個杠桿將 M2 向前移動一個,將 M3 向前移動一個。 M1 處於狀態 2。M2 處於狀態 3。M3 處於狀態 3。所以我們的方程系統如下所示:
在 prolog 中,我們可以使用 clpfd 庫解決這個問題。
?- [library(clpfd)].
然后像這樣解決:
?- X1+(-4)*K1+2 #= 0, 1*X2+(-4)*K2+3 #= 0, 2*X1+X2+(-4)*K3+3 #= 0,Vs = [X1,X2], Vs ins 0..100,label(Vs).
這給了我們解決方案
VS = [2, 1]
-> 所以 X1 = 2 和 X2 = 1 這是正確的。 Prolog可以給你更多的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.