基於ASP設計的走迷宮程序

基於ASP設計的走迷宮程序

  • ASP簡介

ASP的全稱爲Answer Set Programming,其中文解釋爲回答集程序設計。ASP是邏輯程序設計的一個分支,ASP的基本思想是以邏輯程序的形式表達一個問題,是一種基於邏輯程序及其回答集的聲明式編程範例。

  • 程序設計方法

生成-定義-測試方法(Generate-Define-Test methodology),GDT是ASP中編碼搜索問題中的極爲有效的方法。在GDT,一個程序可以將這個問題分爲三部分組成:生成、定義和測試[9]。生成的作用是生成搜索空間(hypothesis generation)。由一組選擇規則編碼:

{A} ← B1,...,Bn, not C1,...,not Cm.

其中A、Bi和Ci是原子。規則規定,如果規則的主體所表達的條件成立,原子A可以是任意真或假。這個條件可能引用其他生成的謂詞,或者引用定義的謂詞。

定義部分是一些輔助謂詞的一組定義。每個定義由一組規則:

A ← B1 ,..., Bn,not C1 ,..., not Cm.

其中,A、Bi、Cj是原子,A是被定義的輔助謂詞。這些規則通常是以確定性的方式描述瞭如何從生成的謂詞或其他定義的謂詞中導出輔助謂詞。

最後,測試部分消除生成的不滿足期望約束的答案集。它們由約束規則表示:

←B1,...,Bn,not C1 ,..., not Cm.

這三種規則的集合將被稱爲GDT程序。GDT方式構思的ASP程序加強了內部結構豐富度。這三個部分中的每一個都可以由獨立的組件組成。ASP程序中內部結構並不凸顯,通常只有當我們研究謂詞之間的依賴關係時才變得明顯。這促使我們去定義一個邏輯,這個邏輯使GDT計劃的內部結構變得更清晰。

  • 設計過程

運用ASP的GDT方法,可以對走迷宮問題進行編程設計,步驟如下:

1、生成

首先需要一個記錄時間的原子(atom),以記錄和限制代理移動的次數。發成部分主要生成代理在time(T)內在迷宮地圖中所以的移動路徑,也就是走迷宮問題的搜索空間,實現代碼如下:

1 {valid_move((X,Y),T) :cell(X,Y) } 1 :- time(M),T=1..M.

其表示在時間T內,每個時間點有且只有一個代理在迷宮地圖中移動。

在10*10的網格地圖中,代理在其中移動一次就有COW * COL個可能移動的位置,所以其搜索空間大小爲:

HG=(COW * COL)T

2、定義

需要定義代理每一個時間點的有效移動產生的效果,即當前時刻代理的位置將是當前時刻有效移動的目標格子。再者,需要定義這兩者是迷宮中代理的移動方式,有以下兩種:一是代理下一刻的有效移動是與代理相鄰的格子,當然這個移動方向是隨機的;二是當前時刻代理所處位置是傳送隧道(link/2)的入口,下一刻代理將會到達隧道的另一端。實現代碼如下:

agent_at(C,T) :-valid_move(C,T).

表示如果時間點T代理移動到座標爲C的格子可以作爲有效移動,那麼在時間點T所處的位置爲座標C。

agent_at(C,T+1) :- not valid_move(C,T+1),agent_at(C,T), time(T).

如果時間點T代理所處位置爲座標C,T+1時未進行有效移動,且時間點T不是最後的時間點,那麼在T+1代理所處的位置任爲座標C。

adjacent((X, Y), (X + 1, Y)) :- cell((X, Y)), cell((X + 1, Y)).
adjacent((X + 1, Y), (X, Y)) :- cell((X, Y)), cell((X + 1, Y)).
adjacent((X, Y + 1), (X, Y)) :- cell((X, Y)), cell((X, Y + 1)).
adjacent((X, Y), (X, Y + 1)) :- cell((X, Y)), cell((X, Y + 1)).

表示隨機選定一個格子,在上下左右四個方向與其相差一的座標點的格子的被稱爲相鄰格子。

3、測試

要從數值如此龐大的搜索空間中找出爲數不多的無衝突路徑,如果採用窮舉法,其中的計算量是無法想象的。所以測試部分主要目的是消除生成的不滿足期望約束的答案集,重點就在於符合題設的選擇規則。例如,不是相鄰格子之間的移動不能當作有效移動;代理不能通過兩個相鄰之間有牆體的格子;代理所處位置不能是被鎖住的格子;傳送隧道是單向的,代理只能從規定的方向使用傳送隧道。實現代碼如下:

:- valid_move(C2, T),not adjacent(C1, C2), agent_at(C1, T-1).
:- valid_move(C2, T),wall(C1, C2) ,agent_at(C1, T-1). 
:- agent_at(C, T),remain_locked(C), time(M),T=1..M.
:- valid_move(C2, T), sup_adjacent (C1, C2) ,agent_at(C1, T-1).

以上爲代理在迷宮地圖中的行走規則,只能以相鄰格子作爲下一時間點的移動目標;兩個格子之間存在牆體不能互相移動;代理不能移動到任被鎖住的格子。

:-goal(X,Y),not agent_at((X,Y),T),time(T).

表示在最後時間點T,代理的位置並不在指定的目標位置,則被認定爲目標沒有完成。

當代理所處位置爲傳送隧道的入口時,有以下兩種可能情況,一是代理可以選擇不通過傳送隧道,繼續通往與其相鄰的格子;二是代理必須通過傳送隧道,沒有其他選擇。這兩者在一個地圖中可能都能實現,但這會導致代理從起始點到目標點的路徑差異。所以就形成了兩個版本,前者更適合找到最短路徑和更具有靈活性,後者則體現題設規則的嚴謹。

下圖顯示第一種情況的代理移動方式的集合:

adjacent(C1, C2) :- link(C1, C2).

:- valid_move(C2, T),not adjacent(C1, C2), agent_at(C1, T-1).

版本一搜索空間

 

 

下圖顯示第二種情況代理移動方式的集合:

刪除部分爲link/2的補集,即全集adjacent/2不屬於集合link/2的元素;

sup_adjacent/2  =  C(adjacent/2)( link/2)

其謂詞定義和選擇規則如下:

adjacent(C1, C2) :- link(C1, C2).

sup_adjacent (C1, C3) :- link(C1, C2),adjacent(C1, C3),C2!=C3.

:- valid_move(C2, T),not adjacent(C1, C2), agent_at(C1, T-1).

:- valid_move(C2, T), sup_adjacent (C1, C2) ,agent_at(C1, T-1).

 

版本二搜索空間

 

  • 結果展示

如下圖所示,實際人工規劃示例地圖的完整路徑:

 

自己畫的路徑
通過clingo編譯器編譯運行的結果
  •  小結

        ASP不算是一門通用編程語言,受衆很小,算是一個用來求解受限的一階邏輯問題的領域專用語言。領域專用語言最初發明出來就是爲了快速解決基於約束的問題,類如類型推導、圖着色、N皇后等問題和一些計算困難的組合問題。clingo一直在不斷的更新中,不斷的完善和研究新功能,在機器運算能力不再是阻礙程序性能的時候,依靠自身描述能力強,自動查找答案等獨有性能特點,肯定會屬於聲明式編程的一片天地。

相關鏈接:

ASP在線編輯編譯網站:https://potassco.org/clingo/run/

本地編譯環境也可在此網站下載!

本文到此結束!!!!感謝閱讀!!!!

注:本文章爲博主原創,未經同意,禁止隨意轉載。內容如有錯誤,歡迎評論私信指正!!!

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章