簡體   English   中英

在序言中解決一個簡單的難題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM