簡體   English   中英

前言中的2水壺

[英]2-Water jug in prolog

我正在嘗試解決swi-prolog中的2水壺問題:給定2罐容量分別為4和3加侖的水,我想找到在2罐容量為4和0的水壺中獲得2加侖水的步驟。

我使用bfs和dfs在C ++中針對此問題編寫了程序: http : //kartikkukreja.wordpress.com/2013/10/11/water-jug-problem/ 現在,我正在嘗試解決序言中的問題。 我是該語言的新手,我的代碼也不會終止。

這是我到目前為止的代碼:

% state(0, 0) is the initial state
% state(2, 0) is the goal state
% Jugs 1 and 2 have capacities 4 and 3 respectively
% P is a path to the goal state
% C is the list of visited states

solution(P) :-
    path(0, 0, [state(0, 0)], P).

path(2, 0, [state(2, 0)|_], _).

path(0, 2, C, P) :-
not(member(state(2, 0), C)),
path(2, 0, [state(2, 0)|C], R),
P = ['Pour 2 gallons from 3-Gallon jug to 4-gallon.'|R].

path(X, Y, C, P) :-
X < 4,
not(member(state(4, Y), C)),
path(4, Y, [state(4, Y)|C], R),
P = ['Fill the 4-Gallon Jug.'|R].

path(X, Y, C, P) :-
Y < 3,
not(member(state(X, 3), C)),
path(X, 3, [state(X, 3)|C], R),
P = ['Fill the 3-Gallon Jug.'|R].

path(X, Y, C, P) :-
X > 0,
not(member(state(0, Y), C)),
path(0, Y, [state(0, Y)|C], R),
P = ['Empty the 4-Gallon jug on ground.'|R].

path(X, Y, C, P) :-
Y > 0,
not(member(state(X, 0), C)),
path(X, 0, [state(X, 0)|C], R),
P = ['Empty the 3-Gallon jug on ground.'|R].

path(X, Y, C, P) :-
X + Y >= 4,
X < 4,
Y > 0,
NEW_Y = Y - (4 - X),
not(member(state(4, NEW_Y), C)),
path(4, NEW_Y, [state(4, NEW_Y)|C], R),
P = ['Pour water from 3-Gallon jug to 4-gallon until it is full.'|R].

path(X, Y, C, P) :-
X + Y >=3,
X > 0,
Y < 3,
NEW_X = X - (3 - Y),
not(member(state(NEW_X, 3), C)),
path(NEW_X, 3, [state(NEW_X, 3)|C], R),
P = ['Pour water from 4-Gallon jug to 3-gallon until it is full.'|R].

path(X, Y, C, P) :-
X + Y =< 4,
Y > 0,
NEW_X = X + Y,
not(member(state(NEW_X, 0), C)),
path(NEW_X, 0, [state(NEW_X, 0)|C], R),
P = ['Pour all the water from 3-Gallon jug to 4-gallon.'|R].

path(X, Y, C, P) :-
X + Y =< 3,
X > 0,
NEW_Y = X + Y,
not(member(state(0, NEW_Y), C)),
path(0, NEW_Y, [state(0, NEW_Y)|C], R),
P = ['Pour all the water from 4-Gallon jug to 3-gallon.'|R].

任何幫助表示贊賞。

Prolog 的“等於”運算符執行算術運算,而是統一其兩個參數。 嘗試(例如)替換它

NEW_Y = Y - (4 - X)

NEW_Y is Y - (4 - X)

OT:同樣,Prolog和其他任何語言一樣,都受益於代碼分解: 大多數 path / 4規則都公開了相同的模式,因此使用輔助謂詞可以使代碼更簡潔:例如

path(0, 2, C, P) :-
  not(member(state(2, 0), C)),
  path(2, 0, [state(2, 0)|C], R),
  P = ['Pour 2 gallons from 3-Gallon jug to 4-gallon.'|R].

可能

path(0, 2, C, ['Pour 2 gallons from 3-Gallon jug to 4-gallon.'|R]) :-
  upd_path(2, 0, C, R).

給定

upd_path(X, Y, C, R).
      not(member(state(X, Y), C)),
      path(X, Y, [state(X, Y)|C], R).

編輯 :另一個OT提示:使用memberchk / 2而不是member / 2。 它具有確定性,因此效率更高,並且可以更輕松地跟蹤執行。

編輯此外,遞歸的基本情況不會關閉描述的列表:try

path(2, 0, [state(2, 0)|_], []).

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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