You are on page 1of 7

Machine Translated by Google

9 đồ thị. Đường dẫn trong đồ thị


Phiên này bao gồm các lựa chọn thay thế biểu diễn đồ thị và một số loại đường dẫn đồ thị trong

Prolog.

9.1 Biểu diễn

Một đồ thị được cho bởi một tập hợp các đỉnh và một tập hợp các cạnh (nếu đồ thị là

vô hướng, hoặc các cung, nếu đồ thị có hướng):

G=(V,E)

Chúng ta hãy xem xét một ví dụ về đồ thị vô hướng:

Một số lựa chọn thay thế có sẵn để biểu diễn đồ thị trong Prolog và chúng có thể được phân loại

theo các tiêu chí sau:

Một loại đại diện:

1 Là một tập hợp các cạnh

2 Là một tập hợp các đỉnh và danh sách láng giềng liên quan

B Nơi bạn lưu trữ biểu đồ:


1 Trong bộ nhớ chính, như một đối tượng dữ liệu

2 Trong cơ sở vị ngữ, với tư cách là một tập hợp các sự kiện vị ngữ

Do đó, có thể có bốn cách biểu diễn chính (có thể tồn tại các cách tiếp cận khác, nhưng với mục

đích của khóa học hiện tại, những cách này là đủ): • (A1B2) Là một tập hợp các cạnh, được lưu trữ dưới dạng

các sự kiện vị từ ( dạng mệnh đề cạnh): edge(a , b). cạnh (b, a). cạnh (b, c). cạnh (c, b).

….
Trong biểu diễn này, các nút bị cô lập không thể được chỉ định.

• (A2B2) Là một tập hợp các đỉnh và danh sách lân cận liên quan, được lưu dưới dạng

sự kiện vị ngữ (dạng mệnh đề danh sách hàng xóm ):

1
Machine Translated by Google

hàng xóm(a,[b,d]).

hàng xóm(b, [a, c, d]).

hàng xóm(c, [b, d]).

• (A2B1) Là một tập hợp các đỉnh và danh sách lân cận được liên kết, được lưu trữ dưới dạng đối

tượng dữ liệu ( dạng danh sách lân cận): ?- Graph = [n(a, [b,d]), n(b, [a, c,d]), n(c,

[b,d]), n(d, [a,b,c]), n(e, [f,g]), n(f, [e]), n(g, [e]), n(h, [])].

• (A1B1) Là tập hợp các đỉnh và tập hợp các cạnh, được lưu trữ dưới dạng đối tượng dữ liệu

( dạng thuật ngữ đồ

thị): ?- Graph = graph([a,b,c,d,e,f,g,h], [e(a,b), e(b,a), … ]).

Biểu diễn phù hợp nhất để sử dụng phụ thuộc nhiều vào vấn đề hiện tại. Do
đó, thật thuận tiện khi biết cách thực hiện chuyển đổi giữa các biểu diễn đồ thị
khác nhau. Ở đây, chúng tôi cung cấp một ví dụ chuyển đổi từ biểu mẫu mệnh đề láng
giềng sang biểu mẫu mệnh đề cạnh : neighbour(a, [b, d]). % một đồ thị ví dụ – 1
st
láng giềng(b, [a, c, d]). % ví dụ đồ thị hàngthành
xóm(c, [b,
phần d]).
liên kết của

neighb_to_edge:-neighbor(Nút,Danh sách),

quá trình (Nút, Danh sách),

không thành công. hàng

xóm_to_edge.

process(Node, [H|T]):- assertz(edge(Node, H)), process(Node,

T).

quá trình(_, []).

Biểu đồ ban đầu được lưu trữ trong cơ sở dữ liệu vị từ. Vị từ neighb_to_edge
đọc một mệnh đề của vị từ lân cận tại một thời điểm và xử lý thông tin trong từng mệnh
đề một cách riêng biệt; quá trình duyệt qua danh sách lân cận của nút hiện tại và xác
nhận một thực tế mới cho cạnh vị từ cho mỗi lân cận mới của nút hiện tại.

9.2 Đường đi trong đồ thị

Đã đề cập đến vấn đề biểu diễn đồ thị, chúng ta hãy giải quyết vấn đề duyệt đồ
thị. Chúng ta sẽ bắt đầu với đường dẫn đơn giản giữa hai nút và tiến hành

2
Machine Translated by Google

đến đường đi giới hạn giữa hai nút, đường đi tối ưu giữa hai nút và cuối cùng là chu trình
Hamilton của một đồ thị.

9.2.1 Đường dẫn đơn giản

Chúng tôi giả sử đồ thị được biểu diễn dưới dạng mệnh đề cạnh. Vị ngữ which
tìm kiếm đường dẫn giữa hai nút trong biểu đồ được trình bày bên dưới:
% path(Source, Target, Path)

đường dẫn (X, Y, Đường dẫn): -đường dẫn (X, Y, [X], Đường dẫn).

đường dẫn(X,Y,PPath, FPath):- cung(X,Z), \+

(thành viên(Z, PPath)), đường

dẫn(Z, Y, [Z|PPath], FPath).

đường dẫn (X, X, PPath, PPath).

Loại đệ quy nào được sử dụng ở đây?

Bài tập 9.1: Biểu diễn một đồ thị bằng cách sử dụng biểu mẫu mệnh đề cạnh và theo
dõi việc thực hiện vị từ đường dẫn trên các truy vấn khác nhau (bạn có thể sử dụng đồ thị
ví dụ, có thể thêm một số cạnh vào nó). Điều gì xảy ra khi bạn lặp lại câu hỏi?

9.2.2 Đường giới hạn

Bây giờ chúng ta thử viết một vị từ tìm đường đi giới hạn giữa hai nút trong một
đồ thị, tức là đường đi phải đi qua các nút nhất định, theo một thứ tự nhất định (các nút
này được chỉ định trong một danh sách). %strict_path(Source, Target,RestrictionsList,
Path) %check_restrictions(Lrestrictions, Path)

đường dẫn bị hạn chế (X, Y, LR, P): - đường dẫn (X,

Y, P), check_restrictions (LR, P).

check_restrictions([],_):- !.

check_restrictions([H|T], [H|R]):- !, check_restrictions(T,R).

check_restrictions(T, [H|L]):-check_restrictions(T,L).

Vị từ bị hạn chế_path/4 tìm kiếm đường dẫn giữa nút nguồn và nút đích, sau đó kiểm
tra xem đường dẫn đó có thỏa mãn các hạn chế được chỉ định trong LR hay không (tức là đi
qua một chuỗi các nút nhất định, được chỉ định trong LR), sử dụng vị từ check_restrictions/
2, thực hiện kiểm tra thực tế. check_restrictions/2 đi qua danh sách hạn chế (đối số thứ
nhất) và danh sách đại diện cho đường dẫn (đối số thứ hai

3
Machine Translated by Google

đối số) đồng thời, miễn là phần đầu của chúng trùng nhau (điều khoản 2). Khi các mặt ngửa không
khớp nhau, chúng tôi chỉ tiến lên trong danh sách thứ hai (mệnh đề 3). Vị ngữ thành công khi
danh sách đầu tiên trở nên trống rỗng (mệnh đề 1).

Câu hỏi: Điều gì xảy ra nếu chúng ta chuyển điều kiện dừng thành mệnh đề cuối cùng? Làm
chúng ta cần dấu “!” ở trạng thái dừng?

Bài tập 9.2: Theo dõi việc thực hiện các truy vấn sau: 1. ?-
check_restrictions([2,3], [1,2,3,4]). 2. ?-
check_restrictions([1,3], [1,2,3,4]). 3. ?-
check_restrictions([1,3], [1,2]).

Bài tập 9.3: Theo dõi việc thực hiện một số truy vấn cho vị từ bị hạn chế_path/4 , trên
biểu đồ ví dụ của bạn. Thứ tự mà bạn phải chỉ định các nút trong danh sách hạn chế là gì? Tại
sao?

9.2.3 Đường đi tối ưu

Chúng tôi coi đường dẫn tối ưu giữa nút nguồn và nút đích trong biểu đồ là đường dẫn
chứa số lượng nút tối thiểu. Một cách tiếp cận để tìm đường đi tối ưu là tạo ra tất cả các
đường dẫn thông qua quay lui và sau đó chọn đường dẫn tối ưu. Tất nhiên, điều này cực kỳ kém
hiệu quả. Thay vào đó, trong quá trình quay lui, chúng tôi sẽ giữ giải pháp tối ưu một phần
bằng cách sử dụng các hiệu ứng bên (tức là trong cơ sở vị từ) và cập nhật nó bất cứ khi nào tìm
thấy giải pháp tốt hơn: %optimal_path(Source, Target, Path)

optim_path(X,Y,Path):-asserta(sol_part([],100)), path(X,Y,

[X],Path,1). optim_path(_,_,Path):-

retract(sol_part(Path,_)).

path(X,X,Path,Path,LPath):-retract(sol_part(_,_)),!,

asserta(sol_part(Path,LPath)), không
thành công.

đường dẫn(X,Y,PPath,FPath,LPath):-e_arc(X,Z),

\+(thành viên(Z,PPath)),

LPath1 là LPath+1,

sol_part(_,Lopt),

LPath1<Lopt, path(Z,Y,[Z|

PPath],FPath,LPath1).

Đường dẫn vị ngữ/5 tạo, thông qua quay lui, tất cả các đường dẫn tốt hơn giải pháp từng
phần hiện tại và cập nhật giải pháp từng phần hiện tại bất cứ khi nào một đường dẫn ngắn hơn

4
Machine Translated by Google

được tìm thấy. Khi một giải pháp tốt hơn giải pháp tối ưu hiện tại được tìm thấy, vị từ
sẽ thay thế giải pháp tối ưu cũ trong cơ sở vị từ (mệnh đề 1) và sau đó tiếp tục tìm
kiếm bằng cách khởi chạy cơ chế quay lui (sử dụng fail).

Bài tập 9.3: Theo dõi việc thực hiện một số truy vấn cho vị từ optim_path/3 , sử
dụng biểu đồ ví dụ.

!!! Khi làm việc với khẳng định/rút lại, hãy đảm bảo rằng bạn “làm sạch bản thân”, tức là kiểm

tra xem không có mệnh đề không mong muốn nào vẫn được khẳng định trên cơ sở vị ngữ của bạn sau khi thực

hiện các truy vấn của bạn (tác động của chúng không bị ảnh hưởng bởi việc quay lui!).

9.2.4 Chu trình Hamilton

Chu trình Hamilton là một đường đi khép kín trong đồ thị đi qua đúng một lần tất
cả các nút (ngoại trừ nút đầu tiên, là nguồn và đích của đường đi). Tất nhiên, không
phải mọi đồ thị đều có chu trình như vậy. Vị từ hamilton/3 được cung cấp bên dưới:
%hamilton(NbNodes, Source, Path)

hamilton(NN, X, Đường dẫn):- NN1 là NN-1, hamilton_path(NN1,X, X, [X],Đường dẫn).

Vị từ hamilton_path/5 được để lại cho bạn thực hiện. Vị từ nên tìm kiếm một đường
dẫn khép kín từ X, có độ dài NN1 (số nút trong biểu đồ, trừ 1).

Bài tập 9.3: Theo dõi việc thực hiện một số truy vấn cho vị từ hamilton/3 , sử
dụng biểu đồ ví dụ.

5
Machine Translated by Google

9.3 Bài tập trắc nghiệm

q91. Viết (các) vị từ thực hiện chuyển đổi giữa biểu diễn mệnh đề cạnh ( A1B2 ) sang biểu
diễn danh sách danh sách láng giềng (A2B1).

q92. Vị từ đường dẫn bị hạn chế tính toán đường dẫn giữa nút nguồn và nút đích, sau đó
kiểm tra xem đường dẫn được tìm thấy có chứa các nút trong danh sách hạn chế hay

không. Vì đường dẫn vị từ được sử dụng đệ quy thuận, thứ tự của các nút phải được
đảo ngược trong cả hai danh sách – đường dẫn và danh sách hạn chế. Cố gắng giải
thích lý do tại sao chiến lược này không hiệu quả (sử dụng dấu vết để xem điều gì sẽ xảy ra).
Viết một vị từ hiệu quả hơn để tìm kiếm đường dẫn bị hạn chế giữa nút nguồn và nút

đích.

q93. Viết lại vị từ optim_path/3 sao cho nó hoạt động trên các biểu đồ có trọng số: gắn
trọng số cho mỗi cạnh trên biểu đồ và tính toán đường dẫn chi phí tối thiểu từ nút
nguồn đến nút đích.

9.4 Sự cố

p91. Viết một chu trình vị từ(A,P) để tìm một đường đi khép kín (chu trình) P bắt đầu tại

một nút A đã cho trong đồ thị G (sử dụng bất kỳ biểu diễn đồ thị nào cho G). Vị

từ phải trả về tất cả các chu kỳ thông qua quay lui.

p92. (**) Viết một tập hợp các vị từ Prolog để giải bài toán WolfGoatCabbage: “Một nông

dân cùng con dê, con sói và cây bắp cải của anh ta đang ở bờ Bắc của một con sông.

Họ cần băng qua bờ Nam. Họ có một chiếc thuyền, với sức chứa hai người; người nông

dân là người duy nhất có thể chèo. Nếu để dê và bắp cải một mình mà không có người

nông dân, dê sẽ ăn bắp cải. Tương tự như vậy, nếu con sói và con dê ở cùng nhau mà

không có người nông dân, con dê sẽ bị ăn thịt.”

gợi ý:

bạn có thể chọn mã hóa không gian trạng thái dưới dạng các phiên bản
cấu hình của 4 đối tượng (Nông dân, Sói, Dê, Bắp cải), được biểu diễn
dưới dạng danh sách (tức là [F,W,G,C]) hoặc dưới dạng cấu trúc phức tạp
(ví dụ: FWGC hoặc trạng thái (F,W,G,C)).
trạng thái ban đầu sẽ là [n,n,n,n], trạng thái cuối cùng [s,s,s,s],
để biểu diễn danh sách các trạng thái (ví dụ: nếu Farmer đưa Wolf qua >
[s,s,n,n ] (và con dê ăn bắp cải), vì vậy trạng thái này không hợp lệ)

6
Machine Translated by Google

trong mỗi lần chuyển đổi (hoặc di chuyển), Nông dân có thể thay đổi trạng thái

của mình (từ n sang s hoặc ngược lại) cùng với nhiều nhất một người tham gia khác

(Sói, Dê hoặc Bắp cải), điều này có thể được xem như một bài toán tìm đường trong

đồ thị Vui thích!

You might also like