2011-11-29 29 views
9

Tôi đã xem qua các câu hỏi tương tự nhưng không thể tìm thấy bất kỳ điều gì liên quan đến vấn đề của tôi. Tôi đang loay hoay tìm một thuật toán hoặc bộ 'vòng' rằng sẽ tìm thấy một con đường CityA-CityB, sử dụng một cơ sở dữ liệu củaNhân Viên Bán Hàng Du Lịch Đơn Giản trong Prolog

distance(City1,City2,Distance) 

sự kiện. Những gì tôi đã quản lý để làm cho đến nay là dưới đây, nhưng nó luôn luôn backtracks tại write(X), và sau đó hoàn thành với iteration cuối cùng, đó là những gì tôi muốn nó làm nhưng chỉ đến một mức độ nhất định.

Ví dụ: tôi không muốn nó in ra bất kỳ tên thành phố nào là kết thúc chết hoặc sử dụng lặp lại cuối cùng. Tôi muốn nó về cơ bản tạo một con đường từ CityA đến CityB, viết tên của các thành phố mà nó đi vào đường dẫn.

Tôi hy vọng ai đó có thể giúp tôi!

all_possible_paths(CityA, CityB) :- 
    write(CityA), 
    nl, 
    loop_process(CityA, CityB). 

loop_process(CityA, CityB) :- 
    CityA == CityB. 
loop_process(CityA, CityB) :- 
    CityA \== CityB, 
    distance(CityA, X, _), 
    write(X), 
    nl, 
    loop_process(X, CityB). 

Trả lời

7

Tôi đã cố gắng chứng minh cách bạn có thể đạt được những gì bạn đang làm việc để bạn có thể hiểu rõ hơn cách hoạt động của nó. Vì vậy, kể từ khi OP của bạn đã không hoàn thành, tôi đã lấy một số quyền tự do! Dưới đây là những sự kiện tôi đang làm việc với:

road(birmingham,bristol, 9). 
road(london,birmingham, 3). 
road(london,bristol, 6). 
road(london,plymouth, 5). 
road(plymouth,london, 5). 
road(portsmouth,london, 4). 
road(portsmouth,plymouth, 8). 

đây là vị chúng tôi sẽ gọi để tìm con đường của chúng tôi, get_road/4. Về cơ bản nó gọi là vị ngữ làm việc, có hai bộ tích lũy (một cho các điểm đã được truy cập và một cho khoảng cách mà chúng ta đã trải qua).

get_road(Start, End, Visited, Result) :- 
    get_road(Start, End, [Start], 0, Visited, Result). 

Đây là vị làm việc,
get_road/6: get_road (+ Start + End, + Waypoints, + DistanceAcc, -Visited, -TotalDistance):
Mệnh đề đầu tiên nói rằng nếu có một con đường giữa điểm đầu tiên và điểm cuối cùng của chúng ta, chúng ta có thể kết thúc ở đây.

get_road(Start, End, Waypoints, DistanceAcc, Visited, TotalDistance) :- 
    road(Start, End, Distance), 
    reverse([End|Waypoints], Visited), 
    TotalDistance is DistanceAcc + Distance. 

Điều khoản thứ hai cho biết nếu có một con đường giữa điểm đầu tiên và điểm trung gian, chúng tôi có thể lấy nó và sau đó giải quyết get_road (trung gian, kết thúc).

get_road(Start, End, Waypoints, DistanceAcc, Visited, TotalDistance) :- 
    road(Start, Waypoint, Distance), 
    \+ member(Waypoint, Waypoints), 
    NewDistanceAcc is DistanceAcc + Distance, 
    get_road(Waypoint, End, [Waypoint|Waypoints], NewDistanceAcc, Visited, TotalDistance). 

Cách sử dụng như sau:

?- get_road(portsmouth, plymouth, Visited, Distance). 

Và sản lượng:

Visited = [portsmouth, plymouth], 
Distance = 8 ; 
Visited = [portsmouth, london, plymouth], 
Distance = 9 ; 
Visited = [portsmouth, plymouth, london, plymouth], 
Distance = 18 ; 
false. 

Tôi hy vọng nó sẽ rất hữu ích cho bạn.

+0

Bạn thưa bạn, đã đi trên và vượt ra ngoài các cuộc gọi của nhiệm vụ! Điều này thật đáng kinh ngạc, nó hoàn hảo và nó thực sự có ý nghĩa! Xin lỗi tôi là một giả, tôi thực sự mới để prolog và trong khi khá nhiều của nó đã đến rất tự nhiên tôi đã thực sự đấu tranh với nhiệm vụ này. Cảm ơn bạn rất nhiều vì vậy sooooo nhiều:] –

+0

đừng ngần ngại gửi câu hỏi thêm nếu bạn đấu tranh một lần nữa để hiểu mã này, tôi hoặc những người khác sẽ trả lời chúng trong ý kiến ​​:) – m09

1

Bạn nên trả lại danh sách thành công dưới dạng Biến ngoài trong all_possible_paths. Sau đó viết ra danh sách đó. Đừng làm cả hai trong cùng một thủ tục.

+0

cảm ơn sự giúp đỡ của bạn:] –

4

Vui lòng tách phần tinh khiết ra khỏi không tinh khiết (I/O, như write/1, nl/0 nhưng cũng (==)/2(\==)/2). Miễn là chúng hoàn toàn xen kẽ với mã thuần túy của bạn, bạn không thể mong đợi nhiều.

Có thể bạn muốn có mối quan hệ giữa điểm xuất phát, điểm kết thúc và đường dẫn ở giữa.

Đường dẫn đó có bị tuần hoàn hoặc bạn có cho phép chu kỳ không?

Để đảm bảo rằng một yếu tố X không xảy ra trong một danh sách Xs sử dụng mục tiêu maplist(dif(X),Xs). Bạn không cần bất kỳ vị từ phụ trợ hơn nữa để làm cho một mối quan hệ tốt đẹp!

+0

Khi một thành phố đã được sử dụng, nó không thể được sử dụng lại trong cùng một đường dẫn. Vì vậy, theo chu kỳ. Ngoài ra, bạn có ý nghĩa gì bởi tinh khiết và không tinh khiết? –

+0

Tôi đã thêm giải thích ở trên. – false

+0

cảm ơn sự giúp đỡ của bạn! :] –

Các vấn đề liên quan