Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Relatorio
1. Centro Federal de Educação Tecnológica de Minas Gerais
CEFET MG
Common Lisp
Aplicação de busca – Exercício das Jarras
Adson Nogueira Alves
201023510057
Prof. Maicon
Janeiro 2015
Leopoldina -MG
2. Proposta:
Dispondo de uma fonte de agua e duas garrafas onde uma contém uma capacidade de 4
litros e a outra 3 litros. O objetivo é deixar o recipiente de 3 litros com 2 litros de agua.
Solução:
Utilizando o formalismo de espaço de estados, representamos o problema como
(<conteúdo em 4 litros><conteúdo em 3 litros>)
Dessa forma, o estado inicial é ( 0 0 ) e o estado final ( 0 2 ) em Lisp temos:
(defun estado-inicial () '(0 0)) ;; Definição da função inicial
(defun teste-fim (estado) (equal estado '(0 2 ))) ;; Definição da função de teste
;; comparando se o estado atual confere
;; com o final
Tanto o estado inicial, quanto o estado final estão sob a forma de procedimento. Sendo
que no estado inicial o procedimento apenas retorna a lista correspondente; já no estado
final é testado de o estado é igual ao estado final ou não.
Nesse ponto é introduzido duas variáveis globais para simbolizar a capacidade dos
recipientes - *a* e *b* , 4 e 3 litros respectivamente
(defvar *a* 4) ;; definindo variáveis globais jarra 1
(defvar *b* 3) ;; definindo variáveis globais jarra 2
Nesse momento é criado função que retorna um estado sucessor de um estado dado para
uma possível manipulação, que pode ser reconhecida através do nome de cada função.
Quando um operador não é aplicável, a função retorna a lista vazia, isto é , NIL .
(defun enche-a (estado) ;; Definição do estado enche a
(cond ((not (= (car estado) *a*)) ;; teste condicional
(list *a* (cadr estado)))))
(defun enche-b (estado) ;; Definição do estado enche b
(cond ((not (= (cadr estado) *b*)) ;; teste condicional
(list (car estado) *b*))))
(defun esvazia-a (estado) ;; Definição do estado esvazia a
(cond ((not (= (car estado) 0)) ;; teste condicional
(list 0 (cadr estado)))))
(defun esvazia-b (estado) ;; Definição do estado esvazia b
(cond ((not (= (cadr estado) 0)) ;; teste condicional
(list (car estado) 0))))
(defun joga-ab (estado) ;; Definição do estado joga a em b
(cond ;; teste condicional
3. ((and (not (= (car estado) 0))
(not (= (cadr estado) *b*)))
(cond ;; teste condicional
((> (car estado) (- *b* (cadr estado)))
(list (- (car estado)(- *b* (cadr estado))) *b*))
(t (list 0 (+ (cadr estado) (car estado))))))))
(defun joga-ba (estado) ;; Definição do estado Joga b em a
(cond ;; teste condicional
((and (not (= (cadr estado) 0))
(not (= (car estado) *a*)))
(cond ;; teste condicional
((> (cadr estado)(- *a* (car estado)))
(list *a* (- (cadr estado)(- *a* (car estado)))))
(t (list (+ (car estado)(cadr estado)) 0))))))
Essa próxima função nada mais é que o procedimento de solução, que dado um estado
retorna uma lista contendo todos os seus possíveis sucessores.
(defun sucessores (estado)
(mapcan #'(lambda (op)
(let ((novo (apply op (list estado))))
(cond (novo (list novo)))))
'(enche-a enche-b esvazia-a esvazia-b
joga-ab joga-ba)))
No caso os nomes das funções que representam os operadores estão sendo utilizados
como dados passados como parâmetro para outra função, no caso, a função anônima
utilizada como segundo argumento da função “mapcan “ , e executados através da função
“ apply “ , nesse caso utilizando uma função especifica do Common Lisp, a função “ let”,
que permite a definição de variáveis locais.
Até esse ponto temos os sucessores de cada estado possível, porém precisamos que o
programa apresente o caminho de solução de forma “inteligente “, dessa forma é preciso
criar uma estrutura q pode ser expressa pela forma abaixo.
(defstruct (node (:print-function print-node))
(state nil)
(father nil)
(g 0)
(h 0))
Função “print-node “, será utilizada sempre que um nodo for impresso
(defun print-node (node &optional stream level )
(princ (node-state node) stream)
(cond ((node-father node)
(princ "<-" stream)
(princ (node-father node) stream))
4. (t (terpri))))
Existe basicamente duas estratégias “cegas” para a construção de uma arvore de busca:
busca em largura e busca em profundidade. O utilizado foi busca em largura. O Criterio
utilizado leva em conta dois valores numéricos associados ao nodo – g e h. No caso da
busca cega, o valor h, que contém a informação heurística especifica de cada problema,
não é utilizado, de maneira que o único parâmetro que pode ser utilizado é o valor de
profundidade do nodo – g.
(defun blind-search ()
(let ((node-i nil) ; Armazena o nodo a ser examinado
(closed nil) ; Contém a lista vazia
(open (list (make-node :state (estado-inicial)))))
O let permite a inicialização das variáveis locais “node-i” , “closed” e “open” .
A interação infinita “loop” pode ser interrompida caso todos os casos tenha sido
examinados sem que uma solução tenha sido encontrada, retornando o símbolo “fail” ou
quando encontra uma solução. No último caso é impresso o caminho associado à solução
e o símbolo “sucess”.
(loop
(cond
((null open)
(return 'fail)))
(setq node-i (select open))
(setq open (remove node-i open))
(setq closed (cons node-i closed))
(cond
((teste-fim (node-state node-i))
(princ node-i)
(terpri)
(return 'success))
(t (dolist (state-j (sucessores (node-state node-i)))
(let ((no (compare state-j open))
(nc (compare state-j closed)))
(cond
((not (or no nc))
(setq open
(includ (make-node :state state-j
:father node-i)
open)))))))))))
A função “compare” simplesmente procura em uma lista de nodos (“open ” ou “closed”)
a ocorrência de um nodo cujo estado associado corresponda ao seu primeiro argumento
(“state”).
(defun compare (state node-list)
(cond
5. ((null node-list) nil)
((equal state (node-state (car node-list)))
(car node-list))
(t (compare state (cdr node-list)))))
A função “select” seleciona um nodo da lista “open” para ser examinado.
(defun select (node-list)
(car node-list))
A função “includ” como um novo nodo deve ser incluído na lista “open”, no caso como
realizamos uma busca em largura os novos nodos serão incluídos no fim da lista “open”.
(defun includ (node node-list)
(append node-list (list node)))