湖南大學人工智慧實驗二:Prolog程式設計求解圖搜尋問題
說在前面:這個實驗我也是抄的 真的有人會寫prolog嘛?
程式碼連結:人工智慧實驗
文章目錄
人工智慧實驗二:Prolog程式設計求解圖搜尋問題
一.實驗目的
-
熟悉PROLOG的執行環境,進行PROLOG的基本程式設計練習;
瞭解PROLOG語言中常量、變數的表示方法。PROLOG的簡單程式結構,掌握分析問題、詢問解釋技巧;進行事實庫、規則庫的編寫,並在此基礎上進行簡單的詢問。
-
求解圖搜尋問題。
任選一個以下實際應用題目:愛因斯坦的超級問題、字謎問題、漢諾塔問題、八數碼問題、八皇后問題、農夫過河問題、傳教士與野人問題。
二.實驗的硬體、軟體平臺
__硬體:__計算機
__軟體:__作業系統:WINDOWS
__應用軟體:__GNU Prolog
三.實驗內容及步驟
熟悉prolog語言的使用並實現求解圖搜尋問題
實驗步驟:
- 安裝prolog整合開發環境
- 採用prolog編寫所選問題的源程式
- 編譯程式,輸出查詢問題的結果或資料
四.實驗報告要求
-
通過PROLOG的基本程式設計練習,說明實驗的方法和步驟;
-
針對圖搜尋要求,說明求解的問題與程式、程式分析、註釋、執行結果等,在討論與結論部分說明實驗收穫、難點重點討論等;
-
附上所有實驗原始碼。
五.實驗步驟
通過PROLOG的基本程式設計練習,說明實驗的方法和步驟
原子:小寫字母開頭
變數:大寫字母開頭
符合用來組成事實
規則:且:, 或:. 非:\+
loves(jack,mia).
loves(marsellus,mia).
loves(mike,john).
loves(john,mike).
jealous(X,Y):- loves(X,Z), loves(Y,Z).
| ?- jealous(jack, marsellus).
yes
| ?- jealous(mike, john).
no
列表:[A, B, C],可以通過[Head|Tail]解析
| ?- [Head|Tail] = [A, B, C].
Head = A
Tail = [B,C]
yes
匿名變數:_
| ?- [A, B, C, D] = [_,Head|Tail].
Head = B
Tail = [C,D]
yes
內建謂詞
member:檢查某一個值是否在一個列表內
fd_all_different:檢查列表中是否有重複元素
fd_domain:驗證值是否在一個範圍之內
length:獲取列表的長度
針對圖搜尋要求,說明求解的問題與程式、程式分析、註釋、執行結果等,在討論與結論部分說明實驗收穫、難點重點討論等
求解的問題
在8×8格的國際象棋上擺放8個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。
程式
valid((_,Col)):-
Range = [1,2,3,4,5,6,7,8],
member(Col,Range).
valid_board([]).
valid_board([Head|Tail]):- valid(Head),valid_board(Tail).
cols([],[]).
cols([(_,Col)|QueensTail],[Col|ColsTail]):-
cols(QueensTail,ColsTail).
main_diag([],[]).
main_diag([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col - Row,
main_diag(QueensTail,DiagonalsTail).
diag([],[]).
diag([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col + Row,
diag(QueensTail,DiagonalsTail).
eight_queens(Board) :-
Board = [(1, _), (2, _), (3, _), (4, _), (5, _), (6, _), (7, _), (8, _)],
valid_board(Board),
cols(Board,Cols),
main_diag(Board,Main_diag),
diag(Board,Diag),
fd_all_different(Cols),
fd_all_different(Main_diag),
fd_all_different(Diag).
程式分析及註釋
- 主體部分:
eight_queens(Board) :-
Board = [(1, _), (2, _), (3, _), (4, _), (5, _), (6, _), (7, _), (8, _)],
valid_board(Board),
cols(Board,Cols),
main_diag(Board,Main_diag),
diag(Board,Diag),
fd_all_different(Cols),
fd_all_different(Main_diag),
fd_all_different(Diag).
- 既然是8皇后問題,自然要定義一個8 * 8的棋盤,根據約束條件:不能位於同一行,所以按照prolog的語法棋盤可表示為:
Board = [(1, _), (2, _), (3, _), (4, _), (5, _), (6, _), (7, _), (8, _)]
棋盤生成之後就需要檢查是否符合範圍要求,即是不是在棋盤上:
valid_board(Board).
由於Board是以列表的形式呈現,所以可以用之前提到的[Head|Tail]進行判斷,檢查Head指向的當前第一個元素是不是符合要求,再將剩餘的Tail作為新的列表繼續。檢查是不是符合時,只需要判斷列號是不是在1-8的範圍內,這個可以用到內建謂詞member判斷是不是在範圍內。具體實現為
valid((_,Col)):-
Range = [1,2,3,4,5,6,7,8],
member(Col,Range).
valid_board([]).
valid_board([Head|Tail]):- valid(Head),valid_board(Tail).
- 接下來就是生成列號以及得到兩個對角線的數值:
cols(Board,Cols),
main_diag(Board,Main_diag),
diag(Board,Diag),
對於Col列號,只需要從棋盤中取出即可
cols([],[]).
cols([(_,Col)|QueensTail],[Col|ColsTail]):-
cols(QueensTail,ColsTail).
而對於兩個對角線,則需要通過計算:主對角線為列 - 行,副對角線為列 + 行
main_diag([],[]).
main_diag([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col - Row,
main_diag(QueensTail,DiagonalsTail).
diag([],[]).
diag([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col + Row,
diag(QueensTail,DiagonalsTail).
- 這樣在最後,只需要保證列號,兩條對角線均不相同,則可完成任務:
fd_all_different(Cols),
fd_all_different(Main_diag),
fd_all_different(Diag).
執行結果
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-QsnSdAVv-1609253228360)(C:\Users\a2783\AppData\Roaming\Typora\typora-user-images\image-20201121165519777.png)]
⭐ | |||||||
---|---|---|---|---|---|---|---|
⭐ | |||||||
⭐ | |||||||
⭐ | |||||||
⭐ | |||||||
⭐ | |||||||
⭐ | |||||||
⭐ |
⭐ | |||||||
---|---|---|---|---|---|---|---|
⭐ | |||||||
⭐ | |||||||
⭐ | |||||||
⭐ | |||||||
⭐ | |||||||
⭐ | |||||||
⭐ |
均符合要求
實驗收穫
這次實驗最大的應該就是一定程度上掌握了prolog語言吧,瞭解到了還有一門這樣的可以進行邏輯推理,程式設計也比較方便的語言。主要的難點部分的話,應該就是prolog語法的學習,因為在之前一直沒有接觸過,而且有的地方的不熟練也在一定程度上限制了程式設計,所以這次實驗主要的時間都是耗費在了prolog的學習之上。
實驗原始碼
valid((_,Col)):-
Range = [1,2,3,4,5,6,7,8],
member(Col,Range).
valid_board([]).
valid_board([Head|Tail]):- valid(Head),valid_board(Tail).
cols([],[]).
cols([(_,Col)|QueensTail],[Col|ColsTail]):-
cols(QueensTail,ColsTail).
main_diag([],[]).
main_diag([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col - Row,
main_diag(QueensTail,DiagonalsTail).
diag([],[]).
diag([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col + Row,
diag(QueensTail,DiagonalsTail).
eight_queens(Board) :-
Board = [(1, _), (2, _), (3, _), (4, _), (5, _), (6, _), (7, _), (8, _)],
valid_board(Board),
cols(Board,Cols),
main_diag(Board,Main_diag),
diag(Board,Diag),
fd_all_different(Cols),
fd_all_different(Main_diag),
fd_all_different(Diag).
相關文章
- 程式設計題求解程式設計
- Java實驗二:類程式設計實驗Java程式設計
- 湖南大學人工智慧實驗三:分類演算法實驗人工智慧演算法
- CMP DataSource問題,尋求解決方案
- 面試手撕(一):圖搜尋,排布問題面試
- 實驗二 結對程式設計程式設計
- 【問題】 檔案搜尋
- 二分搜尋演算法-吃香蕉問題演算法
- 比酒量問題與二叉樹搜尋和路徑問題二叉樹
- 相似圖片搜尋的原理(二)
- 一圖簡看基於搜尋的問答機器人設計機器人
- Delphi實用程式設計經驗二 (轉)程式設計
- 圖形程式設計問題記錄程式設計
- 關於搜尋地址的問題
- SI 2120程式設計影像搜尋綜合程式設計
- LeetCode 642 號問題:設計搜尋自動補全系統LeetCode
- 解決 PbootCMS 搜尋未搜尋到任何資料的問題boot
- Delphi實用程式設計經驗二則 (轉)程式設計
- c語言程式設計——實驗報告二C語言程式設計
- AB實驗坑賊多?騰訊搜尋實驗有妙招
- [教程二] 寫一個搜尋:解決搜尋結果高亮問題,使用 Laravel Scout,Elasticsearch,ik 分詞LaravelElasticsearch分詞
- 程式設計題:尋找木頭程式設計
- javascript實現二叉搜尋樹JavaScript
- 程式設計師的基礎生存技能:搜尋引擎程式設計師
- 最好的程式設計師凡事先上谷歌搜尋程式設計師谷歌
- 搜尋引擎ElasticSearch18_ElasticSearch程式設計操作5Elasticsearch程式設計
- SAP Fiori應用的搜尋問題
- 網站搜尋引擎優化問題網站優化
- 迴圈結構程式設計 實驗題目程式設計
- 淘寶拍立淘介面,圖片搜尋介面,圖片識別介面,以圖搜貨介面,按圖搜尋介面程式碼教程
- 二叉搜尋樹程式碼例項
- 用c++設計哲學家進餐問題的求解C++
- 如果搜尋引擎被禁止,你還會程式設計嗎?程式設計
- 程式設計師應該掌握的10個搜尋技巧程式設計師
- mysql的中文全文搜尋實踐(二)薦MySql
- 用資料輔助設計-搜尋中的實踐
- 通過Observable解決搜尋框問題
- 《C語言程式設計:問題與求解方法》——2.2節C語言歷史概述C語言程式設計