In acest paragraf se vor analiza urmaroarele aspecte:
Principii de elaborare a planificatoarelor(sus)
Prima idee de baza in planificare este de a cunoaste reprezentarea starilor telurilor si a actiunilor. Algoritmii de planificare folosesc descrieri in mai multe limbaje formale. Starile si telurile sunt reprezentate printr-o multime de propozitii, actiunile fiind reprezentate printr-o descriere logica a preconditiilor si a efectelor. Aceasta reprezentare permite planificatorului sa faca legaturi directe intre stari si actiuni.
A doua idee de baza in planificare este ca planificatorul este liber sa adauge actiuni planului oriunde este nevoie, mai degraba decat a le plasa intr-o ordine incrementala incepand cu starea initiala. De exemplu daca un agent doreste sa bea lapte, el poate decide sa cumpere laptele, chiar inainte de a decide de unde sa cumpere, cum sa ajunga acolo, sau ce sa faca dupa aceea. Nu este necesara o corelare intre ordinea de planificare a pasilor si ordinea de executie. Luand mai intai decizii "evidente" sau "importante", planificatorul poate reduce factorul de ramificare pentru optiunile urmatoare si reducand astfel nevoia de a reconsidera anumite actiuni arbitrare.
A treia idee importanta care sta la baza planificarii este aceea ca multe parti ale lumii sunt independente de altele. Aceasta face posibil sa consideram teluri in mod conjunctiv, cum ar fi " cumpara o sticla de lapte si o ciocolata si o bicicleta" si rezolva aceasta printr-o strategie de divide si cucereste. Algoritmii bazati pe strategia divide si cucereste sunt eficienti pentru ca aproape de fiecare data este mai usor sa rezolvi mai multe subprobleme decat o problema mai mare.Oricum, strategia divide si cucereste esueaza in situatiile in care costul combinarii solutiilor subproblemelor este prea mare.
Domeniile de planificare in acest SNLP sunt definite folosind limbajul STRIPS, aplicand principiile descrise mai sus. Acest limbaj determina o eficientizare a algorimilor. O problema de planificare este reprezentata prin expresii logice care descriu cele trei parti principale ale unei probleme :
Definirea domeniilor si a actiunilor(sus)
Operatorii sunt specificati printr-o sintaxa predefinita. Formatul pentru a defini un operator este dupa cum urmeaza:
(defstep :action `(<nume-operator> <parametru1>...<parametrun>)
:preconditie `(<lista de propozitii care trebuie satisfacute pentru ca actiunea
sa fie realizabila>)
:add `(<lista de propozitii care vor deveni adevarate dupa aplicarea operatorului
>)
:delete `(< lista de propozitii care vor deveni false dupa aplicarea operatorului>)
:equals `(<lista aditionala de constranderi asupra variabilelor continant
relatii de egalitate si inegalitate >))
Sa consideram un exemplu de domeniu pentru un o problema de planificare a unui robot, definind urmatoarele rutine.
(defun Robot-world ()
(reset-domain) ;elimina domeniul vechi prealabil definirii unui nou domeniu
;; definirea unui pas care permite robotului sa treaca pe usa
(defstep :action '(go-thru-dr ?x ?y ?z)
:precond '((is-room ?y) (connects ?x ?y ?z) (is-door ?x)
(dr-open ?x) (arm-empty) (next-to robot ?x)
(in-room robot ?z))
:add '((in-room robot ?y))
:dele '((in-room robot ?z) (next-to robot ?w))
:equals '((not (?x ?y)) (not (?x ?z)) (not (?y ?z))
(not (?x robot)) (not (?y robot)) (not (?z robot))
(not (?w ?y)) (not (?w ?z) ) (not (?w robot))))
;; definiprea unui pas care permite robotului sa mearga la o usa
(defstep :action '(goto-dr ?x ?y)
:precond '((is-door ?x) (connects ?x ?z ?y) (in-room robot ?y))
:add '((next-to robot ?x))
:dele '((next-to robot ?w))
:equals '((not (?x ?y)) (not (?x ?z)) (not (?y ?z))
(not (?x robot)) (not (?y robot)) (not (?z robot))
(not (?w robot)) (not (?w ?x)))))
O data ce un domeniu este definit, se defineste problema prin doua liste, reprezentand un set de conditii initiale, respectiv o multime de teluri. Problema poate fi definita dupa cum urmeaza:
(defun <nume-problema> ()
(<numele-functiei-care-descrie-operatorul>)
(plan `(<stare-initiala>)
`(<stare-finala>)
:rank-fun #'<numele-functie- folosite>))
Unde, rank-fun este o functie euristica care ghideaza cautarea planificatorului, in program (snlp.lisp) sunt declarate mai multe astfel de functii, cum ar fi DF-RANK (plan),RANK1 (plan),RANK2 (plan).
Planificatorul va returna doua valori: un plan si un obiect statistic.Pentru ambele structuri sunt definite functii specifice de afisare
De asemenea sunt definite urmatoarele variabile, care sunt folosite ca indicatori.
PLAN-UTILS:*SEARCH-LIMIT* - Limiteaza numarul planelor pe care planificatorul le va produce in incercarea de a rezolva problema, folosit pentru a evita cicluri infinite
PLAN-UTILS:*VERBOSE* -
Strategii de elaborare a planelor(sus)
Un drum prin spatiul solutiilor incepand cu starea initiala la starea tel constituie un plan. Pentru o problema descrisa intr-un limbaj STRIPS, un plan se poate obtine incepand cu starea initiala si aplicand operatori, cate unul in fiecare pas, pana obtinem un pas care satisface toate constrangerile telului. Un algoritm care realizeaza asa ceva va rezolva problema, si il putem considera un planificator, si il putem numi planificator in spatiul situatiilor pentru ca va cauta prin spatiul situatiilor. Un astfel de planificator este progresiv daca va cauta de la starea initiala spre tel. Problema pricipala a unui asemena planificator este ca are un factor de ramificare mare in spatiul de cautare.
Un mod de a reduce factorul de ramificare este de a cauta inapoi, de la tel
spre starea initiala, cu o astfel de cautare avem un planificator regresiv.
O astfel de abordare este posibila datorita faptului ca operatorii contin suficiente
informatii pentru a regresa de la o descriere partiala a unei stari rezultat
la o descriere partiala inainte ca un operator sa fie aplicat. Nu putem obtine
o descriere completa a starii in acest mod. dar nici nu este necesar. O astfel
de abordare este de dorit deoarece starea tel are cateva conjunctii, fiecare
cu doar cativa operatori, in schimb starea initiala are semnificativ mai multi
opearatori. Din nefericire, cautand inapoi este mai complicat deoarece, intr-un
anumit sens, trebuie sa atingem o conjunctie de teluri, nu doar unul. Algoritmul
STRIPS original era unul regresiv care nu era complet, adica se putea sa nu
gaseasca un plan chiar daca exista unul. Aceasta eroare aparea datorita faptului
ca avea un mod neadecvat de a manipula conjunctii complicate de teluri, rezolvand
aceasta incompletitudine facea planificatorul ineficient.
O alternativa este sa se caute in spatiul planelor si nu in cel al situatiilor.
Pentru aceasta vom incepe cu un plan simplu, incomplet, pe care il numim plan
partial. Pe urma se cauta moduri de a extinde acest plan pana vom obtine unul
complet, care rezolva problema. Operatorii in aceasta strategie de cautare sunt
operatori pe plane, si anume : adaugare pas, impunerea unei canstrangeri de
ordine asupra pasilor, etc . Solutia este planul final, si calea de a-l atinge
este irelevanta. Aceasta ultima varianta fiind aplicata pentru cautarea unui
plan in programul dat (snlp.lisp).
Folosire(sus)
Pogramul a fost rulat sub versiunea GCL (GNU Common Lisp) v 2.5.0., varianta pentru sistemul de operare Mandrake 9.2. Programul va furniza printre datele rezultat timpul CPU necesar obtineerii planului. Acesti timpi obtinuti prin rulare unor exemple sunt semnificativ mai mici decat cei dati datorita performantelor mai mari ale calculatoarelor pe care am rulate programele.
Pentru rezolvarea unei probleme reale trebuie specificate domeniile, operatorii si telul. Planificatorul va incerca determinarea unui plan bazandu-se pe aceste cunostinte si din care va obtine altele noi, ca urmare a intreprinderii anumitor actiuni.
Conditiile initiale si operatorii se specifica printr-o sintaxa prezentata mai sus si care se salveaza intr-un fisier .lisp impreuna cu functia care apeleaza algoritmul de planificare si care are ca parametrii conditiile initiale si telurile. Pentru executarea exemplului se parcurg urmatorii pasi:
Exemple(sus)
Urmatorul exemplu este asemanator problemei turnurilor din Hanoi. Avem o configuratie initiala a blocurilor si una finala, vrem sa gasim un plan care sa ne genereze pasii necesari pentru a ajunge la configuratia finala, incepand cu configuratia initiala.
Domeniul va fi definit prin urmatoarele rutine:
(defun blocks-world-domain ()
- aceasta functie va schimba un domeniu vechi, daca era definit ,cu unul nou.
(plan-utils:reset-domain)
- definim pasul care pune un bloc pe masa.
(plan-utils:defstep :action '(newtower ?x) ; se creea o noua 'stiva' de obiecte
pe masa care contine numai blocul X
:precond '((on ?X ?Z) (clear ?X)) ;se specifica faptul ca blocul X este deasupra
blocului Z si blocul X nu mare nimic
; deasupra lui : (clear ?x)
:add '((on ?X Table) (clear ?Z)) ; savarsirea acestei actiuni are ca efect crearea
urmatoarelor predicate: (on ?X Table)
;-X va fi pe masa,
:dele'((on ?X ?Z))
;se 'sterge' faptul ca blocul X este deasupra blocului Z
:equals '((not (?X ?Z)) (not (?X Table)) (not (?Z Table))))
- definirea pasului care pune un bloc peste altul
(plan-utils:defstep :action '(puton ?X ?Y) ; mutam
blocul X peste blocul Y
:precond '((on ?X ?Z) (clear ?X) (clear ?Y)) ; actiunea se poate realiza numai
daca blocurile X si Y nu au alte blocuri
;;deasupra lor
( (clear ?X) , (clear ?Y) )
:add '((on ?X ?Y) (clear ?Z)) ; in urma executarii actiunii, se vor forma urmatoarele
certitudini: X este deasupra lui Y, si Z nu
;; va mai avea nici un bloc deasupra sa
:dele '((on ?X ?Z) (clear ?Y))
; X nu va mai fi deasupra lui Z si Y va avea un bloc deasupra lui;
:equals '((not (?X ?Y)) (not (?X ?Z)) (not (?Y ?Z))
(not (?X Table)) (not (?Y Table)))))
- planul se genereaza apeland urmatoarea functie, pentru care se specifica conditiile initiale si telurile.
(defun snlp-sussman-anomaly ()
(snlp:plan '((on C A) (on A Table) (on B Table) (clear C) (clear B)) ;; conditii
initiale
'((on A B) (on B C)))) ;; teluri
USER(10): (snlp-sussman-anomaly)
#SNLP-Plan<S=3; O=0; U=0>
#Stats:<cpu time = 2>
Setand flagul PLAN-UTILS:*VERBOSE* la T rezulta se vor afisa urmatoarele date::
USER(15): (snlp-sussman-anomaly)
Initial : ((ON C A) (ON A TABLE) (ON B TABLE) (CLEAR C) (CLEAR B))
Pas 1 : (NEWTOWER C) Created 2
Pas 2 : (PUTON B C) Created 3
Pas 3 : (PUTON A B) Created 1
Goal : ((ON A B) (ON B C))
Complete!